Skip to Content
Next — You're reading the unreleased preview docs. APIs and pages may change before the next release.Switch to the current docs →
How-To GuidesMoonBitEnabling OpenTelemetry for a MoonBit Agent

Enabling OpenTelemetry for a MoonBit Agent

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.8" 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

Add "golemcloud/golem_sdk/context" @context and "golemcloud/golem_sdk/logging" @log to the imports in moon.pkg. Use the @context module for automatic span lifecycle management:

@context.with_span( "my-operation", attributes=[("env", "production"), ("service", "my-service"), ("version", "1.0")], fn(span) { // ... do work ... // Add more attributes dynamically if needed: span.set_attribute("step", "processing") let ctx = @context.current_context() println("trace_id: " + ctx.trace_id()) }, )

with_span automatically finishes the span when the callback returns.

Logs

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

println("Hello from MoonBit!") @log.debug("This is a debug log entry")

Metrics

When metrics is included in signals, exported metrics include the following (this is not an exhaustive list):

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 queued invocation requests, not current queue depth
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 remote transactions
golem.transaction.rolled_backCounterNumber of rolled back remote transactions
golem.snapshot.size_bytesCounterSnapshot size in bytes
golem.oplog_processor.lagGaugeOplog processor delivery lag

These are emitted OTLP names. A backend such as Prometheus may normalize dots to underscores and add suffixes; use that backend’s mapping when writing queries.

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

Export Semantics

  • Long-lived spans retain their origin trace across invocations. Failed or retrying attempts do not close the logical span. Logs use their recorded trace context.
  • Streams export aggregate item counts, not a span per item. Query active-resource counts and initial/total memory as gauges.
  • Use agent-type service-name mode to exclude constructor parameters and phantom IDs from service.name. golem.agent.id still contains the full identity.
  • Treat collector export as best effort, not exactly-once delivery. A failed send can lose telemetry; traces, logs, and metrics are attempted independently.
  • Fork/revert cannot retract exported telemetry. Agent deletion does not close open spans, and switching plugin instances can lose open-span state.

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.8" parameters: endpoint: "http://localhost:4318" signals: "traces,logs,metrics" presets: app-env:production: pluginsMergeMode: replace plugins: - name: golem-otlp-exporter version: "1.5.8" 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.with_span for custom spans with automatic lifecycle management
  • Plugin can be activated/deactivated per agent with golem agent activate-plugin / golem agent deactivate-plugin
  • Load golem-manage-plugins for the general plugin installation model (manifest sections, CLI commands, priority, per-environment configuration)