Skip to content

Sending Data with OTLP

Marc Netterfield edited this page Aug 25, 2026 · 1 revision

Sending data with OTLP

ktranslate can export SNMP, flow rollups, traps, syslog, and container health over OpenTelemetry Protocol (OTLP). This is the path used with Grafana Alloy and Grafana Cloud.

These flags landed across PR #653 (format), #695 (TLS), #698 (traps), #765 (rollups), #767 (logs), #847 (trap logs), and #923 (CHF / jchf health metrics).

The ktranslate README -h dump still omits most of these flags. Use this page plus ktranslate -h from a current binary.

Minimum flags

Flag Default Purpose
-format otel flat_json Encode telemetry as OTLP.
-sinks otel stdout Use the OTEL sink (the formatter talks to the collector; this sink also tees logs).
-otel.endpoint empty Collector URL. Example: http://alloy:4317/ (gRPC) or https://otlp-gateway-….grafana.net/otlp (HTTP). If unset, ktranslate prints to stdout for debugging (#656).
-otel.protocol stdout grpc, http, https, or stdout.
-format_metric otel (inherit) Required if you want --metrics=jchf container-health series on the same OTLP connection.
-tee_logs=true false Forward ktranslate logs (and syslog/trap text) onto the log pipeline.
-service_name ktranslate Resource service.name (use a distinct value per container: ktranslate-snmp, ktranslate-flow, …).

Optional TLS (#695):

Flag Purpose
-otel.tls_cert Client certificate file.
-otel.tls_key Client key file.
-otel.root_ca Root CA file.
-otel.no_block Drop metrics when the export channel is full instead of blocking.

If all three of tls_cert, tls_key, and root_ca are set, ktranslate applies that TLS config to gRPC and HTTP exporters.

Useful environment variables (OpenTelemetry SDK):

Variable Purpose
OTEL_METRIC_EXPORT_INTERVAL Export interval in milliseconds (SDK default is 60000). Example: 30000.

Grafana Cloud / Alloy (flow)

Grafana Cloud’s Netflow integration uses this pattern. Alloy listens on OTLP gRPC :4317 and forwards to Grafana Cloud:

docker run -d --name ktranslate --cap-add net_raw --net=host kentik/ktranslate:v2 \
  --format=otel \
  --format_metric=otel \
  --otel.protocol=grpc \
  --otel.endpoint=http://localhost:4317/ \
  --nf.source=auto \
  --nf.port=9995 \
  --sinks=otel \
  --rollup_interval=60 \
  --tee_logs=true \
  --service_name=flow \
  --max_flows_per_message=100 \
  --metrics=jchf \
  --rollups=s_sum,bytes_by_flow,in_bytes+out_bytes,src_addr,dst_addr,l4_src_port,l4_dst_port,protocol,custom_str.application,device_name,custom_str.src_host,custom_str.dst_host,src_geo,dst_geo \
  --rollup_top_k=10 \
  --rollup_keep_undefined=true

Point -otel.endpoint at Alloy when it is not on localhost. Rollup syntax is documented in Sinks, formats, and rollups.

SNMP poller

Same OTLP flags; add the SNMP config instead of -nf.source:

docker run -d --name ktranslate-snmp -p 162:1620/udp \
  -v `pwd`/snmp-base.yaml:/snmp-base.yaml \
  kentik/ktranslate:v2 \
    --snmp /snmp-base.yaml \
    --format=otel \
    --format_metric=otel \
    --otel.protocol=grpc \
    --otel.endpoint=http://alloy:4317/ \
    --sinks=otel \
    --metrics=jchf \
    --tee_logs=true \
    --service_name=ktranslate-snmp

Traps and syslog as logs

With -format=otel, SNMP traps are written as logs (not metrics) and forwarded by the OTEL pipeline (#698, #847). Syslog and --tee_logs use the same log path (#767).

Trap listen settings stay in snmp-base.yaml (trap.listen, trap.version, drop_undefined, …). See Advanced Configuration.

Container health (CHF / jchf)

--metrics=jchf emits kentik.ktranslate.chf.kkc.* (queue depth, ingest rates, netflow.flows, baseserver health).

On OTLP those series only leave the process when:

  1. -format_metric=otel (or -format=otel and no other metric format), and
  2. the health channel is not swallowed by rollup accumulation.

PR #923 fixed the common --format=otel --rollups=… case. If you still do not see kentik_ktranslate_chf_kkc_* in Grafana, confirm both format flags and recreate the container.

What is not an OTLP sink flag

ktranslate also has -http_url / -http_log_url for HTTP sinks (Splunk HEC, generic webhooks). That is a different path — see Sinks, formats, and rollups.

Clone this wiki locally