Edge Delta OTLP Destination Node

Configure the OTLP destination node in Edge Delta to send telemetry data over gRPC or HTTP to a specified endpoint.

Overview

The OTLP (OpenTelemetry Protocol) destination node in Edge Delta is used to send logs, metrics, and traces to a specified OTLP endpoint using either gRPC or HTTP protocols. This node can handle multiple data types and supports both protobuf and JSON encoding for HTTP connections, providing a comprehensive solution for telemetry data transmission. The OTLP output node requires Edge Delta version 1.32.0.

This node requires Edge Delta agent version v1.32.0 or higher.

Example Configuration

gRPC Protocol Example

nodes:
  - name: my_otlp_stream
    type: otlp_output
    endpoint: example.com
    port: 443
    protocol: grpc
    tls:
      enabled: true
      ignore_certificate_check: false
      ca_file: /path/to/ca_file.pem

HTTP Protocol Example

nodes:
  - name: my_otlp_http_stream
    type: otlp_output
    endpoint: endpoint.example.com/receiver/v1/otlp
    port: 443
    protocol: http
    encoding: proto
    tls:
      enabled: true
    headers:
      - header: Authorization
        value: Api-Token <your-token>

Required Parameters

name

A descriptive name for the node. This is the name that will appear in pipeline builder and you can reference this node in the YAML using the name. It must be unique across all nodes. It is a YAML list element so it begins with a - and a space followed by the string. It is a required parameter for all nodes.

nodes:
  - name: <node name>
    type: <node type>

type: otlp_output

The type parameter specifies the type of node being configured. It is specified as a string from a closed list of node types. It is a required parameter.

nodes:
  - name: <node name>
    type: <node type>

endpoint

The endpoint parameter specifies the OTLP server endpoint to send telemetry data. It is required and must be specified as a string without the protocol prefix (do not include http:// or https://). For HTTPS endpoints, configure TLS separately using the tls.enabled parameter.

nodes:
  - name: <node name>
    type: otlp_output
    endpoint: example.com/v1/otlp
    port: <port number>

Examples:

  • For gRPC: endpoint: otel.example.com
  • For HTTP: endpoint: collector.example.com/v1/traces
  • For HTTPS: endpoint: secure.example.com/receiver with tls.enabled: true

port

The port parameter defines the port number for the OTLP endpoint. It should be an integer between 1 and 65535 and is required.

protocol

The protocol parameter specifies the transport protocol to use for sending OTLP data. It is required and must be one of:

  • grpc - Use gRPC protocol (default)
  • http - Use HTTP protocol
nodes:
  - name: <node name>
    type: otlp_output
    endpoint: <OTLP server URI>
    port: <port number>
    protocol: http

Note: When using http protocol with HTTPS endpoints, you must enable TLS by setting tls.enabled: true.

encoding

The encoding parameter specifies the encoding format for OTLP data when using HTTP protocol. It is required when protocol is set to http. Options are:

  • proto - Use Protocol Buffers (protobuf) encoding (recommended)
  • json - Use JSON encoding
nodes:
  - name: <node name>
    type: otlp_output
    endpoint: <OTLP server URI>
    port: <port number>
    protocol: http
    encoding: proto

Note: This parameter only applies to HTTP protocol and is ignored when using gRPC.

Optional Parameters

TLS Configuration

The tls parameter allows configuring SSL/TLS settings. It includes sub-parameters like enabled, ignore_certificate_check, ca_file, among others, which control the security configuration for both gRPC and HTTP connections. All TLS settings are optional.

nodes:
  - name: <node name>
    type: otlp_output
    endpoint: <OTLP server URI>
    port: <port number>
    tls:
      enabled: true
      ignore_certificate_check: true
      ca_file: /path/to/ca_file.pem

Note: When using HTTP protocol with HTTPS endpoints, you must set tls.enabled: true.

headers

The headers parameter allows you to specify custom HTTP headers to be sent with OTLP requests. This is commonly used for authentication tokens or API keys. Each header consists of a header name and a value.

nodes:
  - name: <node name>
    type: otlp_output
    endpoint: <OTLP server URI>
    port: <port number>
    protocol: http
    headers:
      - header: Authorization
        value: Bearer <your-token>
      - header: X-Custom-Header
        value: <custom-value>

Note: For gRPC protocol, headers are sent as metadata. Please refer to the gRPC metadata documentation for more details.

Integration Examples

Dynatrace

nodes:
  - name: dynatrace_otlp
    type: otlp_output
    endpoint: your-environment-id.live.dynatrace.com/api/v2/otlp
    port: 443
    protocol: http
    encoding: json
    tls:
      enabled: true
    headers:
      - header: Authorization
        value: Api-Token <your-dynatrace-token>

Sumo Logic

nodes:
  - name: sumologic_otlp
    type: otlp_output
    endpoint: endpoint.collection.sumologic.com/receiver/v1/otlp/<your-collector-token>
    port: 443
    protocol: http
    encoding: proto
    tls:
      enabled: true

Important Notes

  • Endpoint Format: Do not include http:// or https:// in the endpoint field. Use the tls.enabled parameter to specify secure connections.
  • Port Specification: When using HTTPS endpoints (port 443), ensure tls.enabled: true is set.
  • Encoding for HTTP: When using HTTP protocol, specify the encoding parameter. Protobuf (proto) is recommended for better performance and smaller payload sizes.
  • Authentication: Use the headers parameter to add authentication tokens or API keys required by your OTLP receiver.

Troubleshooting

For detailed troubleshooting guidance including:

  • Connection errors and timeout issues
  • Authentication failures (401 errors)
  • Endpoint configuration problems
  • Protocol-specific troubleshooting (gRPC vs HTTP)
  • Destination-specific configuration examples

See the comprehensive OTLP Destination Troubleshooting guide.

persistent_queue

The persistent_queue configuration enables disk-based buffering to prevent data loss during destination failures or slowdowns. When enabled, the agent stores data on disk and automatically retries delivery when the destination recovers.

Complete example:

persistent_queue:
  path: /var/lib/edgedelta/outputbuffer
  mode: error
  max_byte_size: 1GB
  drain_rate_limit: 1000

How it works:

  1. Normal operation: Data flows directly to the destination (for error and backpressure modes) or through the disk buffer (for always mode)
  2. Destination issue detected: Based on the configured mode, data is written to disk at the configured path
  3. Recovery: When the destination recovers, buffered data drains at the configured drain_rate_limit while new data continues flowing
  4. Completion: Buffer clears and normal operation resumes

Key benefits:

  • Data durability: Logs preserved during destination outages and slowdowns
  • Agent protection: Slow backends don’t cascade failures into the agent cluster
  • Automatic recovery: No manual intervention required
  • Configurable behavior: Choose when and how buffering occurs based on your needs

Learn more: Buffer Configuration - Conceptual overview, sizing guidance, and troubleshooting

path

The path parameter specifies the directory where buffered data is stored on disk. This parameter is required when configuring a persistent queue.

Example:

persistent_queue:
  path: /var/lib/edgedelta/outputbuffer

Requirements:

  • Required field - persistent queue will not function without a valid path
  • The directory must have sufficient disk space for the configured max_byte_size
  • The agent process must have read/write permissions to this location
  • The path should be on a persistent volume (not tmpfs or memory-backed filesystem)

Best practices:

  • Use dedicated storage for buffer data separate from logs
  • Monitor disk usage to prevent buffer from filling available space
  • Ensure the path persists across agent restarts to maintain buffered data

max_byte_size

The max_byte_size parameter defines the maximum disk space the persistent buffer is allowed to use. Once this limit is reached, any new incoming items are dropped, ensuring the buffer never grows beyond the configured maximum.

Example:

persistent_queue:
  path: /var/lib/edgedelta/outputbuffer
  max_byte_size: 1GB

Sizing guidance:

  • Small deployments (1-10 logs/sec): 100MB - 500MB
  • Medium deployments (10-100 logs/sec): 500MB - 2GB
  • Large deployments (100+ logs/sec): 2GB - 10GB

Calculation example:

Average log size: 1KB
Expected outage duration: 1 hour
Log rate: 100 logs/sec

Buffer size = 1KB × 100 logs/sec × 3600 sec = 360MB
Recommended: 500MB - 1GB (with safety margin)

Important: Set this value based on your disk space availability and expected outage duration. The buffer will accumulate data during destination failures and drain when the destination recovers.

mode

The mode parameter determines when data is buffered to disk. Three modes are available:

  • error (default) - Buffers data only when the destination returns errors (connection failures, HTTP 5xx errors, timeouts). During healthy operation, data flows directly to the destination without buffering.

  • backpressure - Buffers data when the in-memory queue reaches 80% capacity OR when destination errors occur. This mode helps handle slow destinations that respond successfully but take longer than usual to process requests.

  • always - Uses write-ahead-log behavior where all data is written to disk before being sent to the destination. This provides maximum durability but adds disk I/O overhead to every operation.

Example:

persistent_queue:
  path: /var/lib/edgedelta/outputbuffer
  mode: error
  max_byte_size: 1GB

Mode comparison:

ModeProtects AgainstTrade-offRecommended For
errorDestination outages and failuresNo protection during slow responsesReliable destinations with consistent response times
backpressureOutages + slow/degraded destinationsSlightly more disk writes during slowdownsMost production deployments
alwaysAll scenarios including agent crashesDisk I/O on every item reduces throughputMaximum durability requirements

Why choose error mode:

The error mode provides the minimal protection layer needed to prevent data loss when destinations temporarily fail. Without any persistent queue, a destination outage means data is lost. With error mode enabled, data is preserved on disk during failures and delivered automatically when the destination recovers.

Why choose backpressure mode:

The backpressure mode provides everything error mode offers, plus protection against slow destinations. When a destination is slow but not completely down:

  • Without backpressure: Data delivery becomes unreliable, and the backend’s slowness propagates to the agent—the agent can get stuck waiting before sending subsequent payloads
  • With backpressure: The agent spills data to disk and continues processing, isolating itself from the slow backend

This prevents a slow destination from cascading failures into your agent cluster. For most production environments, backpressure provides the best balance of protection and performance.

Why choose always mode:

The always mode is designed for customers with extremely strict durability requirements. It forces the agent to write every item to disk before attempting delivery, then reads from disk for transmission. This guarantees that data survives even sudden agent crashes or restarts.

Important: This mode introduces a measurable performance cost. Each agent performs additional disk I/O on every item, which reduces overall throughput. Most deployments do not require this level of durability—this feature addresses specialized needs that apply to a small minority of customers.

Only enable always mode if you have a specific, well-understood requirement where the durability guarantee outweighs the throughput reduction.

strict_ordering

The strict_ordering parameter controls how items are consumed from the persistent buffer.

When strict_ordering: true, the agent runs in strict ordering mode with a single processing thread. This mode always prioritizes draining buffered items first—new incoming data waits until all buffered items are processed in exact chronological order. When strict_ordering: false (default), multiple workers process data in parallel, and new data flows directly to the destination while buffered data drains in the background.

Example:

persistent_queue:
  path: /var/lib/edgedelta/outputbuffer
  mode: always
  strict_ordering: true
parallel_workers: 1

Default value: false

Important: Strict ordering is a specialized feature needed by a very small minority of deployments. Most users should keep the default value of false. Only enable strict ordering if you have a specific, well-understood requirement for exact event sequencing.

Required setting: When strict_ordering: true, you must set parallel_workers: 1. Pipeline validation will fail if parallel_workers is greater than 1 because parallel processing inherently breaks ordering guarantees.

Behavior:

ValueProcessing ModelBuffer PriorityRecovery Latency
false (default)Parallel workersBuffered data drains in backgroundLower - current state visible immediately
trueSingle-threadedBuffered items always drain firstHigher - queue must drain before new data

Why the default is false:

In most observability use cases, data freshness is more valuable than strict ordering. When a destination recovers from an outage, operators typically want to see current system state on dashboards immediately, while historical data backfills in the background. The default behavior prioritizes this real-time visibility.

When to enable strict ordering:

Strict ordering is primarily needed by security-focused customers who build systems where events must arrive in the exact delivery order. These customers typically run stateful security streaming engines that depend on precise temporal sequencing.

Specific use cases:

  • Stateful security streaming engines - Security systems that maintain state across events and detect patterns based on exact event order
  • Audit and compliance logs - Regulatory requirements that mandate audit trails preserve exact temporal sequence
  • State reconstruction - Systems that replay events to rebuild state require chronological order

When to keep default (false):

The vast majority of deployments should keep the default:

  • Real-time monitoring dashboards - Current state visibility is more important than historical order
  • High-volume log ingestion - Faster drain times reduce recovery period
  • Stateless analytics - When each log is analyzed independently without temporal correlation

drain_rate_limit

The drain_rate_limit parameter controls the maximum items per second when draining the persistent buffer after a destination recovers from a failure.

Example:

persistent_queue:
  path: /var/lib/edgedelta/outputbuffer
  drain_rate_limit: 1000

Default value: 0 (no limit - drain as fast as the destination accepts)

Why rate limiting matters:

When a destination recovers from an outage, it may still be fragile. Immediately flooding it with hours of backlogged data can trigger another failure. The drain rate limit allows gradual, controlled recovery that protects destination stability.

Choosing the right rate:

ScenarioRecommended RateReasoning
Stable, well-provisioned destination0 (unlimited)Minimize recovery time when destination can handle full load
Shared or multi-tenant destination20-50% of capacityLeave headroom for live traffic and other tenants
Recently recovered destination10-25% of capacityGentle ramp-up to prevent re-triggering failure
Rate-limited destination (e.g., SaaS)Below API rate limitAvoid throttling or quota exhaustion

Impact on recovery time:

Buffer size: 1GB
Average log size: 1KB
Total items: ~1,000,000 logs

At unlimited (0): Depends on destination capacity
At 5000:      ~3.5 minutes to drain
At 1000:      ~17 minutes to drain
At 100:       ~2.8 hours to drain