fix(observability): code-review remediation pass
- Trino scrape path: /v1/status (JSON) → /metrics (OpenMetrics)
- Tempo→Loki correlation: add tags mapping service.name → container
so span clicks build {container=...} | traceID=... instead of an
unindexed scan
- Promtail api/mail-poller/cloudflared regexes: add \b word boundaries
so high-frequency words (error/origin/poll) don't set the labels
on every other line
- data-lake S3 ops panel: drop `| json` (RustFS isn't JSON), use the
s3_op stream label directly
- Add Quarkus-pair test covering the nessie|polaris combined stage
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,6 @@
|
|||||||
{"id": 2, "title": "Trino query duration p95", "type": "timeseries", "gridPos": {"x": 12, "y": 0, "w": 12, "h": 8}, "datasource": {"uid": "prometheus"}, "targets": [{"expr": "histogram_quantile(0.95, sum by (le) (rate(trino_query_execution_seconds_bucket[5m])))"}]},
|
{"id": 2, "title": "Trino query duration p95", "type": "timeseries", "gridPos": {"x": 12, "y": 0, "w": 12, "h": 8}, "datasource": {"uid": "prometheus"}, "targets": [{"expr": "histogram_quantile(0.95, sum by (le) (rate(trino_query_execution_seconds_bucket[5m])))"}]},
|
||||||
{"id": 3, "title": "Nessie/Polaris HTTP rate", "type": "timeseries", "gridPos": {"x": 0, "y": 8, "w": 12, "h": 8}, "datasource": {"uid": "prometheus"}, "targets": [{"expr": "sum by (job) (rate(http_server_requests_seconds_count{job=~\"nessie|polaris\"}[1m]))"}]},
|
{"id": 3, "title": "Nessie/Polaris HTTP rate", "type": "timeseries", "gridPos": {"x": 0, "y": 8, "w": 12, "h": 8}, "datasource": {"uid": "prometheus"}, "targets": [{"expr": "sum by (job) (rate(http_server_requests_seconds_count{job=~\"nessie|polaris\"}[1m]))"}]},
|
||||||
{"id": 4, "title": "Nessie/Polaris error rate", "type": "timeseries", "gridPos": {"x": 12, "y": 8, "w": 12, "h": 8}, "datasource": {"uid": "prometheus"}, "targets": [{"expr": "sum by (job) (rate(http_server_requests_seconds_count{job=~\"nessie|polaris\",status=~\"5..\"}[1m]))"}]},
|
{"id": 4, "title": "Nessie/Polaris error rate", "type": "timeseries", "gridPos": {"x": 12, "y": 8, "w": 12, "h": 8}, "datasource": {"uid": "prometheus"}, "targets": [{"expr": "sum by (job) (rate(http_server_requests_seconds_count{job=~\"nessie|polaris\",status=~\"5..\"}[1m]))"}]},
|
||||||
{"id": 5, "title": "RustFS S3 ops by op", "type": "timeseries", "gridPos": {"x": 0, "y": 16, "w": 24, "h": 8}, "datasource": {"uid": "loki"}, "targets": [{"expr": "sum by (s3_op) (rate({container=\"rustfs\"} | json [1m]))"}]}
|
{"id": 5, "title": "RustFS S3 ops by op", "type": "timeseries", "gridPos": {"x": 0, "y": 16, "w": 24, "h": 8}, "datasource": {"uid": "loki"}, "targets": [{"expr": "sum by (s3_op) (rate({container=\"rustfs\", s3_op!~\"\"}[1m]))"}]}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,5 +26,11 @@ datasources:
|
|||||||
tracesToLogsV2:
|
tracesToLogsV2:
|
||||||
datasourceUid: loki
|
datasourceUid: loki
|
||||||
filterByTraceID: true
|
filterByTraceID: true
|
||||||
|
# Map span resource attributes to Loki stream labels so a
|
||||||
|
# span click yields {container="<service>"} | traceID="<id>"
|
||||||
|
# instead of an unindexed scan.
|
||||||
|
tags:
|
||||||
|
- key: service.name
|
||||||
|
value: container
|
||||||
serviceMap:
|
serviceMap:
|
||||||
datasourceUid: prometheus
|
datasourceUid: prometheus
|
||||||
|
|||||||
@@ -120,11 +120,13 @@ scrape_configs:
|
|||||||
s3_bucket:
|
s3_bucket:
|
||||||
|
|
||||||
# --- API (FastAPI/stack) ---
|
# --- API (FastAPI/stack) ---
|
||||||
|
# Word-boundary anchors keep the label off lines that merely contain
|
||||||
|
# the substrings (e.g. "polling" should not set api_event=poll).
|
||||||
- match:
|
- match:
|
||||||
selector: '{container="api"}'
|
selector: '{container="api"}'
|
||||||
stages:
|
stages:
|
||||||
- regex:
|
- regex:
|
||||||
expression: '(?P<api_event>pipeline|ingest|health|error)'
|
expression: '\b(?P<api_event>pipeline|ingest|health|error)\b'
|
||||||
- regex:
|
- regex:
|
||||||
expression: 'pipeline=(?P<pipeline_name>[A-Za-z0-9_.-]+)'
|
expression: 'pipeline=(?P<pipeline_name>[A-Za-z0-9_.-]+)'
|
||||||
- labels:
|
- labels:
|
||||||
@@ -136,7 +138,7 @@ scrape_configs:
|
|||||||
selector: '{container="mail-poller"}'
|
selector: '{container="mail-poller"}'
|
||||||
stages:
|
stages:
|
||||||
- regex:
|
- regex:
|
||||||
expression: '(?P<mail_event>ingest|poll|error)'
|
expression: '\b(?P<mail_event>ingest|poll|error)\b'
|
||||||
- regex:
|
- regex:
|
||||||
expression: 'count=(?P<mail_count>\d+)'
|
expression: 'count=(?P<mail_count>\d+)'
|
||||||
- labels:
|
- labels:
|
||||||
@@ -160,7 +162,7 @@ scrape_configs:
|
|||||||
selector: '{container="cloudflared"}'
|
selector: '{container="cloudflared"}'
|
||||||
stages:
|
stages:
|
||||||
- regex:
|
- regex:
|
||||||
expression: '(?P<cf_event>connection|registered|unregistered|reconnect|quic|error|tunnel|origin)'
|
expression: '\b(?P<cf_event>connection|registered|unregistered|reconnect|quic|error|tunnel|origin)\b'
|
||||||
- regex:
|
- regex:
|
||||||
expression: 'status=(?P<cf_origin_status>\d{3})'
|
expression: 'status=(?P<cf_origin_status>\d{3})'
|
||||||
- labels:
|
- labels:
|
||||||
|
|||||||
@@ -41,11 +41,11 @@
|
|||||||
job: polaris
|
job: polaris
|
||||||
__metrics_path__: /q/metrics
|
__metrics_path__: /q/metrics
|
||||||
|
|
||||||
# Trino
|
# Trino — /metrics is the OpenMetrics endpoint (435+); /v1/status is JSON
|
||||||
- targets: ['trino:8080']
|
- targets: ['trino:8080']
|
||||||
labels:
|
labels:
|
||||||
job: trino
|
job: trino
|
||||||
__metrics_path__: /v1/status
|
__metrics_path__: /metrics
|
||||||
|
|
||||||
# OTel Collector
|
# OTel Collector
|
||||||
- targets: ['otel-collector:8889']
|
- targets: ['otel-collector:8889']
|
||||||
|
|||||||
@@ -129,6 +129,13 @@ class TestPerServiceStages:
|
|||||||
assert f'container="{container}"' in text, f"no match stage for {container}"
|
assert f'container="{container}"' in text, f"no match stage for {container}"
|
||||||
assert label in text, f"no {label} extraction for {container}"
|
assert label in text, f"no {label} extraction for {container}"
|
||||||
|
|
||||||
|
def test_quarkus_pair_has_combined_stage(self):
|
||||||
|
# nessie + polaris share one stage via regex selector.
|
||||||
|
cfg = yaml.safe_load((ROOT / "infra/loki/promtail-config.yml").read_text())
|
||||||
|
text = yaml.safe_dump(cfg["scrape_configs"][0]["pipeline_stages"])
|
||||||
|
assert 'container=~"nessie|polaris"' in text
|
||||||
|
assert "quarkus_route" in text
|
||||||
|
|
||||||
|
|
||||||
class TestOtelTempo:
|
class TestOtelTempo:
|
||||||
def test_otel_exports_traces_to_tempo(self):
|
def test_otel_exports_traces_to_tempo(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user