Telemetry & Observability
Every agent action produces OpenTelemetry spans — LLM calls, tool invocations, subagent delegations, chain/graph steps, retrieval. Spans land in an in-memory exporter for the live view, a local SQLite database for historical query, and optionally an external OTLP endpoint.
What gets traced
Section titled “What gets traced”OpenLLMetry auto-instruments LangChain + LangGraph:
- LLM calls — model, provider, token counts (input / output / cache_read / cache_creation), latency, streaming status
- Tool invocations — tool name, input, output, duration
- Subagent delegations — subagent type, description, result
- Chain / graph steps — LangGraph node transitions, state changes
- Retrieval — vector search queries, result counts
Each span carries: span_id, trace_id, parent_id, name, kind, start/end (ns), status, attributes (JSON), events (JSON).
Persistence
Section titled “Persistence”SQLite at ~/.codebuddy/telemetry/traces.db via sql.js (WASM).
CREATE TABLE spans ( span_id TEXT PRIMARY KEY, trace_id TEXT NOT NULL, parent_id TEXT, name TEXT NOT NULL, kind INTEGER, start_time_s INTEGER, start_time_ns INTEGER, end_time_s INTEGER, end_time_ns INTEGER, status_code INTEGER, status_message TEXT, attributes TEXT, -- JSON events TEXT, -- JSON links TEXT, -- JSON session_id TEXT, created_at TEXT);Indexed on trace_id, created_at, session_id, name.
Batched writes: buffered → flushed every 5 s or at 50 spans, whichever first. Transactional INSERT OR IGNORE.
Auto-pruning: spans older than retentionDays (default 7) removed on startup.
Query API — ObservabilityService facade
Section titled “Query API — ObservabilityService facade”| Method | Source | Returns |
|---|---|---|
getTraces() | In-memory exporter | Live spans from current session |
getPersistedTraces(days, limit) | SQLite | Historical spans with computed duration |
getSessions() | SQLite | Distinct session IDs + span counts + date ranges |
getMetrics() | PerformanceProfiler | Runtime performance data |
getRecentLogs() | Logger | Last 1000 log entries from circular buffer |
OTLP export
Section titled “OTLP export”Set an endpoint:
{ "codebuddy.telemetry.otlpEndpoint": "https://your-langfuse.example/api/public/otel" }Or the dedicated Langfuse settings for the vendor-specific auth flow — see the code base for the exact key names (codebuddy.telemetry.langfuse.*).
DNS-rebinding pinning: OTLP exports use validateAndPinOutboundUrl (landed 2026-07-10) — the resolved IP is pinned to the socket connect via a custom dns.LookupFunction. Closes the check-then-connect window where a malicious resolver could flip a public answer to a private IP.
Compatible platforms:
| Platform | Endpoint |
|---|---|
| Langfuse | https://<host>/api/public/otel |
| LangSmith | https://api.smith.langchain.com |
| Jaeger (OTLP) | http://localhost:4318 |
| Grafana Tempo | Your Tempo OTLP HTTP endpoint |
Any OTLP HTTP endpoint works.
Structured logging
Section titled “Structured logging”Every log event carries the current OTel traceId so logs + traces correlate.
interface ILogEvent { timestamp: string; level: string; module: string; message: string; data: unknown; sessionId: string; traceId: string; // matches the active OTel trace}Destinations:
- VS Code Output channel (“CodeBuddy”)
- Log files —
.codebuddy/logs/codebuddy-*.log(structured JSON, one event per line) - Circular buffer — last 1000 entries, accessible via
getRecentLogs() - Telemetry — optionally forwarded to the persistence service
Settings
Section titled “Settings”| Setting | Default | Purpose |
|---|---|---|
codebuddy.telemetry.persistTraces | true | Persist traces to SQLite across sessions |
codebuddy.telemetry.retentionDays | 7 | Auto-prune after N days (1–90) |
codebuddy.telemetry.otlpEndpoint | "" | OTLP HTTP endpoint (empty = disabled) |
Dependencies
Section titled “Dependencies”| Package | Version | Role |
|---|---|---|
@opentelemetry/api | ^1.9.0 | OTel API |
@opentelemetry/sdk-trace-base | ^2.5.1 | Trace SDK |
@opentelemetry/exporter-metrics-otlp-http | ^0.212.0 | OTLP HTTP export |
@traceloop/node-server-sdk | ^0.22.7 | Auto-instrument LangChain/LangGraph |
Related
Section titled “Related”- Security — SSRF + DNS-rebinding gates that OTLP export inherits
- Cost tracking — how token counts on spans get priced