agentskit.js
Observability

Loggers + tracers

Attach console, LangSmith, or OpenTelemetry observers to any runtime — mix and match, all receive the same event stream.

Every observer receives the same event sequence — chat.start, llm.call, tool.call, tool.result, error, chat.end — so switching from console to LangSmith in production requires only changing which observer you pass.

import { createRuntime } from '@agentskit/runtime'
import { consoleLogger, langsmith, opentelemetry } from '@agentskit/observability'
import { langfuse } from '@agentskit/observability-langfuse'

const runtime = createRuntime({
  adapter,
  tools,
  observers: [
    consoleLogger(),
    langsmith({ apiKey: process.env.LANGSMITH_API_KEY!, project: 'prod' }),
    opentelemetry({ serviceName: 'agent-worker' }),
    langfuse({ publicKey: process.env.LANGFUSE_PUBLIC_KEY!, secretKey: process.env.LANGFUSE_SECRET_KEY! }),
  ],
})

#Observers

ObserverPackagePurposeEnv
consoleLogger()@agentskit/observabilitydev
langsmith({ apiKey, project })@agentskit/observabilitytraces UILANGSMITH_API_KEY
opentelemetry({ serviceName })@agentskit/observabilityOTel pipelineOTLP endpoint
langfuse({ publicKey, secretKey })@agentskit/observability-langfuseLangfuse traces + generationsLANGFUSE_PUBLIC_KEY LANGFUSE_SECRET_KEY
datadogSink({ apiKey, site?, env? })@agentskit/observabilityDatadog Logs HTTP intakeDD_API_KEY
axiomSink({ token, dataset, endpoint? })@agentskit/observabilityAxiom dataset ingestAXIOM_TOKEN
newRelicSink({ apiKey, region? })@agentskit/observabilityNew Relic Logs API (US / EU)NEW_RELIC_LICENSE_KEY
createTraceTracker()@agentskit/observabilityBYO span lifecycle

#Langfuse

langfuse is a separate package (@agentskit/observability-langfuse) with langfuse as an optional peer dependency. Install both:

pnpm add @agentskit/observability-langfuse langfuse
import { langfuse } from '@agentskit/observability-langfuse'

createRuntime({
  adapter,
  observers: [
    langfuse({
      publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
      secretKey: process.env.LANGFUSE_SECRET_KEY!,
      baseUrl: process.env.LANGFUSE_HOST ?? 'https://cloud.langfuse.com',
      environment: 'production',
      sessionId: requestId,      // optional — group traces by session
      userId: currentUserId,     // optional — link traces to users
    }),
  ],
})

Every agent run becomes a Langfuse trace. LLM calls map to generations (with token usage), tool calls map to spans. Network errors are swallowed — observability never breaks the agent loop.

Config options mirror the Langfuse SDK: release, tags, flushAt, flushInterval. Env vars LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_HOST, LANGFUSE_RELEASE, and LANGFUSE_ENVIRONMENT are read automatically when the corresponding config option is omitted.

#SaaS sinks — failure-safe

datadogSink, axiomSink, and newRelicSink follow the same observer contract: every span start / end is forwarded as a JSON event to the upstream HTTP intake. All three swallow network errors — observability never breaks the main agent loop. Configure region (site / endpoint / region) and service tags per provider.

import { datadogSink, axiomSink, newRelicSink } from '@agentskit/observability'

createRuntime({
  adapter,
  observers: [
    datadogSink({ apiKey: process.env.DD_API_KEY!, env: 'prod', site: 'datadoghq.eu' }),
    axiomSink({ token: process.env.AXIOM_TOKEN!, dataset: 'agentskit' }),
    newRelicSink({ apiKey: process.env.NEW_RELIC_LICENSE_KEY!, region: 'US' }),
  ],
})

Explore nearby

✎ Edit this page on GitHub·Found a problem? Open an issue →·How to contribute →

On this page