Skip to main content

Overview

The Secure MCP Gateway uses OpenTelemetry as its primary observability framework, providing:
  • Structured Logging via OTLP log export to Loki
  • Distributed Tracing with context propagation to Jaeger
  • Metrics Collection with Prometheus export
  • Unified Telemetry through the OpenTelemetry Collector

OpenTelemetry Provider

The OpenTelemetryProvider implements full OpenTelemetry support: Location: src/secure_mcp_gateway/plugins/telemetry/opentelemetry_provider.py

Key Features

  • OTLP Export: gRPC and HTTP protocols supported
  • Resource Attributes: Service name, version, environment metadata
  • Batch Processing: Efficient batching of telemetry data
  • Connectivity Check: Automatic endpoint validation on startup
  • Graceful Degradation: Falls back to no-op if collector unavailable

Provider Implementation

Configuration

Basic Configuration

Add telemetry configuration to enkrypt_mcp_config.json:

Configuration Options

boolean
default:"true"
Enable OpenTelemetry telemetry. When false, uses no-op implementations.
string
default:"http://localhost:4317"
OTLP endpoint URL. Supports:
  • gRPC: http://localhost:4317 (default)
  • HTTP: http://localhost:4318
boolean
default:"true"
Use insecure connection (no TLS). Set to false for production with TLS.
string
default:"secure-mcp-gateway"
Service name in resource attributes. Used for filtering in Grafana/Jaeger.
string
default:"enkryptai"
Job name for Prometheus metrics and resource attributes.

Production Configuration

For production deployments with TLS:

OpenTelemetry Collector Setup

Using Docker Compose

The gateway includes a complete observability stack:
This starts:
  • OpenTelemetry Collector (ports 4317, 4318, 8889)
  • Jaeger (port 16686)
  • Loki (port 3100)
  • Prometheus (port 9090)
  • Grafana (port 3000)

Collector Configuration

Location: infra/otel_collector/otel-collector-config.yaml

Manual Installation

If not using Docker Compose:

Distributed Tracing

Trace Context Propagation

The gateway automatically propagates trace context across operations:

Trace Attributes

Common attributes used in gateway traces:

Viewing Traces in Jaeger

  1. Open Jaeger UI: http://localhost:16686
  2. Select service: secure-mcp-gateway
  3. Search by:
    • Operation name (e.g., tool_execution)
    • Tags (e.g., server_name=github_server)
    • Duration (e.g., slow traces > 1s)

Trace Examples

Tool Execution Trace:

OTLP Export

gRPC Export (Default)

Default configuration uses gRPC:
Location: src/secure_mcp_gateway/plugins/telemetry/opentelemetry_provider.py:349

HTTP Export

To use HTTP instead of gRPC, configure endpoint with port 4318:
The provider automatically selects the appropriate exporter based on the port.

Resource Attributes

Resource attributes identify the telemetry source:
These attributes appear in all logs, traces, and metrics. Location: src/secure_mcp_gateway/plugins/telemetry/opentelemetry_provider.py:321

Connectivity Check

Before enabling telemetry, the provider validates endpoint reachability:
Location: src/secure_mcp_gateway/plugins/telemetry/opentelemetry_provider.py:152 This ensures the gateway starts successfully even if the collector is unavailable.

Metrics Export

Metrics are exported via Prometheus exporter:
Location: src/secure_mcp_gateway/plugins/telemetry/opentelemetry_provider.py:358 The collector receives OTLP metrics and exports them to Prometheus on port 8889.

Integration with Services

Grafana Integration

Datasource Configuration: Location: infra/grafana/provisioning/datasources/datasources.yaml

Jaeger Integration

Jaeger receives traces via OTLP:
Location: infra/docker-compose.yml:37

Loki Integration

Loki receives logs via OTLP HTTP:
Location: infra/docker-compose.yml:50

Troubleshooting

Telemetry Not Exporting

Check collector is running:
Check gateway logs:
Verify configuration:

Connection Refused

Error: Telemetry enabled but endpoint localhost:4317 unreachable Solutions:
  1. Start the collector: docker-compose up -d otel-collector
  2. Check firewall rules
  3. Verify endpoint in config matches collector address

No Traces in Jaeger

  1. Check collector exports to Jaeger:
  2. Verify Jaeger OTLP is enabled:
  3. Check trace sampling (if configured)

Metrics Not in Prometheus

  1. Check Prometheus scrape targets:
  2. Verify collector Prometheus endpoint:
  3. Check Prometheus config:

Performance Tuning

Batch Processing

Adjust batch settings in collector config:

Export Interval

Adjust metric export interval:

Sampling

For high-volume deployments, configure trace sampling:

Advanced Topics

Custom Exporters

Add custom exporters to the collector:

TLS Configuration

For production with TLS:

Authentication

Add authentication to OTLP export:

Next Steps

Metrics

Explore available metrics and Grafana dashboards

Logging

Configure structured logging and log aggregation

Overview

Return to observability overview

Deployment

Deploy the full observability stack