Guides
Observability
RateGuard emits OpenTelemetry spans and metrics for every LLM call using the official GenAI semantic conventions. Span names follow {operation} {model} (e.g. chat gpt-4o); standard gen_ai.* attributes are used where the convention defines them, and RateGuard-specific data lives under rateguard.* so the reserved namespace stays clean.
chat gpt-4o ← span name: {operation} {model}
├── gen_ai.provider.name: "openai" | "anthropic" | "google"
├── gen_ai.request.model: "gpt-4o" | "claude-opus-4-5" | ...
├── gen_ai.operation.name: "chat" | "text_completion" | "embedding"
├── gen_ai.usage.input_tokens: 1234
├── gen_ai.usage.output_tokens: 567
└── gen_ai.conversation.id / gen_ai.response.id (when provided)Track any call manually
ctx, span := rg.StartGenAICall(ctx, rateguard.GenAICall{
Provider: "openai", Model: "gpt-4o", Operation: "chat",
})
resp, err := client.Chat(ctx, req)
span.RecordChunk() // optional, per streaming chunk — first call sets TTFT
span.End(rateguard.GenAICall{
PromptTokens: usage.Input,
CompletionTokens: usage.Output,
}, err)Cost is estimated automatically from the pricing table (14 models verified against provider pricing pages) when not provided. TTFT and TPOT are derived from RecordChunk() timing. Node and Python expose the same attribute builders via genaiSpanName / genai_span_name and friends.
Tip
OTLPCollectorEndpoint at your collector and the spans land in Datadog, Grafana, or Honeycomb with zero extra glue — they follow the semconv your backend already understands.Prometheus
http.Handle("/metrics", rg.Metrics())
// live counters: requests, rate limits, budgets,
// breakers, loops, outbound calls + fallbacks + tokensEvents
Every request emits an event — request.completed, request.rate_limited, token_budget.exceeded — for custom dashboards, alerts, or audit logs:
// Send to an HTTP endpoint
rg := rateguard.New(rateguard.Config{
EventEndpoint: "https://my-dashboard.example/api/events",
})
// Or handle in-process
rg = rateguard.New(rateguard.Config{
EventEmitter: myCustomEmitter{},
})