OpenTelemetry Protocol (OTLP)
Synopsis
Creates a target that forwards telemetry data to any OpenTelemetry Protocol (OTLP)-compatible receiver. Supports HTTP and gRPC transports, protobuf and JSON encoding, gzip compression, custom headers, TLS, and configurable retry logic.
Schema
- name: <string>
description: <string>
type: otlp
pipelines: <pipeline[]>
status: <boolean>
properties:
url: <string>
address: <string>
port: <numeric>
protocol: <string>
path: <string>
format: <string>
compression: <boolean>
timeout: <numeric>
batch_size: <numeric>
max_retries: <numeric>
retry_delay: <numeric>
grpc_passthrough: <boolean>
headers:
<key>: <value>
tls:
status: <boolean>
verify: <boolean>
cert_name: <string>
key_name: <string>
server_name: <string>
min_tls_version: <string>
debug:
status: <boolean>
dont_send_logs: <boolean>
Configuration
The following fields are used to define the target:
| Field | Required | Default | Description |
|---|---|---|---|
name | Y | Target name | |
description | N | - | Optional description |
type | Y | Must be otlp | |
pipelines | N | - | Optional post-processor pipelines |
status | N | true | Enable/disable the target |
Connection
| Field | Required | Default | Description |
|---|---|---|---|
url | Y* | - | Full endpoint URL for HTTP (e.g. http://collector:4318) or host:port for gRPC |
address | Y* | - | Remote host; alternative to url |
port | Y* | - | Remote port; alternative to url |
* = Provide url or both address and port. Exactly one form is required.
Transport
| Field | Required | Default | Description |
|---|---|---|---|
protocol | N | http | Wire transport: http or grpc |
path | N | /v1/logs | HTTP URL path; leading / is added automatically. Use /v1/metrics or /v1/traces for other signals. HTTP only. |
format | N | protobuf | Encoding: protobuf or json. json is invalid with protocol: grpc. |
compression | N | true | Enable gzip compression |
Performance
| Field | Required | Default | Description |
|---|---|---|---|
timeout | N | 30 | Request or RPC timeout in seconds |
batch_size | N | 1000 | Maximum events per batch; must be >= 1 |
max_retries | N | 3 | Maximum delivery attempts on failure; must be >= 0 |
retry_delay | N | 1 | Seconds between retry attempts |
gRPC
| Field | Required | Default | Description |
|---|---|---|---|
grpc_passthrough | N | true | When true, sends raw OTLP bytes using content-subtype: raw-otlp (VirtualMetric-to-VirtualMetric only). When false, re-encodes as standard typed OTLP/gRPC for interoperability with any spec-compliant receiver. |
Headers
| Field | Required | Default | Description |
|---|---|---|---|
headers | N | - | Map of string key-value pairs added to every HTTP request or gRPC metadata (e.g. authorization tokens, tenant IDs) |
TLS
| Field | Required | Default | Description |
|---|---|---|---|
tls.status | N | false | Enable TLS |
tls.verify | N | true | Verify server certificate |
tls.cert_name | N* | - | Client certificate file name (PEM format) |
tls.key_name | N* | - | Client private key file name (PEM format) |
tls.server_name | N | - | SNI override / ServerName for TLS handshake |
tls.min_tls_version | N | tls1.2 | Minimum TLS version: tls1.0, tls1.1, tls1.2, tls1.3 |
* = tls.cert_name and tls.key_name must be provided together or omitted together.
Scheduling
See Scheduling and Pool Behavior for interval and cron fields shared by all targets.
Debug Options
| Field | Required | Default | Description |
|---|---|---|---|
debug.status | N | false | Enable debug logging |
debug.dont_send_logs | N | false | Process logs but don't send to target (testing) |
Details
The OTLP target delivers telemetry to any OpenTelemetry-compatible receiver — otel-collector, rotel, Grafana Alloy, vendor ingest endpoints, or another VirtualMetric Director.
Record translation
Records originating from this Director's own OTEL listener carry a JSON envelope with full Resource and Scope context. The target parses the envelope and reassembles each record as a one-record ExportLogsServiceRequest, preserving the original Resource and Scope end-to-end. This path is lossless.
Records from non-OTEL sources (TCP listener, syslog, etc.) are wrapped as a synthetic LogRecord with the body set to the raw message bytes and minimal resource attributes (service.name = the device name). This path is lossy by definition — non-OTEL sources have no OTLP context — but produces valid OTLP that any downstream collector accepts.
HTTP transport
HTTP is the default transport. Each worker maintains its own http.Client to avoid idle-connection contention. Batches are POSTed to endpoint + path. The Content-Type header is set to application/x-protobuf for format: protobuf and application/json for format: json. When compression: true, the body is gzip-compressed and Content-Encoding: gzip is set.
The path field controls the signal type delivered: /v1/logs (default), /v1/metrics, or /v1/traces. The wire payload for all three is the corresponding OTLP proto message — only the path and embedded message type differ.
gRPC transport
When protocol: grpc, each worker maintains its own grpc.ClientConn. The gRPC method path is fixed to /opentelemetry.proto.collector.logs.v1.LogsService/Export (logs only in v1; metrics and traces require the HTTP path via path).
grpc_passthrough: true (default): sends raw OTLP bytes using grpcraw.Codec with content-subtype: raw-otlp. This is the fast path for VirtualMetric-to-VirtualMetric relay — one Director to another with no re-serialization. Standard OTLP/gRPC receivers (otel-collector, rotel, vendor gateways) reject this subtype as Unimplemented.
grpc_passthrough: false: re-encodes each batch into the typed proto message (ExportLogsServiceRequest, etc.) using the standard gRPC codec and marshals with UnmarshalVT. This produces spec-compliant OTLP/gRPC that any receiver accepts, at the cost of one additional unmarshal+marshal per outbound batch. Use false for cross-vendor deployments.
Configuration validation
The following rules are enforced at config load:
urlor (address+port) must be provided; providing neither is rejected.formatmust beprotobuforjson.format: jsoncombined withprotocol: grpcis rejected — OTLP/gRPC is protobuf-only on the wire.batch_sizemust be >= 1.max_retriesmust be >= 0.tls.cert_nameandtls.key_namemust both be present or both be absent.
Examples
Basic HTTP
Forwarding logs to an OTLP/HTTP collector with default settings... | |
JSON Format over HTTP
Sending telemetry as JSON-encoded OTLP to an HTTP endpoint... | |
gRPC Spec-Compliant
Delivering logs over gRPC to a third-party collector using typed OTLP encoding... | |
TLS-Secured
Sending logs over HTTPS with mutual TLS client certificate authentication... | |
Performance Tuning
High-volume configuration with large batches, retry logic, and auth header... | |