Skip to content

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.

sequenceDiagram participant Agent participant SDK as OTel SDK (OpenLLMetry) participant Mem as InMemorySpanExporter participant DB as TelemetryPersistenceService participant Ext as OTLP HTTP exporter Note over Agent, Ext: Init SDK->>SDK: setupInstrumentation()<br/>appName: "codebuddy-agent" SDK->>Mem: Attach + SimpleSpanProcessor SDK->>DB: Open SQLite, create tables, prune old Note over Agent, Ext: Runtime Agent->>SDK: LLM / tool / subagent SDK->>SDK: Auto-instrument LangChain + LangGraph SDK->>Mem: Completed span (live view) SDK->>DB: Persist (span_id, trace_id, attrs, events) opt OTLP enabled SDK->>Ext: HTTP batch export<br/>(DNS-pinned to resolved IP) end

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).

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.

MethodSourceReturns
getTraces()In-memory exporterLive spans from current session
getPersistedTraces(days, limit)SQLiteHistorical spans with computed duration
getSessions()SQLiteDistinct session IDs + span counts + date ranges
getMetrics()PerformanceProfilerRuntime performance data
getRecentLogs()LoggerLast 1000 log entries from circular buffer

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:

PlatformEndpoint
Langfusehttps://<host>/api/public/otel
LangSmithhttps://api.smith.langchain.com
Jaeger (OTLP)http://localhost:4318
Grafana TempoYour Tempo OTLP HTTP endpoint

Any OTLP HTTP endpoint works.

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
SettingDefaultPurpose
codebuddy.telemetry.persistTracestruePersist traces to SQLite across sessions
codebuddy.telemetry.retentionDays7Auto-prune after N days (1–90)
codebuddy.telemetry.otlpEndpoint""OTLP HTTP endpoint (empty = disabled)
PackageVersionRole
@opentelemetry/api^1.9.0OTel API
@opentelemetry/sdk-trace-base^2.5.1Trace SDK
@opentelemetry/exporter-metrics-otlp-http^0.212.0OTLP HTTP export
@traceloop/node-server-sdk^0.22.7Auto-instrument LangChain/LangGraph
  • Security — SSRF + DNS-rebinding gates that OTLP export inherits
  • Cost tracking — how token counts on spans get priced