Observability¶
The docs-mcp-server includes production-grade observability with OpenTelemetry-aligned tracing, structured logging, and Prometheus metrics.
Endpoints¶
| Endpoint | Description |
|---|---|
/metrics |
Prometheus metrics in text format |
/health |
Health check endpoint |
Structured Logging¶
All logs are emitted as JSON with trace correlation:
{
"timestamp": "2026-01-12T22:29:07.429878+00:00",
"level": "INFO",
"message": "Search completed",
"logger": "docs_mcp_server.search",
"trace_id": "625f5e96e1e24618a58fb2e291f7574d",
"span_id": "46a0ed11012f4ec6",
"component": "search",
"tenant": "django"
}
Fields:
- trace_id: 32-char hex ID correlating all logs in a request
- span_id: 16-char hex ID for the current operation
- component: Module name (extracted from logger)
- tenant: Tenant codename when available
When OTLP export is enabled, logs are shipped via OTLP to any OpenTelemetry-compatible backend. SigNoz is the reference implementation used for validation. https://signoz.io/docs/instrumentation/python/
Metrics¶
Golden signal metrics exposed at /metrics:
| Metric | Type | Labels | Description |
|---|---|---|---|
mcp_request_latency_seconds |
Histogram | tenant, tool | Request latency |
mcp_requests_total |
Counter | tenant, tool, status | Total requests |
mcp_errors_total |
Counter | tenant, error_type, component | Total errors |
search_latency_seconds |
Histogram | tenant | Search query latency |
index_document_count |
Gauge | tenant | Documents in index |
When OTLP export is enabled, these metrics are exported via OTLP to any OpenTelemetry-compatible backend (no Prometheus scrape required). SigNoz is the reference implementation used for validation. https://signoz.io/docs/instrumentation/python/
Tracing¶
OpenTelemetry tracing is enabled by default. Trace boundaries:
- HTTP requests via
TraceContextMiddleware - MCP tool calls (
mcp.tool.*spans) - Search queries (
search.queryspans)
Trace context propagates via contextvars across async boundaries.
Trace export¶
OTLP export is opt-in. Configure infrastructure.observability_collector in deployment.json to send traces to an OpenTelemetry-compatible collector via OTLP gRPC (default http://localhost:4317) or OTLP HTTP (http://localhost:4318/v1/traces). Env-driven single-tenant mode does not expose collector settings, so you must use deployment.json to enable export. SigNoz is the reference deployment used for validation. https://signoz.io/docs/install/docker/
Use resource_attributes in the collector config to attach OpenTelemetry resource attributes (for example, service.version, deployment.environment). https://signoz.io/docs/instrumentation/python/
SigNoz helper (reference deployment)¶
The repo includes scripts/signoz-observability-restart for restarting/upgrading a local SigNoz deployment via Docker Compose. The script clones the SigNoz repo (shallow), updates to the requested version, and runs docker compose up -d --remove-orphans. https://signoz.io/docs/install/docker/ https://docs.docker.com/reference/cli/docker/compose/up/
SigNoz provisioning (reference deployment)¶
Use scripts/signoz-provision.py to replay dashboard and alert rule provisioning. This orchestrates scripts/signoz-dashboards-sync.py and scripts/signoz-alerts-sync.py and supports API key or session-token auth (see script help for env vars). https://signoz.io/docs/userguide/dashboards/ https://signoz.io/docs/userguide/alerts-management/
deploy_multi_tenant.py runs SigNoz provisioning when SIGNOZ_PROVISION=true and OTLP export is enabled. This is optional for other OpenTelemetry-compatible backends.
Configuration¶
Observability is initialized automatically in AppBuilder.build(). The log level follows infrastructure.log_level in deployment.json.
To disable JSON logging for local development, set environment variable: