Getting Started
Initialize the ADK-TS telemetry service and start collecting traces and metrics
Call telemetryService.initialize() once, before any agent operations, and ADK-TS starts emitting OpenTelemetry spans and metrics for every agent run, LLM call, and tool execution automatically.
Basic Initialization
The minimal setup requires an appName to identify your service in the trace backend. An otlpEndpoint is needed to export data anywhere; without it, initialization still succeeds but no data leaves the process.
import { telemetryService, AgentBuilder } from "@iqai/adk";
await telemetryService.initialize({
appName: "my-agent-app",
otlpEndpoint: "http://localhost:4318/v1/traces",
});
const response = await AgentBuilder.withModel("gemini-2.5-flash").ask("Hello!");
console.log(response);
await telemetryService.shutdown(5000);Initialize before agents
Always call initialize() before creating or running any agent. Spans created
before initialization are not captured.
Configuration Options
import { telemetryService } from "@iqai/adk";
await telemetryService.initialize({
// Service identification
appName: "my-agent-app",
appVersion: "1.0.0",
environment: "development",
// OTLP export
otlpEndpoint: "http://localhost:4318/v1/traces",
otlpHeaders: { Authorization: `Bearer ${process.env.OTEL_API_KEY}` },
// Feature flags
enableTracing: true,
enableMetrics: true,
enableAutoInstrumentation: false,
// Privacy controls
captureMessageContent: true,
// Performance tuning
samplingRatio: 1.0,
metricExportIntervalMs: 60000,
// Custom resource attributes
resourceAttributes: {
"deployment.name": "local",
"team": "platform",
"revision": 42,
},
// Enable in-memory exporter for testing/debugging
debug: false,
});Standard OpenTelemetry environment variables are respected alongside the configuration object. If both are set, the configuration object takes precedence.
export OTEL_SERVICE_NAME=my-agent-app
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=development,team=platform
export ADK_CAPTURE_MESSAGE_CONTENT=true
export NODE_ENV=developmentimport { telemetryService } from "@iqai/adk";
await telemetryService.initialize({
appName: process.env.OTEL_SERVICE_NAME || "my-agent-app",
otlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318/v1/traces",
environment: process.env.NODE_ENV || "development",
});Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
appName | string | — | Required. Service name shown in trace backends |
otlpEndpoint | string | — | OTLP HTTP endpoint, e.g. http://localhost:4318/v1/traces |
otlpHeaders | Record<string, string> | — | Auth headers sent with every OTLP request |
appVersion | string | "unknown" | Application version |
environment | string | Auto-detected from NODE_ENV | Deployment environment |
enableTracing | boolean | true | Enable distributed tracing |
enableMetrics | boolean | true | Enable metrics collection |
enableAutoInstrumentation | boolean | false | Trace outbound HTTP and database calls automatically |
captureMessageContent | boolean | true | Capture LLM prompts, completions, and tool arguments |
samplingRatio | number | 1.0 | Fraction of traces to sample (0.0–1.0) |
metricExportIntervalMs | number | 60000 | How often metrics are exported, in milliseconds |
resourceAttributes | Record<string, string | number | boolean> | — | Extra attributes attached to all spans and metrics |
debug | boolean | false | Activate in-memory exporter for local inspection |
Privacy in production
Set captureMessageContent: false in production to prevent LLM prompts and
tool arguments from appearing in your trace backend.
Debug Mode and In-Memory Traces
When debug: true, ADK-TS additionally routes all spans to an in-memory exporter. You can read them back without a running backend — useful for unit tests or quick local inspection.
import { telemetryService, AgentBuilder } from "@iqai/adk";
await telemetryService.initialize({
appName: "my-agent-app",
debug: true,
});
const sessionId = "session-abc";
const { runner } = await AgentBuilder.create("my-agent")
.withModel("gemini-2.5-flash")
.build();
for await (const _ of runner.runAsync({
userId: "user-1",
sessionId,
newMessage: { role: "user", parts: [{ text: "Hello!" }] },
})) {
// consume events
}
// Retrieve all spans collected so far
const allSpans = telemetryService.getTraces();
console.log(`Captured ${allSpans.length} spans`);
// Or retrieve only spans tagged with a specific session ID
const sessionSpans = telemetryService.getTracesForSession(sessionId);
console.log(`Session spans: ${sessionSpans.length}`);getTraces() returns ReadableSpan[] from @opentelemetry/sdk-trace-base. Each span exposes name, attributes, startTime, endTime, and status.
Graceful Shutdown
Always call shutdown() before your process exits to flush any pending spans and metrics. Pass a timeout in milliseconds; if the flush takes longer than the timeout, the method throws.
import { telemetryService } from "@iqai/adk";
process.on("SIGTERM", async () => {
await telemetryService.shutdown(5000);
process.exit(0);
});
process.on("SIGINT", async () => {
await telemetryService.shutdown(5000);
process.exit(0);
});To flush without shutting down — for example between test cases — use flush():
await telemetryService.flush(5000);Complete Example
import { telemetryService, AgentBuilder } from "@iqai/adk";
async function main() {
await telemetryService.initialize({
appName: "example-agent",
appVersion: "1.0.0",
otlpEndpoint: "http://localhost:4318/v1/traces",
enableMetrics: true,
enableTracing: true,
});
process.on("SIGTERM", async () => {
await telemetryService.shutdown(5000);
process.exit(0);
});
process.on("SIGINT", async () => {
await telemetryService.shutdown(5000);
process.exit(0);
});
const response = await AgentBuilder.withModel("gemini-2.5-flash").ask(
"What is the capital of France?",
);
console.log(response);
}
main().catch(console.error);