Skip to Content

How do I trace a TypeScript AI agent running in a Docker container?

Rius traces a TypeScript agent in a Docker container when you call init() once at startup, set your settings as container environment variables, and call client.shutdown() when the container stops. The TypeScript SDK registers no process-exit hook, so spans still queued when the process ends are lost unless you flush them. Each container start shows up in Rius as its own instance of one agent.

How it works

  • One init() per process. Call it as early as possible in your entry file. A second global init() logs a warning and returns the existing client, so do not call it per request.
  • Integrations attach asynchronously. init() returns immediately and enables every installed integration it finds. Await client.ready before your first model call so the integration is in place. It resolves with the names that attached and never rejects.
  • Spans export in batches. Spans queue in memory and a background timer sends them in batches. The network never sits on your agent’s hot path, and exporter errors never reach your code.
  • Nothing flushes for you. The TypeScript SDK installs no exit hook and no signal handlers. An unhandled SIGTERM or a SIGKILL sends no final stopped ping, so the instance shows as gone. That is how Rius tells a crash from a clean exit.
  • Each container start is a new instance. Keep the service name constant across replicas and deploys. Three containers show as three instances of one agent.

Set it up

  1. Install the SDK in your image. Add the package for each library your agent calls, such as OpenAI. The SDK only patches libraries whose packages are installed. Full options are on Installation and configuration.
npm install @glassflow-ai/rius @opentelemetry/api npm install @arizeai/openinference-instrumentation-openai
  1. Pass settings as container environment variables, so the image holds no secret. Most options have a RIUS_* variable, and an explicit argument in code wins over the variable.

    • RIUS_API_KEY: your API key, sent as an Authorization Bearer header. Without it, span exports are rejected and dropped, and no heartbeat is sent.
    • RIUS_SERVICE_NAME: a constant name for the agent, such as my-agent.
    • RIUS_SERVICE_VERSION: your release or image tag, so you can tell builds apart.
    • RIUS_ENDPOINT: only if you change the default, https://ingest.eu.console.rius-glassflow.com.
  2. Initialize once, wait for the integrations, and shut down on SIGTERM:

import { init } from '@glassflow-ai/rius' const client = init({ serviceName: 'my-agent' }) // apiKey comes from RIUS_API_KEY await client.ready process.on('SIGTERM', async () => { await client.shutdown() // drains pending spans and sends the final stopped ping process.exit(0) })
  1. For a short-lived container, such as a batch job or a one-off task, call await client.flush() before the process exits. It returns false when the most recent export failed, for example on a bad API key, so you can log it. Do not call flush() inside request handlers, because it blocks until the export completes.

  2. Keep the heartbeat on for a long-running container. If you set RIUS_HEARTBEAT_INTERVAL, keep it at 15 seconds or below, because an instance is marked stale after 30 seconds without a ping. Do not set RIUS_SESSION_ID in a server that handles many users, because it applies one session to every span.

Delivery rules, retries and batching variables are covered on Reliability.

What you get

  • Spans for the model calls of the integrations you installed, shown in the trace list. Where a call carries a model and token counts, Rius computes a list-price cost estimate in US dollars.
  • An instance in running or ready for each container on the Agents page, grouped under one agent name, with the service.version you set so you can compare builds.
  • A clean exit marker when shutdown() runs, and gone when a container is killed without it.
  • The last spans of a run, because the queue drains before the process ends.

The Integrations page lists which TypeScript libraries are supported and how each one attaches.

When something else fits

  • If your container runs a serverless-style runtime that freezes the process between calls, flush at the end of every invocation and set RIUS_HEARTBEAT=false, as Reliability describes.
  • If your agent calls a library with no TypeScript integration, trace those calls with manual generations instead of relying on auto-instrumentation.
  • If the container runs Python, the SDK flushes on a clean interpreter exit, but docker stop sends SIGTERM, which skips it. Call client.shutdown() from your own SIGTERM handler there too.

Still stuck? Get help

Last updated on