Skip to content

Observability

Nantian Gateway emits structured logs, Prometheus metrics, and optional OpenTelemetry traces from both the control plane and data plane. The data plane also supports Sentry error tracking. This page covers the configuration of each observability signal.

Both components use structured logging with JSON as the default format. Structured logs integrate directly with log aggregation systems such as Loki, Elasticsearch, and Datadog.

The control plane uses Go’s log/slog package:

ParameterTypeDefaultDescription
log.levelstringinfoMinimum log level: debug, info, warn, or error
log.formatstringjsonOutput format: json or text
log.add_sourceboolfalseInclude source file and line number in log entries

The debug level includes reconciliation details, configuration snapshot diffs, and gRPC stream events. This level generates substantially more output than info and should not remain enabled in production.

When log.add_source is enabled, each log entry includes the Go source file and line number. This adds a small overhead per log call but significantly aids debugging.

Each JSON log entry contains the fields time, level, msg, and context-specific attributes. Use the text format for local development where logs are read directly rather than processed by aggregation tools.

The data plane uses Rust’s tracing framework with fine-grained per-module control:

ParameterTypeDefaultDescription
log.levelstringinfo,nantian_core::connectors=offTracing filter directives
log.formatstringjsonOutput format: json or text
log.add_sourceboolfalseInclude source location
log.include_targetboolfalseInclude the tracing target (Rust module path)
log.include_thread_idsboolfalseInclude thread IDs
log.include_thread_namesboolfalseInclude thread names
log.non_blockingbooltrueUse non-blocking log output
log.non_blocking_buffered_linesint65536Ring buffer capacity
log.drop_when_fullbooltrueDrop logs when the buffer is full

The level field accepts tracing filter syntax for per-module granularity. For example, info,hyper=warn,tower=debug sets the global level to info, reduces hyper to warn, and increases tower to debug. The default suppresses verbose output from nantian_core::connectors.

Non-blocking logging is essential for a high-throughput proxy. A slow log sink (congested disk or network) can stall proxy threads when using blocking output. The ring buffer absorbs bursts, and drop_when_full ensures the proxy continues operating if the buffer overflows.

Both planes expose Prometheus metrics on configurable endpoints.

The control plane exposes an HTTP metrics endpoint at the configured path (default: /metrics). Metrics include:

  • Reconciliation counters — count of Kubernetes resource events processed, errors encountered, and configuration snapshots generated
  • gRPC stream metrics — active connections, messages sent and received, and connection duration
  • Go runtime metrics — goroutine count, memory allocation, and GC statistics

The data plane exposes Prometheus metrics on its admin listener at /metrics. There is no separate metrics server to enable or configure — the endpoint shares the admin address:

ParameterTypeDefaultDescription
admin_addrstring"127.0.0.1:19080"Admin listener address; serves /metrics alongside health endpoints

In Kubernetes, the Helm chart exposes this through the dataplane metrics Service on port 19080.

Key data plane metrics:

  • Request counters — total requests, grouped by HTTP method, status code, and route
  • Latency histograms — request duration percentiles (p50, p95, p99)
  • Connection metrics — active connections, connection rate, and connection duration
  • Upstream metrics — backend connection pool hits/misses, backend latency, and backend errors
  • AI gateway metrics — token counts, provider latency, and rate limit enforcement

For a complete metric reference, see Metrics Reference.

OpenTelemetry tracing is optional and is configured under log.open_telemetry in the data plane configuration:

ParameterTypeDefaultDescription
log.open_telemetry.enabledboolfalseEnable OpenTelemetry tracing
log.open_telemetry.endpointstring""OTLP collector endpoint
log.open_telemetry.protocolstring"grpc"OTLP transport (grpc or http)
log.open_telemetry.timeoutMsint3000Export timeout in milliseconds
log.open_telemetry.insecureboolfalseDisable TLS when connecting to the collector
log.open_telemetry.sampleRatiofloat1.0Sampling ratio (0.0 to 1.0)
log.open_telemetry.serviceNamestring"nantian-dataplane"Service name in trace data
log.open_telemetry.serviceNamespacestring""Service namespace in trace data

When enabled, the data plane propagates W3C trace-context headers and exports spans to the configured OTLP collector. Traces cover the request lifecycle: route matching, header transformation, upstream request, and response.

sampleRatio controls the fraction of requests that generate traces (default 1.0 traces all requests). For high-traffic production, lower this to reduce trace volume and storage cost.

The data plane supports Sentry error tracking for full APM: error/panic capture, performance tracing, breadcrumbs, and release tracking.

ParameterTypeDefaultDescription
log.sentry.enabledboolfalseEnable Sentry error tracking
log.sentry.dsnstring""Sentry DSN (Data Source Name)
log.sentry.environmentstring""Environment name (production, staging, development)
log.sentry.sample_ratefloat1.0Event sampling rate (0.0 to 1.0)
log.sentry.traces_sample_ratefloat0.01Performance transaction sampling rate (0.0 to 1.0)
log.sentry.attach_stacktracebooltrueAttach stack traces to error events
log.sentry.send_default_piiboolfalseSend personally identifiable information
log.sentry.debugboolfalseEnable Sentry SDK debug logging

Sentry is disabled by default. To enable, set log.sentry.enabled to true and provide a valid log.sentry.dsn. The DSN is available from your Sentry project settings.

When enabled, the data plane captures:

  • Errors and panics — all Rust panics and unhandled errors are captured and reported
  • Performance traces — transactions and spans from request processing
  • Breadcrumbs — context events leading up to errors
  • Release tracking — correlates events with the deployed data plane version

Sentry is an additional consumer of tracing events and does not replace existing OpenTelemetry tracing.

To configure Prometheus to scrape the data plane metrics:

scrape_configs:
- job_name: nantian-gw-dataplane
kubernetes_sd_configs:
- role: pod
namespaces:
names: [nantian-gw]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
action: keep
regex: nantian-gw-dataplane
- source_labels: [__meta_kubernetes_pod_container_port_number]
action: keep
regex: "19080"