Skip to main content

OpenTelemetry Protocol (OTLP)

Network

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:

FieldRequiredDefaultDescription
nameYTarget name
descriptionN-Optional description
typeYMust be otlp
pipelinesN-Optional post-processor pipelines
statusNtrueEnable/disable the target

Connection

FieldRequiredDefaultDescription
urlY*-Full endpoint URL for HTTP (e.g. http://collector:4318) or host:port for gRPC
addressY*-Remote host; alternative to url
portY*-Remote port; alternative to url

* = Provide url or both address and port. Exactly one form is required.

Transport

FieldRequiredDefaultDescription
protocolNhttpWire transport: http or grpc
pathN/v1/logsHTTP URL path; leading / is added automatically. Use /v1/metrics or /v1/traces for other signals. HTTP only.
formatNprotobufEncoding: protobuf or json. json is invalid with protocol: grpc.
compressionNtrueEnable gzip compression

Performance

FieldRequiredDefaultDescription
timeoutN30Request or RPC timeout in seconds
batch_sizeN1000Maximum events per batch; must be >= 1
max_retriesN3Maximum delivery attempts on failure; must be >= 0
retry_delayN1Seconds between retry attempts

gRPC

FieldRequiredDefaultDescription
grpc_passthroughNtrueWhen 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

FieldRequiredDefaultDescription
headersN-Map of string key-value pairs added to every HTTP request or gRPC metadata (e.g. authorization tokens, tenant IDs)

TLS

FieldRequiredDefaultDescription
tls.statusNfalseEnable TLS
tls.verifyNtrueVerify server certificate
tls.cert_nameN*-Client certificate file name (PEM format)
tls.key_nameN*-Client private key file name (PEM format)
tls.server_nameN-SNI override / ServerName for TLS handshake
tls.min_tls_versionNtls1.2Minimum 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

FieldRequiredDefaultDescription
debug.statusNfalseEnable debug logging
debug.dont_send_logsNfalseProcess 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:

  • url or (address + port) must be provided; providing neither is rejected.
  • format must be protobuf or json.
  • format: json combined with protocol: grpc is rejected — OTLP/gRPC is protobuf-only on the wire.
  • batch_size must be >= 1.
  • max_retries must be >= 0.
  • tls.cert_name and tls.key_name must both be present or both be absent.

Examples

Basic HTTP

Forwarding logs to an OTLP/HTTP collector with default settings...

targets:
- name: otel_collector
type: otlp
properties:
url: "http://otel-collector.example.com:4318"

JSON Format over HTTP

Sending telemetry as JSON-encoded OTLP to an HTTP endpoint...

targets:
- name: otel_json
type: otlp
properties:
url: "http://otel-collector.example.com:4318"
format: json
path: /v1/logs

gRPC Spec-Compliant

Delivering logs over gRPC to a third-party collector using typed OTLP encoding...

targets:
- name: grpc_collector
type: otlp
properties:
address: "otel-collector.example.com"
port: 4317
protocol: grpc
grpc_passthrough: false

TLS-Secured

Sending logs over HTTPS with mutual TLS client certificate authentication...

targets:
- name: otel_secure
type: otlp
properties:
url: "https://otel-collector.example.com:4318"
tls:
status: true
verify: true
cert_name: "client-cert.pem"
key_name: "client-key.pem"
min_tls_version: "tls1.2"

Performance Tuning

High-volume configuration with large batches, retry logic, and auth header...

targets:
- name: otel_high_volume
type: otlp
properties:
url: "https://ingest.example.com:4318"
format: protobuf
compression: true
batch_size: 5000
timeout: 60
max_retries: 5
retry_delay: 2
headers:
Authorization: "Bearer ${OTLP_TOKEN}"
X-Tenant-ID: "tenant-prod"