github.com/grafana/pyroscope@v1.18.0/pkg/symbolizer/metrics.go (about)

     1  package symbolizer
     2  
     3  import (
     4  	"github.com/grafana/pyroscope/pkg/util"
     5  
     6  	"github.com/prometheus/client_golang/prometheus"
     7  )
     8  
     9  const (
    10  	// Status values for metrics
    11  	statusSuccess = "success"
    12  
    13  	// Error status prefixes
    14  	statusErrorPrefix = "error:"
    15  
    16  	// HTTP error statuses
    17  	statusErrorNotFound     = statusErrorPrefix + "not_found"
    18  	statusErrorUnauthorized = statusErrorPrefix + "unauthorized"
    19  	statusErrorRateLimited  = statusErrorPrefix + "rate_limited"
    20  	statusErrorClientError  = statusErrorPrefix + "client_error"
    21  	statusErrorServerError  = statusErrorPrefix + "server_error"
    22  	statusErrorHTTPOther    = statusErrorPrefix + "http_other"
    23  
    24  	// General error statuses
    25  	statusErrorCanceled   = statusErrorPrefix + "canceled"
    26  	statusErrorTimeout    = statusErrorPrefix + "timeout"
    27  	statusErrorInvalidID  = statusErrorPrefix + "invalid_id"
    28  	statusErrorOther      = statusErrorPrefix + "other"
    29  	statusErrorDebuginfod = statusErrorPrefix + "debuginfod_error"
    30  )
    31  
    32  type metrics struct {
    33  	registerer prometheus.Registerer
    34  
    35  	// Debuginfod metrics
    36  	debuginfodRequestDuration *prometheus.HistogramVec
    37  	debuginfodFileSize        prometheus.Histogram
    38  
    39  	// Cache metrics
    40  	cacheOperations *prometheus.CounterVec
    41  	cacheSizeBytes  *prometheus.GaugeVec
    42  
    43  	// Profile symbolization metrics
    44  	profileSymbolization *prometheus.HistogramVec
    45  
    46  	// Debug symbol resolution metrics
    47  	debugSymbolResolution       *prometheus.HistogramVec
    48  	debugSymbolResolutionErrors *prometheus.CounterVec
    49  }
    50  
    51  func newMetrics(reg prometheus.Registerer) *metrics {
    52  	m := &metrics{
    53  		registerer: reg,
    54  		debuginfodRequestDuration: prometheus.NewHistogramVec(prometheus.HistogramOpts{
    55  			Name:    "pyroscope_symbolizer_debuginfod_request_duration_seconds",
    56  			Help:    "Time spent performing debuginfod requests by status",
    57  			Buckets: []float64{0.1, 0.5, 1, 5, 10, 30, 60, 120, 300},
    58  		}, []string{"status"}),
    59  		debuginfodFileSize: prometheus.NewHistogram(
    60  			prometheus.HistogramOpts{
    61  				Name: "pyroscope_symbolizer_debuginfo_file_size_bytes",
    62  				Help: "Size of debug info files fetched from debuginfod",
    63  				// 1MB to 4GB
    64  				Buckets: prometheus.ExponentialBuckets(1024*1024, 2, 12),
    65  			},
    66  		),
    67  		// cache metrics
    68  		cacheOperations: prometheus.NewCounterVec(
    69  			prometheus.CounterOpts{
    70  				Name: "pyroscope_symbolizer_cache_operations_total",
    71  				Help: "Total number of cache operations by cache type, operation and status",
    72  			},
    73  			[]string{"cache_type", "operation", "status"},
    74  		),
    75  		cacheSizeBytes: prometheus.NewGaugeVec(prometheus.GaugeOpts{
    76  			Name: "pyroscope_symbolizer_cache_size_bytes",
    77  			Help: "Current size of cache in bytes by cache type",
    78  		}, []string{"cache_type"}),
    79  		// profile symbolization metrics
    80  		profileSymbolization: prometheus.NewHistogramVec(prometheus.HistogramOpts{
    81  			Name:    "pyroscope_profile_symbolization_duration_seconds",
    82  			Help:    "Time spent performing profile symbolization by status",
    83  			Buckets: []float64{.01, .05, .1, .5, 1, 5, 10, 30},
    84  		}, []string{"status"}),
    85  		// debug symbol resolution metrics
    86  		debugSymbolResolution: prometheus.NewHistogramVec(prometheus.HistogramOpts{
    87  			Name:    "pyroscope_debug_symbol_resolution_duration_seconds",
    88  			Help:    "Time spent resolving debug symbols from ELF files by status",
    89  			Buckets: []float64{.001, .005, .01, .05, .1, .5, 1, 5, 10},
    90  		}, []string{"status"}),
    91  		debugSymbolResolutionErrors: prometheus.NewCounterVec(
    92  			prometheus.CounterOpts{
    93  				Name: "pyroscope_debug_symbol_resolution_errors_total",
    94  				Help: "Total number of errors encountered during debug symbol resolution by error type",
    95  			},
    96  			[]string{"error_type"},
    97  		),
    98  	}
    99  
   100  	if reg != nil {
   101  		m.register()
   102  	}
   103  
   104  	return m
   105  }
   106  
   107  func (m *metrics) register() {
   108  	if m.registerer == nil {
   109  		return
   110  	}
   111  
   112  	collectors := []prometheus.Collector{
   113  		m.debuginfodRequestDuration,
   114  		m.debuginfodFileSize,
   115  		m.cacheOperations,
   116  		m.cacheSizeBytes,
   117  		m.profileSymbolization,
   118  		m.debugSymbolResolution,
   119  		m.debugSymbolResolutionErrors,
   120  	}
   121  
   122  	for _, collector := range collectors {
   123  		util.RegisterOrGet(m.registerer, collector)
   124  	}
   125  }