metrics

package
v1.2.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package metrics provides a stdlib-only Prometheus text exposition format encoder. It implements the minimum Counter, Histogram, and Gauge types needed to expose server-level instrumentation over an HTTP /metrics endpoint. No external dependencies.

The implementation targets Prometheus text format version 0.0.4 (https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ToolCallsTotal counts tools/call dispatches by tool name and outcome.
	ToolCallsTotal *Counter
	// ToolCallDuration records dispatch duration in seconds.
	ToolCallDuration *Histogram
	// RateLimitRejections counts rate limiter rejections by kind.
	RateLimitRejections *Counter
	// Cancellations counts tools/call cancellations by reason
	// (client_requested, timeout, context_cancelled).
	Cancellations *Counter
	// HTTPRequestsTotal counts HTTP requests by path, method, and status.
	// Path is normalized at the call site to a bounded set (/mcp, /health,
	// /ready, /metrics, /other) to prevent cardinality blowup from probes.
	HTTPRequestsTotal *Counter
	// HTTPAdmissionRejectionsTotal counts app-layer HTTP admission limiter
	// rejections before a request reaches JSON-RPC dispatch.
	HTTPAdmissionRejectionsTotal *Counter
	// HTTPRequestDuration records HTTP request wall-clock duration.
	HTTPRequestDuration *Histogram
	// ReadyState is 1 when the server is ready, 0 otherwise.
	ReadyState *Gauge
	// BuildInfo exposes build metadata; value is always 1.
	BuildInfo *Gauge
	// InFlightToolCalls reports the dispatch-layer in-flight goroutine count.
	InFlightToolCalls *Gauge
	// UpstreamRequestsTotal counts outbound Clockify API requests by
	// endpoint (URL template), HTTP method, and status code bucket
	// (2xx/3xx/4xx/5xx/error).
	UpstreamRequestsTotal *Counter
	// UpstreamRequestDuration records Clockify API call latency.
	UpstreamRequestDuration *Histogram
	// UpstreamRetriesTotal counts retry attempts by endpoint and reason.
	UpstreamRetriesTotal *Counter
	// UpstreamRetryAfterUnparseableTotal counts non-empty Retry-After
	// headers that could not be parsed. Labelled by normalized endpoint so
	// operator dashboards can distinguish an upstream format regression from
	// a missing header.
	UpstreamRetryAfterUnparseableTotal *Counter
	// ProtocolErrorsTotal counts JSON-RPC protocol-level errors by code.
	ProtocolErrorsTotal *Counter
	// ProtocolVersionHeaderMissingTotal counts post-initialize streamable HTTP
	// requests that omitted Mcp-Protocol-Version. Default-compatible mode
	// accepts them; strict deployments can reject them.
	ProtocolVersionHeaderMissingTotal *Counter
	// PanicsRecoveredTotal counts panics recovered from tool handlers and HTTP.
	PanicsRecoveredTotal *Counter
	// GRPCSendPumpPanicsTotal counts panics recovered from the gRPC
	// Exchange send-pump goroutine.
	GRPCSendPumpPanicsTotal *Counter
	// GRPCNotificationDropsTotal counts gRPC server-initiated
	// notifications dropped before they reached a client stream.
	GRPCNotificationDropsTotal *Counter
	// ClockifyResponsesOversizeTotal counts upstream Clockify responses
	// rejected because the body exceeded the client's hard cap. Lets
	// operators detect adversarial / misconfigured upstreams that
	// emit responses large enough to threaten OOM. Labelled by the
	// HTTP method so a single offending endpoint stands out.
	ClockifyResponsesOversizeTotal *Counter
	// GRPCAuthRejectionsTotal counts gRPC auth interceptor rejections by reason.
	GRPCAuthRejectionsTotal *Counter
	// AuditEventsTotal counts audit-record attempts (all non-read-only calls).
	AuditEventsTotal *Counter
	// AuditFailuresTotal counts audit persistence failures by coarse reason
	// class and audit phase. Label "reason" uses a small fixed vocabulary:
	// "persist_error". Label "phase" uses "intent", "outcome", or "single".
	AuditFailuresTotal *Counter
	// SSESubscriberDropsTotal counts SSE subscribers dropped because the
	// hub's non-blocking publish saw their channel full. Reason vocabulary:
	// "slow_subscriber" (the only emit site today; added so future
	// eviction paths like close-on-auth-change can label themselves).
	SSESubscriberDropsTotal *Counter
	// SSEReplayMissesTotal counts Last-Event-ID resumes that asked for a
	// position older than the live backlog ring. The client will miss
	// events between lastEventID and the oldest retained event — this
	// signals operator-facing lost-event risk even though SSE semantics
	// accept it.
	SSEReplayMissesTotal *Counter
	// StreamableEventsAliasRequestsTotal counts GET /mcp/events legacy
	// alias use. Canonical streamable HTTP clients should use GET /mcp;
	// any non-zero value identifies old clients to migrate.
	StreamableEventsAliasRequestsTotal *Counter
	// StreamableSessionsReapedTotal counts sessions evicted by the
	// streamable HTTP session reaper. Reason vocabulary: "ttl" (TTL
	// expired) and "orphan" (no subscribers past the idle grace).
	StreamableSessionsReapedTotal *Counter
	// StreamableSessionStoreErrorsTotal counts control-plane persistence
	// failures for streamable HTTP session records by operation.
	StreamableSessionStoreErrorsTotal *Counter
	// AuditEventsRetainedTotal counts audit events removed
	// (outcome="deleted", value = rows per tick) or errored
	// (outcome="error", incremented once per failed tick) by the
	// control-plane audit retention reaper. Driven by the B2 reaper
	// that honours MCP_CONTROL_PLANE_AUDIT_RETENTION.
	AuditEventsRetainedTotal *Counter
	// TruncationSkippedTotal counts fail-open truncation paths by reason.
	// Reason vocabulary: "marshal_failed" and "unmarshal_failed".
	TruncationSkippedTotal *Counter
)
View Source
var Default = NewRegistry()

Default is the package-level registry used by the Clockify MCP server.

View Source
var DefaultBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}

DefaultBuckets mirrors Prometheus client_golang's default histogram buckets.

View Source
var HTTPDurationBuckets = []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10}

HTTPDurationBuckets targets fast JSON-RPC request/response latency on the HTTP transport. Pre-handler auth + CORS + decode should land well under 100ms; downstream tool-call time dominates beyond that.

View Source
var ToolCallBuckets = []float64{0.05, 0.1, 0.25, 0.5, 1, 2, 3, 5, 10, 20, 45}

ToolCallBuckets targets the documented tool-call SLO (p95 < 3s, p99 < 10s). Finer granularity at the 3s boundary lets us measure SLO breaches precisely; coverage up to 45s accommodates long-running report tools that may legitimately approach the per-call timeout.

View Source
var UpstreamDurationBuckets = []float64{0.05, 0.1, 0.25, 0.5, 1, 2, 3, 5, 10, 20, 45}

UpstreamDurationBuckets targets Clockify upstream API latency. Most list endpoints respond in 100-500ms; reports can spike into seconds.

Functions

This section is empty.

Types

type Counter

type Counter struct {
	// contains filtered or unexported fields
}

Counter is a monotonically increasing value with optional labels.

func (*Counter) Add

func (c *Counter) Add(delta uint64, labelValues ...string)

Add increments the counter by delta. Silently dropped on label mismatch.

func (*Counter) Get

func (c *Counter) Get(labelValues ...string) uint64

Get returns the current value for a label set. Primarily used in tests.

func (*Counter) Inc

func (c *Counter) Inc(labelValues ...string)

Inc increments the counter by 1 for the given label set.

type Gauge

type Gauge struct {
	// contains filtered or unexported fields
}

Gauge exposes a sampled value provided by the caller via SetFunc.

func (*Gauge) SetFunc

func (g *Gauge) SetFunc(fn func() float64, labelValues ...string)

SetFunc registers (or replaces) the sampling closure for a label set. The closure is invoked at /metrics scrape time.

type Histogram

type Histogram struct {
	// contains filtered or unexported fields
}

Histogram records observations into cumulative bucket counts plus sum and count.

func (*Histogram) Observe

func (h *Histogram) Observe(value float64, labelValues ...string)

Observe records a single value under the given label set.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry owns a set of metrics and writes them in Prometheus text format.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty registry.

func (*Registry) NewCounter

func (r *Registry) NewCounter(name, help string, labels ...string) *Counter

NewCounter registers a new counter. Panics on invalid names or duplicates.

func (*Registry) NewGauge

func (r *Registry) NewGauge(name, help string, labels ...string) *Gauge

NewGauge registers a new gauge. Panics on invalid names or duplicates.

func (*Registry) NewHistogram

func (r *Registry) NewHistogram(name, help string, buckets []float64, labels ...string) *Histogram

NewHistogram registers a new histogram. Panics on invalid names or duplicates.

func (*Registry) WriteTo

func (r *Registry) WriteTo(w io.Writer) (int64, error)

WriteTo emits all registered metrics in Prometheus text format v0.0.4.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL