Skip to main content

otel subscriber

Native OTLP exporter. Ships logs (every event becomes an OTLP log record) and metrics (only events in the metrics namespace — every other OpenZiti event is interval- or transaction-shaped and would produce incorrect rates if mapped to instruments). Talks to any OTel-compliant endpoint: a Collector, a vendor backend (Grafana Cloud, Honeycomb, New Relic, …), or a ClickHouse-via-OTel pipeline without the webhook hop.

Add to the subscribers block in config.yaml:

subscribers:
otel:
enabled: true
protocol: http # http (default) or grpc
endpoint: http://otel.internal:4318
compression: gzip
headers:
Authorization: "Bearer ${OTEL_TOKEN}"
service_name: nf-data-connector
resource_attributes:
deployment.environment: prod
logs:
enabled: true
attribute_paths: # promote event fields onto OTLP log attributes
ziti.identity: identity_name
ziti.service: service_name
ziti.source_id: source_id
ziti.event_type: event_type
batch_size: 100
flush_interval: 5s
metrics:
enabled: true
metric_prefix: "openziti."
attribute_paths:
ziti.source_id: source_id
ziti.source_type: source_type
ziti.metric_type: metric_type
collection_interval: 60s
buffer_size: 5000

Transport (shared by logs and metrics)

Available fields and defaults

FieldDefaultDescription
protocolhttphttp (OTLP/HTTP, port 4318) or grpc (OTLP/gRPC, port 4317)
endpointBase URL for HTTP (https://otel:4318) or host:port for gRPC (otel:4317)
insecurefalseDisable TLS entirely
skip_verifyfalseKeep TLS but skip cert verification
compressiongzipgzip or none
timeout10sPer-export request timeout
headersExtra headers (e.g. Authorization)
service_namenf-data-connectorOTel service.name resource attribute
service_instance_idunsetOTel service.instance.id resource attribute
resource_attributesAdditional resource attributes (map)
buffer_size1000Subscriber channel capacity

logs

Available fields and defaults

FieldDefaultDescription
enabledfalseEmit OTLP log records
severityPer-namespace severity override (e.g. circuit: WARN); names per OTLP severity (TRACE..FATAL)
attribute_pathsattribute key → gjson path; promotes event fields to log attributes
timestamp_pathsPer-namespace gjson path overriding the event timestamp
default_timestamp_pathFallback timestamp path used before Event.Timestamp
namespace_filter[]Restrict to specific event namespaces; empty allows all
exclude_fields[]Dotted paths to strip from the body
include[]Per-event predicates against the enriched payload; any-of. Empty = pass everything. See Per-subscriber filtering.
exclude[]Per-event predicates; none-of — if any matches, drop the event.
batch_size100Records per export
flush_interval5sMax time a partial batch sits before being exported
max_queue_sizeunsetOverride the SDK queue size (defaults to SDK default)

metrics

Available fields and defaults

FieldDefaultDescription
enabledfalseEmit OTLP metrics
metric_prefixopenziti.Prefix applied to every instrument name
static_attributesAttributes attached to every metric data point
attribute_pathsattribute key → gjson path resolved per-event
includeRegex allowlist over the final metric name
excludeRegex blocklist over the final metric name
collection_interval60sPeriodicReader interval

Notes

  • Log record Timestamp is OpenZiti's event time (top-level timestamp field on every event); ObservedTimestamp is the connector's receive time.
  • The metrics path emits every numeric leaf in each metrics-namespace event as a gauge named <metric_prefix><metric_name>[.<leaf_key>]. Counter/histogram refinement (respecting OpenZiti's metric_type) is a future enhancement; gauges are correct for instantaneous values across every metric the controller emits today.
  • Metric names are sanitized to the OTLP instrument-name charset ([A-Za-z0-9_./-]); REST-route metrics like /edge/management/v1/…/:id.DELETE are accepted and emitted with : replaced by _.
  • For a quick local sanity check the repo ships an example OTel Collector config at docs/examples/otel-debug-collector.yaml that dumps every received record to stdout.