# Declarative datasource provisioning. # The `uid` values are STABLE and are what dashboard JSON files reference: # "datasource": { "type": "prometheus", "uid": "prometheus" } apiVersion: 1 deleteDatasources: - name: Prometheus orgId: 1 - name: Loki orgId: 1 - name: Tempo orgId: 1 datasources: - name: Prometheus uid: prometheus type: prometheus access: proxy orgId: 1 url: http://prometheus:9090 isDefault: true editable: false jsonData: httpMethod: POST timeInterval: 30s manageAlerts: false exemplarTraceIdDestinations: - name: trace_id datasourceUid: tempo - name: Loki uid: loki type: loki access: proxy orgId: 1 url: http://loki:3100 editable: false jsonData: timeout: 60 maxLines: 1000 # Logs -> traces: a trace_id in the log line opens Tempo. derivedFields: - name: TraceID matcherType: regex matcherRegex: '"?trace[_-]?id"?[:=]"?([a-f0-9]{16,32})' url: '$${__value.raw}' datasourceUid: tempo urlDisplayLabel: View trace - name: Tempo uid: tempo type: tempo access: proxy orgId: 1 url: http://tempo:3200 editable: false jsonData: httpMethod: GET streamingEnabled: search: true metrics: true # Service graph fed by the metrics_generator -> Prometheus. serviceMap: datasourceUid: prometheus nodeGraph: enabled: true # Span -> logs by trace id rather than by service name. # # The service-name mapping this replaces resolved `service.name` to Loki's # `app` label, which Alloy derives from app.kubernetes.io/name. That label # exists for keycloak and classic-models-api but not for the six Kong # gateways or librechat — and the gateways are precisely where the trace # id does appear in the logs. The mapping pointed at the services where it # could not work. # # A custom query on ${__trace.traceId} sidesteps the label entirely: every # source that writes the id anywhere in the line is matched. The stream # selector is spelled out rather than `.+` so the query stays bounded. tracesToLogsV2: datasourceUid: loki spanStartTimeShift: -1h spanEndTimeShift: 1h filterByTraceID: false filterBySpanID: false customQuery: true query: '{job=~"kong-audit|keycloak/keycloak|classic-models/classic-models-api|librechat/librechat"} |= "$${__trace.traceId}"' # Span -> metrics against the span metrics Tempo's own metrics_generator # feeds into Prometheus. Without explicit queries this block renders a # bare datasource link and nothing else, which is what it did before. # $$__tags expands to the tag mapping below, so each query is scoped to # the span's own service. tracesToMetrics: datasourceUid: prometheus spanStartTimeShift: -30m spanEndTimeShift: 30m tags: - key: service.name value: service queries: - name: 'Request rate' query: 'sum by (span_name) (rate(traces_spanmetrics_calls_total{$$__tags}[$$__rate_interval]))' - name: 'Error rate' query: 'sum by (span_name) (rate(traces_spanmetrics_calls_total{$$__tags,status_code="STATUS_CODE_ERROR"}[$$__rate_interval]))' - name: 'Latency p95' query: 'histogram_quantile(0.95, sum by (span_name, le) (rate(traces_spanmetrics_latency_bucket{$$__tags}[$$__rate_interval])))'