Build And Deploy

Telemetry

Use OpenTelemetry-compatible environment variables to enable request ids, context logs, spans, and request metrics.

By Guillermo Alvarez - Published - Updated

Activation

GoLazy telemetry is off by default. lazyapp.New installs telemetry middleware when the process has meaningful, known OpenTelemetry environment configuration.

This enables telemetry:

OTEL_SERVICE_NAME=sample_app ./sample-app
OTEL_TRACES_EXPORTER=otlp OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 ./sample-app
OTEL_LOGS_EXPORTER=otlp/stdout ./sample-app

This keeps telemetry disabled:

OTEL_SDK_DISABLED=true ./sample-app
OTEL_TRACES_EXPORTER=none OTEL_METRICS_EXPORTER=none OTEL_LOGS_EXPORTER=none ./sample-app

OTEL_SDK_DISABLED=true wins over other telemetry variables. Setting OTEL_SDK_DISABLED=false by itself does not activate telemetry. Unknown OTEL_* variables do not activate telemetry by themselves.

Request context

When telemetry is active, GoLazy adds one request middleware before the normal route dispatcher. It:

  • reads X-Request-ID or X-Correlation-ID when the value is safe;
  • generates a request id when no valid id is present;
  • writes X-Request-ID on the response;
  • preserves W3C traceparent and tracestate when present;
  • starts a lightweight request span;
  • attaches a request-aware slog.Logger to r.Context();
  • records request count and duration metrics.

Application code can read the request id and logger from context:

requestID := lazytelemetry.RequestID(r.Context())
logger := lazytelemetry.Logger(r.Context())
logger.InfoContext(r.Context(), "loaded post", "request_id", requestID)

Prefer lazytelemetry.WithLogAttrs, WithLogTags, and WithLogGroup when a service wants to carry structured context into downstream calls.

Logs

The default log backend is log/slog. Without a log exporter setting, GoLazy uses text logs on stdout. When a log exporter is configured, GoLazy uses JSON logs on stdout for this first implementation.

Logs created through lazytelemetry or lazylogs include request id, trace id, span id, method, path, and any attributes, tags, or groups already attached to the context. Logs emitted while a span is active are also recorded as span events so future exporters can include request-local log messages in traces.

Spans and runtime trace

lazytelemetry.StartSpan starts a lightweight in-process span and attaches it to context. It preserves incoming W3C trace ids, generates local span ids, and uses Go runtime/trace tasks and regions for local diagnostics. The first implementation does not import the OpenTelemetry SDK or send OTLP spans by itself.

Metrics

lazytelemetry/lazymetrics provides in-memory counter, gauge, and histogram vectors with Prometheus-like label APIs but no Prometheus dependency.

The request middleware records:

  • http_server_requests_total with method, route, and status_class;
  • http_server_request_duration_seconds with the same labels.

Keep metric labels low-cardinality. Do not use request id, raw query strings, user ids, or arbitrary route parameter values as labels.

Environment variables

GoLazy reads the following OpenTelemetry-style environment variables with the OTEL_ prefix. The configuration is loaded with lazyconfig.RemoveEnvNamePrefix("OTEL").

SDK and resources

  • OTEL_SDK_DISABLED
  • OTEL_ENTITIES
  • OTEL_RESOURCE_ATTRIBUTES
  • OTEL_SERVICE_NAME
  • OTEL_LOG_LEVEL
  • OTEL_PROPAGATORS
  • OTEL_TRACES_SAMPLER
  • OTEL_TRACES_SAMPLER_ARG

Exporter selection

  • OTEL_TRACES_EXPORTER
  • OTEL_METRICS_EXPORTER
  • OTEL_LOGS_EXPORTER

Known useful values include otlp, console, otlp/stdout, and none. zipkin is trace-only, and prometheus is metrics-only. GoLazy does not add a Prometheus dependency unless a dedicated adapter package is installed later.

OTLP exporter

  • OTEL_EXPORTER_OTLP_ENDPOINT
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
  • OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
  • OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
  • OTEL_EXPORTER_OTLP_INSECURE
  • OTEL_EXPORTER_OTLP_TRACES_INSECURE
  • OTEL_EXPORTER_OTLP_METRICS_INSECURE
  • OTEL_EXPORTER_OTLP_LOGS_INSECURE
  • OTEL_EXPORTER_OTLP_CERTIFICATE
  • OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE
  • OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE
  • OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE
  • OTEL_EXPORTER_OTLP_CLIENT_KEY
  • OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY
  • OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY
  • OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY
  • OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE
  • OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE
  • OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE
  • OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE
  • OTEL_EXPORTER_OTLP_HEADERS
  • OTEL_EXPORTER_OTLP_TRACES_HEADERS
  • OTEL_EXPORTER_OTLP_METRICS_HEADERS
  • OTEL_EXPORTER_OTLP_LOGS_HEADERS
  • OTEL_EXPORTER_OTLP_COMPRESSION
  • OTEL_EXPORTER_OTLP_TRACES_COMPRESSION
  • OTEL_EXPORTER_OTLP_METRICS_COMPRESSION
  • OTEL_EXPORTER_OTLP_LOGS_COMPRESSION
  • OTEL_EXPORTER_OTLP_TIMEOUT
  • OTEL_EXPORTER_OTLP_TRACES_TIMEOUT
  • OTEL_EXPORTER_OTLP_METRICS_TIMEOUT
  • OTEL_EXPORTER_OTLP_LOGS_TIMEOUT
  • OTEL_EXPORTER_OTLP_PROTOCOL
  • OTEL_EXPORTER_OTLP_TRACES_PROTOCOL
  • OTEL_EXPORTER_OTLP_METRICS_PROTOCOL
  • OTEL_EXPORTER_OTLP_LOGS_PROTOCOL

Batch processing

  • OTEL_BSP_SCHEDULE_DELAY
  • OTEL_BSP_EXPORT_TIMEOUT
  • OTEL_BSP_MAX_QUEUE_SIZE
  • OTEL_BSP_MAX_EXPORT_BATCH_SIZE
  • OTEL_BLRP_SCHEDULE_DELAY
  • OTEL_BLRP_EXPORT_TIMEOUT
  • OTEL_BLRP_MAX_QUEUE_SIZE
  • OTEL_BLRP_MAX_EXPORT_BATCH_SIZE

Limits

  • OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT
  • OTEL_ATTRIBUTE_COUNT_LIMIT
  • OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT
  • OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT
  • OTEL_SPAN_EVENT_COUNT_LIMIT
  • OTEL_SPAN_LINK_COUNT_LIMIT
  • OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT
  • OTEL_LINK_ATTRIBUTE_COUNT_LIMIT
  • OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT
  • OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT

Metrics

  • OTEL_METRICS_EXEMPLAR_FILTER
  • OTEL_METRIC_EXPORT_INTERVAL
  • OTEL_METRIC_EXPORT_TIMEOUT

Other exporters and config files

  • OTEL_EXPORTER_ZIPKIN_ENDPOINT
  • OTEL_EXPORTER_ZIPKIN_TIMEOUT
  • OTEL_EXPORTER_ZIPKIN_PROTOCOL
  • OTEL_EXPORTER_PROMETHEUS_HOST
  • OTEL_EXPORTER_PROMETHEUS_PORT
  • OTEL_CONFIG_FILE
  • OTEL_EXPERIMENTAL_CONFIG_FILE

Legacy names

GoLazy also reads these obsolete OTLP names for compatibility:

  • OTEL_EXPORTER_OTLP_SPAN_INSECURE
  • OTEL_EXPORTER_OTLP_METRIC_INSECURE

Development command direction

The current lazy command does not set telemetry variables automatically. The planned development integration is for lazy to set OTEL values that point the application back to the running lazy process, so the development panel can read request metrics from the control plane and receive logs and traces from the app.