Enabling OpenTelemetry
Set the--otel CLI flag or OTEL_ENABLED environment variable:
Configuring the exporter
Isthmus uses OTLP gRPC exporters for both traces and metrics. The OTel SDK reads standard environment variables to configure the exporter endpoint:| Env var | Default | Description |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | localhost:4317 | OTLP gRPC endpoint for traces and metrics |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | (falls back to above) | Override endpoint for traces only |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | (falls back to above) | Override endpoint for metrics only |
Example: local Jaeger
http://localhost:16686 to see traces.
Example: Grafana Tempo + Prometheus
Example: MCP client config
Traces
Isthmus emits two types of spans:Query spans
Every SQL query executed through thequery tool creates a span:
| Attribute | Type | Description |
|---|---|---|
db.system | string | Always "postgresql" |
db.operation.name | string | "query" |
db.statement | string | The SQL statement |
db.response.rows | int | Number of rows returned (on success) |
Tool call spans
Every MCP tool call (discover, describe_table, query) creates a span:
| Attribute | Type | Description |
|---|---|---|
mcp.tool | string | Tool name (e.g. "query", "describe_table") |
error | bool | true if the tool call failed |
query tool call shows the full lifecycle: MCP dispatch, SQL validation, query execution, and masking.
Metrics
Isthmus exposes four metrics:| Metric | Type | Unit | Description |
|---|---|---|---|
isthmus.query.count | Counter | — | Total number of SQL queries executed |
isthmus.query.duration | Histogram | ms | SQL query execution time |
isthmus.query.errors | Counter | — | Total number of failed queries (validation + execution) |
isthmus.tool.duration | Histogram | ms | MCP tool call duration (end-to-end) |
Useful queries
If your backend supports PromQL or a similar query language:Service resource
Isthmus registers itself with the following OTel resource attributes:| Attribute | Value |
|---|---|
service.name | isthmus |
service.version | Build version (e.g. v0.5.0) |
Graceful shutdown
When Isthmus receivesSIGTERM or SIGINT, it flushes all pending traces and metrics before exiting (with a 5-second timeout). This ensures no data is lost during graceful shutdown.
When OTel is disabled
When--otel is not set (the default), all tracing and metrics use no-op implementations. There is zero overhead — no goroutines, no allocations, no network calls. You can safely leave OTel disabled in development.
Semantic conventions
Isthmus follows the OpenTelemetry Semantic Conventions for database spans:db.system="postgresql"(database semconv)db.operation.namefor the operation typedb.statementfor the SQL querydb.response.rowsfor the result size