Skip to content
Obscenter

Docs Backend

OpenTelemetry (OTLP)

Send OpenTelemetry traces from Python, Go, Java or any OTel SDK to Obscenter over OTLP/HTTP JSON, merged with native Node.js traces into one record per request.

Obscenter traces Node.js with its own agent. Every other language joins through OpenTelemetry, and its spans land in the same traces as the native ones, on the same pages.

The endpoint

POST https://your-install/v1/traces       OTLP/HTTP, JSON encoding

Point an OpenTelemetry SDK that can export JSON at your install with three environment variables. For SDKs that only send protobuf, see SDKs that only send protobuf.

OTEL_EXPORTER_OTLP_ENDPOINT=https://your-install
OTEL_EXPORTER_OTLP_PROTOCOL=http/json
OTEL_EXPORTER_OTLP_HEADERS=x-api-key=<application key or agent key>
  • JSON only. A protobuf body is refused with 415 and a message saying to set OTEL_EXPORTER_OTLP_PROTOCOL=http/json. gRPC is not accepted.
  • Traces only. There is no /v1/logs or /v1/metrics. Logs come from the host agent, and metrics from the agents.
  • The key goes in x-api-key. Without a valid key the answer is 401. Payloads may be up to 4 MB.
  • If part of a batch cannot be mapped, the answer reports the rejected spans in OTLP's partialSuccess.

How spans are mapped

  • service.name becomes the service.
  • A span of kind SERVER becomes the request.
  • Other spans become database spans when they carry db.system, HTTP spans when they are of kind CLIENT, and application spans otherwise.
  • The host comes from host.name.

The services appear under Backend → Services, and their calls under Traces, with an otel badge on the spans that came this way.

One request, one row

A Node.js service can be measured by the native agent and also export its own OpenTelemetry spans. The two must never become two services or two requests. So when service.name matches a natively instrumented service, the OTLP spans are grafted into the native request. The match is tried three ways:

  1. by trace id;
  2. otherwise by overlap: the same service and method, at an overlapping time, with the route as a tie-break;
  3. otherwise the fragment waits, for up to three minutes, for its native request to arrive.

A pass every 20 seconds promotes fragments that never pair into requests of their own. A span id that is already stored is dropped, so a retrying exporter does not duplicate anything.

Without an exporter

If a Node.js app already uses @opentelemetry/api to create its own spans, you do not need to configure an exporter at all. The in-process agent wraps the tracer provider and records those spans straight into the request it is measuring. They show with an otel · in-process badge. The install page puts it this way: already using OpenTelemetry, it fits; not using it, the agent picks the spans up anyway.

Attributes your spans declare with a dotted name, such as checkout.total, appear on the Business logic page with their values and ranges.

SDKs that only send protobuf

Not every SDK can export OTLP as JSON. The JavaScript exporter can. The standard Python and Go HTTP exporters send protobuf only. For those, run an OpenTelemetry Collector beside the service. Let the SDK send to the Collector in whatever encoding it speaks, and let the Collector forward to your install as JSON:

receivers:
  otlp:
    protocols:
      grpc:
      http:
exporters:
  otlphttp:
    endpoint: https://your-install      # /v1/traces is added by the exporter
    encoding: json
    headers:
      x-api-key: agt_…
service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlphttp]

Gzip-compressed bodies are accepted, so the exporter's default compression can stay on. Set service.name on each service, through OTEL_SERVICE_NAME or the SDK's resource. If a browser page or a Node.js service calls this one with a traceparent, its spans continue the same trace, and the whole chain shows as one call.

Deploy markers

CI can mark a deploy with POST /api/deploy. Charts draw the marker, and tickets quote it when a fault starts soon after. See Deploy markers.