Send telemetry with OpenTelemetry (OTLP)
Pulse accepts logs, traces and metrics over OTLP/HTTP. You use the standard OpenTelemetry SDKs and exporters, with no proprietary agent. This page covers the endpoints, how to authenticate, the limits and how Pulse maps what you send.
You need a project ingest key; see Send your first logs for how to create one.
Endpoints
Section titled “Endpoints”Through the web address of your company:
| Signal | URL |
|---|---|
| Logs | https://acme.orbit.inortix.com/otlp/v1/logs |
| Traces | https://acme.orbit.inortix.com/otlp/v1/traces |
| Metrics | https://acme.orbit.inortix.com/otlp/v1/metrics |
Bodies are application/x-protobuf or application/json. The Content-Encoding header may be gzip, deflate, zstd or br. Errors are answered with a google.rpc.Status body in the encoding of the request.
Authentication
Section titled “Authentication”Send the ingest key in one of two headers:
X-Pulse-Key: <ingest key>Authorization: Bearer <ingest key>The key decides the project. Anything in the payload that names a project is ignored.
Configure an SDK
Section titled “Configure an SDK”The standard OpenTelemetry environment variables work. The exporter appends /v1/traces, /v1/logs and /v1/metrics to the base endpoint.
OTEL_EXPORTER_OTLP_ENDPOINT=https://acme.orbit.inortix.com/otlpOTEL_EXPORTER_OTLP_HEADERS=X-Pulse-Key=<ingest key>OTEL_SERVICE_NAME=checkoutOTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=stagingOTEL_TRACES_SAMPLER_ARG=1OTEL_TRACES_SAMPLER_ARG is the sampling ratio when you use a ratio sampler.
How resource attributes are mapped
Section titled “How resource attributes are mapped”| OTLP resource attribute | Pulse field |
|---|---|
service.name |
service |
service.version |
version |
deployment.environment.name |
env |
host.name |
host |
telemetry.sdk.language |
source |
All resource attributes are also kept as tags. OTLP severity numbers map to Pulse statuses (FATAL becomes critical). The bounds are the same as for JSON logs: 256 attributes, 128 tags, keys 256 bytes, values 16 KiB, messages 64 KiB, nesting depth 8.
Partial success
Section titled “Partial success”A request can succeed in part. Pulse answers 200 with a partialSuccess object and keeps the valid records:
| Signal | What partialSuccess counts as rejected |
|---|---|
| Logs | rejectedLogRecords: records outside the project’s retention window or more than 2 hours in the future |
| Traces | rejectedSpans: spans outside retention, more than 2 hours in the future, or without a trace or span id |
| Metrics | rejectedDataPoints: points outside retention or in the future, exponential histograms and summaries (not supported yet), invalid names or buckets, and points of new series over the daily series limit. The first reason is in errorMessage. |
When a daily quota is crossed, the records that fit are kept and the rest rejected, with the reason in errorMessage.
Limits per request
Section titled “Limits per request”- At most 10,000 records.
- Body size per key: default 5 MiB, at most 16 MiB (set when the key is created).
- Decompressed size at most 8 times the key’s body limit, capped at 64 MiB.
- Each key has a records-per-minute budget that is all-or-nothing per request: an over-budget request gets
429withRetry-Afterand stores nothing.
How spans are interpreted
Section titled “How spans are interpreted”| Field | Source |
|---|---|
| kind | OTLP span kind: server, client, producer, consumer, otherwise internal |
| status | error when the OTLP status code is ERROR, otherwise ok; the status message is kept |
| entry span | true for service entry spans: no parent, server or consumer kind, or a remote parent. Entry spans define a service’s requests, errors and latency. |
| resource (the endpoint) | http.request.method plus http.route for HTTP servers (GET /orders/{id}); db.query.summary or db.operation.name plus db.collection.name for databases; messaging.operation.type plus messaging.destination.name; rpc.service and rpc.method; otherwise the span name (at most 512 bytes) |
peer.service |
For client and producer spans: peer.service, else db.system.name, messaging.system, server.address or the host of url.full |
| error | The first exception event (exception.type, exception.message, exception.stacktrace, stack up to 32 KiB); otherwise the status message and the error.type attribute on error spans |
| events | Up to 128 events with their attributes |
Pulse rolls entry spans and client spans up per minute (hits, errors, duration and a latency sketch for quantiles). All error traces and slow traces are retained; the rest are sampled at a configured rate, and the rollups stay complete.
Link logs and traces
Section titled “Link logs and traces”Use the same service name (service.name) in your logs and in your traces, so that logs, traces and errors meet under one service. If your logging library adds the current trace_id and span_id to log records, a log opens its trace and a trace opens its logs.