HypLab

Telemetry

Configure OpenTelemetry tracing and structured logging for observability.

Telemetry

HypLab uses OpenTelemetry for distributed tracing and Pino for structured logging. All telemetry is opt-in -- it is disabled by default and can be enabled via environment variables.

Overview

ComponentTechnologyPurpose
Backend tracingOpenTelemetry + OTLPDistributed trace export
Backend loggingPinoStructured log output
Frontend tracingOpenTelemetry + OTLPBrowser-side trace export
Trace viewerJaegerView and search traces
Metrics (optional)Prometheus + GrafanaDashboards and alerting

Environment variables

Backend

VariableDefaultDescription
TELEMETRY_ENABLEDfalseEnable OpenTelemetry tracing
OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4318/v1/tracesOTLP HTTP endpoint
OTEL_SERVICE_NAMEapiService name in traces
OTEL_SERVICE_VERSION0.1.0Service version in traces
LOG_LEVELdebug (dev) / info (prod)Log level: error, warn, info, debug

Frontend

VariableDefaultDescription
NEXT_PUBLIC_TELEMETRY_ENABLEDfalseEnable frontend tracing
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT--OTLP HTTP endpoint (required if enabled)
NEXT_PUBLIC_OTEL_SERVICE_NAMEappService name in traces

Disabling telemetry

To completely disable telemetry (the default for open-source deployments):

Backend (api/.env):

TELEMETRY_ENABLED=false
LOG_LEVEL=info

Frontend (app/.env.local):

NEXT_PUBLIC_TELEMETRY_ENABLED=false

Enabling telemetry

Step 1: Enable in environment variables

# Backend
TELEMETRY_ENABLED=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318/v1/traces

# Frontend
NEXT_PUBLIC_TELEMETRY_ENABLED=true
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318

Step 2: View traces

The Docker setup includes the OpenTelemetry Collector and Jaeger automatically. Access Jaeger at:

http://localhost:16686

What is instrumented

Backend (when enabled):

  • All Express.js HTTP requests and responses
  • Outbound HTTP requests
  • Structured logging (Pino logs are always active, independent of tracing)

Frontend (when enabled):

  • All fetch API requests
  • All XMLHttpRequest requests

Observability stack (optional)

For metrics dashboards, enable the Prometheus + Grafana stack:

make observability
# or
docker compose -f docker/docker-compose.yml --profile observability up -d prometheus grafana

Access:

Note: The /metrics endpoint is not yet implemented in the backend. Prometheus is configured and ready for when it is.

Logging

Structured logging with Pino

Backend logging is always active (independent of telemetry). Pino produces:

  • Development: Pretty-printed, colorized log output.
  • Production: JSON format for log aggregation tools.

Log levels: error, warn, info, debug

Filtered requests: Health checks (/health) and CORS preflight (OPTIONS) requests are not logged to reduce noise.

Best practices

// Good: structured logging with context
logger.info({ userId, action: 'create_person' }, 'Person created')
logger.error({ error, personId }, 'Failed to create person')

// Avoid: unstructured strings
console.log('Person created') // Don't do this

Troubleshooting

Traces not appearing in Jaeger

  1. Check that otel-collector and jaeger containers are running: docker compose -f docker/docker-compose.yml ps
  2. Verify TELEMETRY_ENABLED=true is set.
  3. Check collector logs: docker compose -f docker/docker-compose.yml logs otel-collector

Frontend telemetry not working

  1. Verify NEXT_PUBLIC_TELEMETRY_ENABLED=true and NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT are set.
  2. Check browser console for OpenTelemetry initialization messages.
  3. Verify CORS is configured in the collector for your frontend origin.

Next: Docker Production -- deploy HypLab to production.

On this page