package telemetry import ( "context" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "github.com/fujin/anthropic-proxy/internal/ratelimit" ) var ( RequestCounter metric.Int64Counter RequestDuration metric.Float64Histogram RequestBodySize metric.Int64Histogram UpstreamErrors metric.Int64Counter TokensInput metric.Int64Counter TokensOutput metric.Int64Counter CredentialCooldowns metric.Int64Counter ActiveCredentials metric.Int64UpDownCounter StreamRequests metric.Int64Counter ) // InitMetrics creates all metric instruments from the given meter. // If tracker is non-nil, registers observable gauges for per-window usage. func InitMetrics(meter metric.Meter, tracker *ratelimit.Tracker) { RequestCounter, _ = meter.Int64Counter("proxy.request.count", metric.WithDescription("Total proxy requests"), ) RequestDuration, _ = meter.Float64Histogram("proxy.request.duration_ms", metric.WithDescription("Request latency in milliseconds"), metric.WithUnit("ms"), ) RequestBodySize, _ = meter.Int64Histogram("proxy.request.body_size_bytes", metric.WithDescription("Request body size in bytes"), metric.WithUnit("By"), ) UpstreamErrors, _ = meter.Int64Counter("proxy.upstream.errors", metric.WithDescription("Upstream error count"), ) TokensInput, _ = meter.Int64Counter("proxy.tokens.input", metric.WithDescription("Input tokens consumed"), ) TokensOutput, _ = meter.Int64Counter("proxy.tokens.output", metric.WithDescription("Output tokens consumed"), ) CredentialCooldowns, _ = meter.Int64Counter("proxy.credential.cooldowns", metric.WithDescription("Credential cooldown activations"), ) ActiveCredentials, _ = meter.Int64UpDownCounter("proxy.credential.active", metric.WithDescription("Currently active (non-cooldown) credentials"), ) StreamRequests, _ = meter.Int64Counter("proxy.stream.requests", metric.WithDescription("Streaming request count"), ) if tracker == nil { return } attr5h := attribute.String("window", "5h") attr7d := attribute.String("window", "7d") attrSonnet := attribute.String("window", "7d_sonnet") meter.Float64ObservableGauge("proxy.usage.utilization", metric.WithDescription("Current utilization % from API"), metric.WithFloat64Callback(func(_ context.Context, o metric.Float64Observer) error { o.Observe(tracker.FiveHour().Utilization, metric.WithAttributes(attr5h)) o.Observe(tracker.SevenDay().Utilization, metric.WithAttributes(attr7d)) o.Observe(tracker.Sonnet().Utilization, metric.WithAttributes(attrSonnet)) return nil }), ) meter.Int64ObservableGauge("proxy.usage.resets_at", metric.WithDescription("Unix seconds when window resets"), metric.WithInt64Callback(func(_ context.Context, o metric.Int64Observer) error { o.Observe(tracker.FiveHour().ResetsAt.Unix(), metric.WithAttributes(attr5h)) o.Observe(tracker.SevenDay().ResetsAt.Unix(), metric.WithAttributes(attr7d)) o.Observe(tracker.Sonnet().ResetsAt.Unix(), metric.WithAttributes(attrSonnet)) return nil }), ) }