Enabling OpenTelemetry for a Rust Agent

SkillMonitoring & ops

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

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

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

What this skill tells your AI

The instructions your AI receives, as published by golemcloud/golem in golem-skills/skills/rust/golem-enable-otlp-rust/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 bindings to create custom spans:

use golem_rust::bindings::golem::api::context;

let span = context::start_span("my-operation");
span.set_attribute("env", &context::AttributeValue::String("production".to_string()));
span.set_attributes(&[
    context::Attribute { key: "service".to_string(), value: context::AttributeValue::String("my-service".to_string()) },
    context::Attribute { key: "version".to_string(), value: context::AttributeValue::String("1.0".to_string()) },
]);

// ... do work ...

let ctx = context::current_context();
println!("trace_id: {}", ctx.trace_id());
span.finish();

Logs

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

use log::debug;

println!("Hello from Rust!");
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.

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 context::start_span from golem_rust::bindings::golem::api::context 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
212
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
golem-enable-otlp-rust
Source
github.com/golemcloud/golem