Enabling OpenTelemetry for a TypeScript Agent

SkillMonitoring & ops

Sends your TypeScript Golem agent's traces, logs, and metrics to an observability backend via OpenTelemetry.

Use Enabling OpenTelemetry for a TypeScript Agent in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add Enabling OpenTelemetry for a TypeScript Agent and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the Enabling OpenTelemetry for a TypeScript Agent skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Enabling OpenTelemetry for a TypeScript AgentStart free
About this skill

Enabling the OpenTelemetry (OTLP) plugin for a TypeScript Golem agent, exporting traces, logs, and metrics to an OTLP collector, adding custom spans with the invocation context API or node:diagnostics_channel.

What this skill tells your AI

The instructions your AI receives, as published by golemcloud/golem in golem-skills/skills/ts/golem-enable-otlp-ts/SKILL.md and read by ahel’s review.

The golem-otlp-exporter is a built-in plugin that exports agent telemetry (traces, logs, metrics) to any OTLP-compatible collector via OTLP/HTTP. No plugin installation is needed — just enable it in the application manifest.

Step 1 — Enable the Plugin in golem.yaml

Add the plugin to the component (or agent) that should emit telemetry:

components:
  my-app:service:
    plugins:
      - name: golem-otlp-exporter
        version: "1.5.0"
        parameters:
          endpoint: "http://localhost:4318"
          signals: "traces,logs,metrics"

Plugin Parameters

ParameterRequiredDescription
endpointYesOTLP collector base URL (e.g., http://localhost:4318)
signalsNoComma-separated: traces, logs, metrics. Default: traces
headersNoComma-separated key=value HTTP headers (e.g., x-api-key=secret)
service-name-modeNoagent-id (default) or agent-type

Step 2 — Deploy

golem deploy --yes

After deployment, newly created agents from this component automatically send telemetry to the configured collector.

What Gets Exported

Traces

Spans are created automatically for:

  • Agent invocations
  • RPC calls to other agents
  • Outgoing HTTP requests

Trace and span IDs propagate from inbound HTTP requests (via code-first routes) and are included in outgoing HTTP request headers automatically.

Custom Spans

Use the golem:api/context API to create custom spans:

import { startSpan, currentContext } from 'golem:api/context@1.5.0';

const span = startSpan('my-operation');
span.setAttribute('env', { tag: 'string', val: 'production' });
span.setAttributes([
  { key: 'service', value: { tag: 'string', val: 'my-service' } },
  { key: 'version', value: { tag: 'string', val: '1.0' } },
]);

// ... do work ...

const ctx = currentContext();
console.log(`trace_id: ${ctx.traceId()}`);
span.finish();

Custom Spans via node:diagnostics_channel

TypeScript also supports the Node.js diagnostics_channel API, which automatically creates Golem spans:

import { tracingChannel } from 'node:diagnostics_channel';

const dc = tracingChannel('my-operation');
const result = dc.traceSync(
  () => {
    // ... do work ...
    return 42;
  },
  { method: 'GET', url: '/api/data', env: 'production' } // become span attributes
);

Logs

When logs is included in signals, all log output is forwarded to the OTLP collector. See the golem-logging-ts skill for full logging guidance.

console.log("Hello from TypeScript!");
console.debug("This is a debug log entry");

Metrics

When metrics is included in signals, the following metrics are exported:

MetricTypeDescription
golem_invocation_countCounterNumber of agent method invocations
golem_invocation_duration_nsCounterInvocation duration
golem_invocation_fuel_consumedCounterFuel consumed by invocations
golem_invocation_pending_countCounterNumber of pending invocations
golem_host_call_countCounterNumber of internal host calls
golem_log_countCounterNumber of log entries emitted
golem_memory_initial_bytesGaugeInitially allocated memory
golem_memory_total_bytesGaugeTotal allocated memory
golem_memory_growth_bytesCounterMemory growth since start
golem_component_size_bytesGaugeComponent size in bytes
golem_error_countCounterNumber of recorded errors
golem_interruption_countCounterNumber of interrupt requests
golem_exit_countCounterNumber of process exit signals
golem_restart_countCounterNumber of times a fresh state was created
golem_resources_createdCounterNumber of internal resources created
golem_resources_droppedCounterNumber of internal resources dropped
golem_resources_activeGaugeNumber of active internal resources
golem_update_success_countCounterNumber of successful updates
golem_update_failure_countCounterNumber of failed updates
golem_transaction_committedCounterNumber of committed database transactions
golem_transaction_rolled_backCounterNumber of rolled back database transactions
golem_snapshot_size_bytesCounterSnapshot size in bytes
golem_oplog_processor_lagGaugeOplog processor delivery lag

Each metric includes service.name, golem.agent.id, golem.component.id, and golem.component.version attributes.

Export Semantics

  • Durable Start, End, and Cancelled metadata drives span lifecycle. Long-lived spans retain their origin trace across invocations; failed or retrying attempts do not prematurely close the logical span. Logs use their recorded trace context.
  • Stream summaries use bounded event/outcome metric labels and aggregate item counts; they do not emit a span per item. Active resource and memory values are gauges, and metric labels avoid resource IDs and payload values.
  • In agent-type service-name mode, service.name excludes constructor parameters and phantom instance IDs; golem.agent.id remains the full identity.
  • Collector export is best effort. Accepted source state advances when a send fails, and traces, logs, and metrics are still attempted independently. Exactly-once plugin batch delivery is not exactly-once collector delivery.
  • Fork/revert cannot retract telemetry already accepted by a collector. Source deletion does not provide a terminal signal, so no successful close is invented. Switching plugin instances can lose open-span state; continuity is deferred to GOL-667.

Local Observability Stack

The Golem repository includes a ready-made Docker Compose setup at docker-examples/otlp-collector/:

docker compose -f docker-examples/otlp-collector/docker-compose.yml up -d

This starts:

Configure the plugin with endpoint: "http://localhost:4318" to use this stack.

Per-Environment Configuration

Use presets to vary the endpoint across environments:

components:
  my-app:service:
    plugins:
      - name: golem-otlp-exporter
        version: "1.5.0"
        parameters:
          endpoint: "http://localhost:4318"
          signals: "traces,logs,metrics"
    presets:
      production:
        pluginsMergeMode: replace
        plugins:
          - name: golem-otlp-exporter
            version: "1.5.0"
            parameters:
              endpoint: "https://otel.prod.example.com:4318"
              headers: "x-api-key={{ OTLP_API_KEY }}"
              signals: "traces,logs,metrics"

Key Points

  • Built-in — no golem plugin register needed, just add to golem.yaml
  • Deploy required — run golem deploy after adding the plugin configuration
  • Trace context propagates automatically through HTTP routes and RPC calls
  • Use startSpan from golem:api/context@1.5.0 or tracingChannel from node:diagnostics_channel for custom spans
  • Plugin can be activated/deactivated per agent with golem agent activate-plugin / golem agent deactivate-plugin

Related Skills

  • Load golem-manage-plugins for the general plugin installation model (manifest sections, CLI commands, priority, per-environment configuration)

Signals

GitHub stars
2k
Forks
210
Last commit
Oct 2026
Advanced
Item type
skill
Key
golem-enable-otlp-ts
Source
github.com/golemcloud/golem