Documentation
¶
Overview ¶
Package metrics provides Prometheus metrics collection for the proxy.
Index ¶
- Variables
- func DecrementActiveRequests()
- func Handler() http.Handler
- func IncrementActiveRequests()
- func RecordCacheHit(ecosystem string)
- func RecordCacheMiss(ecosystem string)
- func RecordCircuitBreakerTrip(registry string)
- func RecordHealthProbeFailure(step string)
- func RecordIntegrityFailure(ecosystem string)
- func RecordRequest(ecosystem string, status int, duration time.Duration)
- func RecordResponse(ecosystem, client string, bytes int64)
- func RecordScanError(ecosystem, scannerName, errorType string)
- func RecordScanResult(ecosystem, scannerName string, allowed bool, duration time.Duration)
- func RecordStorageError(operation string)
- func RecordStorageOperation(operation string, duration time.Duration)
- func RecordUpstreamError(ecosystem, errorType string)
- func RecordUpstreamFetch(ecosystem string, duration time.Duration)
- func UpdateCacheStats(sizeBytes, artifactCount int64)
- func UpdateCircuitBreakerState(registry string, state int)
- func UpdateEcosystemStats(stats []EcosystemStats)
- type EcosystemStats
- type Sample
- type Snapshot
Constants ¶
This section is empty.
Variables ¶
var ( // Request metrics RequestsTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_requests_total", Help: "Total number of requests by ecosystem and status", }, []string{"ecosystem", "status"}, ) RequestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "proxy_request_duration_seconds", Help: "Request duration in seconds", Buckets: prometheus.DefBuckets, }, []string{"ecosystem", "status"}, ) // Cache metrics CacheHits = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_cache_hits_total", Help: "Total number of cache hits by ecosystem", }, []string{"ecosystem"}, ) CacheMisses = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_cache_misses_total", Help: "Total number of cache misses by ecosystem", }, []string{"ecosystem"}, ) CacheSize = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "proxy_cache_size_bytes", Help: "Total size of cached artifacts in bytes", }, ) CachedArtifacts = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "proxy_cached_artifacts_total", Help: "Total number of cached artifacts", }, ) // Upstream metrics UpstreamFetchDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "proxy_upstream_fetch_duration_seconds", Help: "Upstream fetch duration in seconds", Buckets: []float64{.1, .25, .5, 1, 2.5, 5, 10, 30}, }, []string{"ecosystem"}, ) UpstreamErrors = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_upstream_errors_total", Help: "Total number of upstream fetch errors by type", }, []string{"ecosystem", "error_type"}, ) // Circuit breaker metrics CircuitBreakerState = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_circuit_breaker_state", Help: "Circuit breaker state (0=closed, 1=half-open, 2=open)", }, []string{"registry"}, ) CircuitBreakerTrips = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_circuit_breaker_trips_total", Help: "Total number of circuit breaker trips", }, []string{"registry"}, ) // Storage metrics StorageOperationDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "proxy_storage_operation_duration_seconds", Help: "Storage operation duration in seconds", Buckets: []float64{.001, .005, .01, .025, .05, .1, .25, .5, 1}, }, []string{"operation"}, ) StorageErrors = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_storage_errors_total", Help: "Total number of storage errors by operation", }, []string{"operation"}, ) // Active requests ActiveRequests = prometheus.NewGauge( prometheus.GaugeOpts{ Name: "proxy_active_requests", Help: "Number of currently active requests", }, ) IntegrityFailures = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_integrity_failures_total", Help: "Cached artifacts that failed hash verification on read", }, []string{"ecosystem"}, ) HealthProbeFailures = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_health_probe_failures_total", Help: "Total number of storage health probe failures, by step (write|size|read|verify|delete).", }, []string{"step"}, ) // Per-ecosystem gauges, derived from the database rather than incremented // in the request path, and refreshed on the same tick as the cache gauges // above. EcosystemDownloadedBytes = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_ecosystem_downloaded_bytes", Help: "Accumulated bytes served from cache per ecosystem (cache hits x artifact size)", }, []string{"ecosystem"}, ) EcosystemDownloads = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_ecosystem_artifact_downloads", Help: "Accumulated artifact downloads served from cache per ecosystem", }, []string{"ecosystem"}, ) EcosystemCacheSize = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_ecosystem_cache_size_bytes", Help: "Size of cached artifacts per ecosystem in bytes", }, []string{"ecosystem"}, ) EcosystemCachedArtifacts = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_ecosystem_cached_artifacts", Help: "Number of cached artifacts per ecosystem", }, []string{"ecosystem"}, ) EcosystemPackages = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_ecosystem_packages", Help: "Number of known packages per ecosystem", }, []string{"ecosystem"}, ) EcosystemVersions = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "proxy_ecosystem_versions", Help: "Number of known package versions per ecosystem", }, []string{"ecosystem"}, ) ResponseBytes = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_response_bytes_total", Help: "Total response body bytes written to clients, by ecosystem", }, []string{"ecosystem"}, ) ClientRequests = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_client_requests_total", Help: "Total requests by client tool, as identified from the User-Agent", }, []string{"client"}, ) ClientResponseBytes = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_client_response_bytes_total", Help: "Total response body bytes written to clients, by client tool", }, []string{"client"}, ) // Scanning metrics ScanDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "proxy_scan_duration_seconds", Help: "Pre-cache artifact scan duration in seconds, by ecosystem and scanner", Buckets: prometheus.DefBuckets, }, []string{"ecosystem", "scanner"}, ) ScanBlocked = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_scan_blocked_total", Help: "Total number of artifacts blocked by a pre-cache scan, by ecosystem and scanner", }, []string{"ecosystem", "scanner"}, ) ScanErrors = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "proxy_scan_errors_total", Help: "Total number of pre-cache scan errors, by ecosystem, scanner, and error type", }, []string{"ecosystem", "scanner", "error_type"}, ) )
Functions ¶
func DecrementActiveRequests ¶
func DecrementActiveRequests()
DecrementActiveRequests decrements the active request counter.
func IncrementActiveRequests ¶
func IncrementActiveRequests()
IncrementActiveRequests increments the active request counter.
func RecordCacheHit ¶
func RecordCacheHit(ecosystem string)
RecordCacheHit increments cache hit counter.
func RecordCacheMiss ¶
func RecordCacheMiss(ecosystem string)
RecordCacheMiss increments cache miss counter.
func RecordCircuitBreakerTrip ¶
func RecordCircuitBreakerTrip(registry string)
RecordCircuitBreakerTrip increments circuit breaker trip counter.
func RecordHealthProbeFailure ¶ added in v0.4.0
func RecordHealthProbeFailure(step string)
RecordHealthProbeFailure increments the health probe failure counter. step is one of: "write", "size", "read", "verify", "delete".
func RecordIntegrityFailure ¶ added in v0.3.2
func RecordIntegrityFailure(ecosystem string)
RecordIntegrityFailure increments the integrity failure counter.
func RecordRequest ¶
RecordRequest tracks request metrics with timing.
func RecordResponse ¶ added in v0.9.1
RecordResponse tracks what a client actually downloaded.
Distinct from proxy_ecosystem_downloaded_bytes: that gauge is derived from the database and counts cache hits multiplied by artifact size, while this counts body bytes as they are written, including metadata responses and cache misses.
client must come from a closed set -- a User-Agent is attacker-controlled, so passing it through raw would mint a time series per request.
func RecordScanError ¶ added in v0.8.0
func RecordScanError(ecosystem, scannerName, errorType string)
RecordScanError increments the scan error counter. errorType is one of: "error" (scanner call failed), "timeout", "cancelled".
func RecordScanResult ¶ added in v0.8.0
RecordScanResult tracks a completed pre-cache scan call.
func RecordStorageError ¶
func RecordStorageError(operation string)
RecordStorageError increments storage error counter.
func RecordStorageOperation ¶
RecordStorageOperation tracks storage operation duration.
func RecordUpstreamError ¶
func RecordUpstreamError(ecosystem, errorType string)
RecordUpstreamError increments upstream error counter.
func RecordUpstreamFetch ¶
RecordUpstreamFetch tracks upstream fetch duration.
func UpdateCacheStats ¶
func UpdateCacheStats(sizeBytes, artifactCount int64)
UpdateCacheStats updates cache size and artifact count gauges.
func UpdateCircuitBreakerState ¶
UpdateCircuitBreakerState updates circuit breaker state gauge. state: 0=closed, 1=half-open, 2=open
func UpdateEcosystemStats ¶ added in v0.9.1
func UpdateEcosystemStats(stats []EcosystemStats)
UpdateEcosystemStats republishes the per-ecosystem gauges from a fresh snapshot.
Rows are summed by label before anything is published, because normalizing collapses aliases: a database holding both "gem" and "rubygems" rows -- the proxy writes the former, git-pkgs the latter -- arrives as two rows belonging to one label, and publishing them one at a time would leave only the last.
The vectors are not Reset() first. Reset followed by a repopulating loop leaves a window in which a scrape sees the families empty or half filled, which renders as a spurious gap on any panel built from them. Each series is Set instead, and only labels that have actually disappeared are deleted.
Types ¶
type EcosystemStats ¶ added in v0.9.1
type EcosystemStats struct {
Ecosystem string
Packages int64
Versions int64
Artifacts int64
CacheSize int64
Downloads int64
DownloadedBytes int64
}
EcosystemStats is one ecosystem's row of the snapshot published as gauges.
type Sample ¶ added in v0.9.1
Sample is one time series read out of the registry at a point in time.
Counters and gauges carry their value in Value. Histograms carry their observation count and total in Count and Sum, and leave Value at zero — there is no single "value" for a histogram, and the UI shows a mean derived from Sum/Count rather than pretending otherwise.
type Snapshot ¶ added in v0.9.1
type Snapshot struct {
// contains filtered or unexported fields
}
Snapshot is the value of every registered proxy metric at one instant.
These are process-lifetime figures held in the Prometheus registry, not database state: they start at zero when the proxy starts and are lost on restart. Anything that needs to survive a restart, or needs history, has to come from a Prometheus server scraping /metrics.
func Gather ¶ added in v0.9.1
Gather reads the default Prometheus registry. It is the same data /metrics serves, shaped for rendering rather than for scraping.
func GatherFrom ¶ added in v0.9.1
func GatherFrom(g prometheus.Gatherer) (*Snapshot, error)
GatherFrom reads an explicit gatherer, so tests can supply their own registry.
func (*Snapshot) Count ¶ added in v0.9.1
Count adds up the observation counts of a histogram across every series.
func (*Snapshot) Mean ¶ added in v0.9.1
Mean returns the average observation of a histogram across every series, or 0 when nothing has been observed.
func (*Snapshot) Names ¶ added in v0.9.1
Names returns the name of every metric family in the snapshot, sorted.
func (*Snapshot) Samples ¶ added in v0.9.1
Samples returns every series of a metric, or nil when it has never been observed. Series are ordered by their label values so that rendering is stable between scrapes.