with one click
jaeger
// Use the local Jaeger instance to inspect OpenTelemetry traces emitted by the Gram server and worker during development. Activate when testing backend endpoints, debugging request flows, or validating instrumentation.
// Use the local Jaeger instance to inspect OpenTelemetry traces emitted by the Gram server and worker during development. Activate when testing backend endpoints, debugging request flows, or validating instrumentation.
Rules and best practices when working on the dashboard and elements React frontend codebases
Concepts, external interfaces, and conventions for Gram's audit logging subsystem — the internal Go API for recording actor/action/subject events and the `/rpc/auditlogs.*` management API that exposes them. Activate whenever the task involves recording or exposing audit events (adding or changing audit coverage on a service, introducing a new audited subject or action, writing tests that assert an event was recorded, changing how entries are displayed or filtered).
Rules and best practices when writing and editing Go (Golang) code
Concepts, external interfaces, and conventions for Gram's management API — the Goa-designed HTTP-RPC surface under `/rpc/<service>.<method>` that powers the dashboard, CLI, and public SDK. Activate whenever the task involves designing, implementing, or modifying a management endpoint (new service, new method, payload/result changes, OpenAPI/SDK surface changes, CLI changes, wiring a new service into the server).
Concepts, external interfaces, and conventions for Gram's role-based access control (RBAC) subsystem — scopes, grants, principals, system roles, and the `authz.Engine.Require` enforcement path used inside handlers. Activate whenever the task involves authorization (adding or modifying a scope or resource type, declaring a new role or grant, gating a handler, changing scope inheritance, exposing RBAC state through the dashboard).
Rules when working with PostgreSQL database in Gram
| name | jaeger |
| description | Use the local Jaeger instance to inspect OpenTelemetry traces emitted by the Gram server and worker during development. Activate when testing backend endpoints, debugging request flows, or validating instrumentation. |
Gram runs a local OpenTelemetry Collector that receives all OTLP signals from gram-server and gram-worker, routing traces to Jaeger and metrics to Prometheus. Everything starts automatically with mise run infra:start.
App → OTLP :$OTLP_GRPC_PORT → OTel Collector → traces → Jaeger
→ metrics → Prometheus (scrapes collector)
→ spanmetrics connector → Prometheus (RED metrics from traces)
$OTLP_GRPC_PORTJaeger ports are configured via environment variables in mise.toml. Always resolve ports from env vars — never hardcode them, as they may differ across worktrees or local overrides.
# Jaeger UI/API port
echo $JAEGER_WEB_PORT
# OTLP gRPC receiver port
echo $OTLP_GRPC_PORT
http://localhost:$JAEGER_WEB_PORTlocalhost:$OTLP_GRPC_PORThttp://localhost:$JAEGER_WEB_PORT/api/...Use these endpoints to programmatically query traces after running seed data or hitting endpoints. Replace $JAEGER_WEB_PORT with the resolved value.
GET http://localhost:$JAEGER_WEB_PORT/api/services
Returns all instrumented services (e.g., gram-server, gram-worker).
GET http://localhost:$JAEGER_WEB_PORT/api/traces?service=gram-server&limit=20
GET http://localhost:$JAEGER_WEB_PORT/api/traces?service=gram-server&operation=POST /v1/mcp/{mcpSlug}&limit=10
GET http://localhost:$JAEGER_WEB_PORT/api/traces?service=gram-server&tags={"http.status_code":"500"}&limit=10
Query parameters:
service (required) — service nameoperation — filter by operation/endpointtags — JSON object of tag key-value filtersstart / end — microsecond Unix timestampslimit — max traces returned (default 20)minDuration / maxDuration — e.g., 1ms, 500ms, 2slookback — e.g., 1h, 2h, 1dGET http://localhost:$JAEGER_WEB_PORT/api/traces/{traceID}
Returns all spans for a trace, including cross-service spans between gram-server and gram-worker.
GET http://localhost:$JAEGER_WEB_PORT/api/services/{service}/operations
Returns all known operation names (HTTP routes, gRPC methods, Temporal activities).
mise run infra:start (Jaeger starts automatically)mise start:server --dev-single-processerror=true tag), missing instrumentation, N+1 query patternsThe Gram server uses OpenTelemetry with these conventions:
otelhttp middleware, operation = HTTP <method> <route>tracer.Start(ctx, "operation-name") in service codeKey attributes on spans:
http.method, http.route, http.status_code — HTTP request detailsdb.statement — SQL query textservice.name — gram-server or gram-workererror — true if the span recorded an errorPrometheus is available at http://localhost:$PROMETHEUS_PORT. It stores:
spanmetrics connector# Prometheus UI
echo $PROMETHEUS_PORT
# Example PromQL queries
# Request rate by service: calls_total{service_name="gram-server"}
# Error rate: calls_total{status_code="STATUS_CODE_ERROR"}
# P99 latency: histogram_quantile(0.99, sum(rate(duration_milliseconds_bucket[5m])) by (le, service_name))
Configured in mise.toml:
| Variable | Default | Purpose |
|---|---|---|
OTLP_GRPC_HOST | localhost | OTLP receiver host (OTel Collector) |
OTLP_GRPC_PORT | 4317 | OTLP receiver port (OTel Collector) |
OTEL_EXPORTER_OTLP_ENDPOINT | http://localhost:4317 | Full endpoint (auto-constructed) |
JAEGER_WEB_PORT | 16686 | Jaeger UI/API port (traces) |
PROMETHEUS_PORT | 9099 | Prometheus UI/API port (metrics) |
GRAM_ENABLE_OTEL_TRACES | 1 | Enable/disable trace export |
GRAM_ENABLE_OTEL_METRICS | 1 | Enable/disable metrics export |