Skip to content
OpenPerf
Esc
↑↓navigate↵open⌘Jpreview
On this page

OpenTelemetry

Send traces and logs from any OpenTelemetry SDK or collector without the OpenPerf SDK.

OpenPerf accepts OTLP over HTTP, so any OpenTelemetry SDK or the Collector can send to it. Use this for languages the SDK doesn’t cover, or an app that already uses OpenTelemetry.

Signal Path
Traces /v1/traces
Logs /v1/logs

Metrics and gRPC are not accepted. Bodies are protobuf (application/x-protobuf) or JSON (application/json), plain or gzip.

Connect

Copy the DSN from the project settings, under Connection. Its token, opf_…, authenticates the requests. The Endpoint shown there is the intake address with /v1 already added.

With the standard environment variables:

OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.example.com"
OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20opf_…"
OTEL_METRICS_EXPORTER="none"
OTEL_SERVICE_NAME="checkout"
OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=production,service.version=1.4.2"

OTEL_EXPORTER_OTLP_ENDPOINT takes the address without /v1; the SDK adds /v1/traces and /v1/logs. Per-signal variables such as OTEL_EXPORTER_OTLP_TRACES_ENDPOINT take the full URL.

A client that can’t set headers can pass the token as ?key=opf_… instead.

Browser exporters work too. The intake answers CORS preflights, and Allowed origins in the project settings limits which sites may send. Empty accepts any origin; requests from an unlisted origin get 403.

Send a request

curl https://ingest.example.com/v1/logs \
  -H "Authorization: Bearer opf_…" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceLogs": [{
      "resource": { "attributes": [
        { "key": "service.name", "value": { "stringValue": "checkout" } }
      ] },
      "scopeLogs": [{ "logRecords": [{
        "severityNumber": 17,
        "body": { "stringValue": "Payment failed" },
        "attributes": [
          { "key": "exception.type", "value": { "stringValue": "PaymentError" } }
        ]
      }] }]
    }]
  }'

The log shows under Logs and, because it carries exception.type, as an error under Errors.

Attributes OpenPerf reads

Resource attributes:

Attribute Used for
service.name The service. unknown when missing.
deployment.environment.name The environment. deployment.environment also works. default when missing.
service.version The release. Needed for source maps and release health.
vcs.ref.head.revision The commit the code was built from.
telemetry.sdk.language webjs, set by OpenTelemetry’s web SDK, marks the data as coming from a browser.

Span and log attributes:

Attribute Used for
exception.type, exception.message, exception.stacktrace The error’s type, message and stack.
openperf.error.fingerprint Groups all errors with the same value together.
user.id, user.email, user.name The user.
http.route Names server transactions, such as GET /users/:id.

Errors

An error is created from:

  • a span event named exception, which recordException adds. Its level is error.
  • a log record with exception.type or exception.stacktrace. Its level follows the log severity: fatal, error, or warn for anything lower.

Errors with a similar type and stack join the same group. Set openperf.error.fingerprint to group them yourself.

Transactions

Root spans, server spans and consumer spans count as transactions in Performance. In the browser, the documentLoad span of the document load instrumentation counts as a page load.

Responses

Status Meaning
200 Accepted. Spans without a valid trace or span ID are dropped and counted in partialSuccess.
400 The body isn’t valid OTLP.
401 Unknown token.
403 The browser origin isn’t in Allowed origins.
413 The body is too large. The limit is 10 MB unless your operator changed it.
415 Unsupported content type or encoding.
429 Rate limited, too many invalid tokens, or the intake is busy. Retry after Retry-After seconds.
503 The intake is unavailable. Retry after Retry-After seconds.

A body identical to one sent in the last 15 minutes is answered with 200 and dropped, so retries are safe.

Was this page helpful?