4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
"""Grafana Mimir/Loki/Ruler wire-format envelopes (shared with synthetic fixtures)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from datetime import UTC, datetime
|
|
from typing import Any
|
|
|
|
|
|
def _iso_to_unix(ts: str) -> float:
|
|
dt = datetime.fromisoformat(ts.replace("Z", "+00:00"))
|
|
return dt.replace(tzinfo=UTC).timestamp() if dt.tzinfo is None else dt.timestamp()
|
|
|
|
|
|
def _iso_to_unix_ns(ts: str) -> str:
|
|
return str(int(_iso_to_unix(ts) * 1_000_000_000))
|
|
|
|
|
|
def _metric_name(metric_name: str, stat: str) -> str:
|
|
snake = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", metric_name)
|
|
snake = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", snake)
|
|
return f"aws_rds_{snake.lower()}_{stat.lower()}"
|
|
|
|
|
|
def _dimension_labels(dimensions: list[dict[str, str]]) -> dict[str, str]:
|
|
return {d["Name"].lower(): d["Value"] for d in dimensions if "Name" in d and "Value" in d}
|
|
|
|
|
|
def format_mimir_query_range(cw_fixture: dict[str, Any]) -> dict[str, Any]:
|
|
result_series: list[dict[str, Any]] = []
|
|
|
|
for entry in cw_fixture.get("metric_data_results", []):
|
|
name = _metric_name(entry.get("metric_name", "unknown"), entry.get("stat", "average"))
|
|
labels: dict[str, str] = {"__name__": name}
|
|
labels.update(_dimension_labels(entry.get("dimensions", [])))
|
|
|
|
timestamps: list[str] = entry.get("timestamps", [])
|
|
values: list[float] = entry.get("values", [])
|
|
|
|
prom_values = [[_iso_to_unix(ts), str(v)] for ts, v in zip(timestamps, values)]
|
|
|
|
result_series.append({"metric": labels, "values": prom_values})
|
|
|
|
return {
|
|
"status": "success",
|
|
"data": {
|
|
"resultType": "matrix",
|
|
"result": result_series,
|
|
},
|
|
}
|
|
|
|
|
|
def format_loki_query_range(rds_events_fixture: dict[str, Any]) -> dict[str, Any]:
|
|
stream_map: dict[tuple[str, str], list[list[str]]] = {}
|
|
|
|
for event in rds_events_fixture.get("events", []):
|
|
key = (event.get("source_type", ""), event.get("source_identifier", ""))
|
|
ns_ts = _iso_to_unix_ns(event["date"])
|
|
line = event.get("message", "")
|
|
stream_map.setdefault(key, []).append([ns_ts, line])
|
|
|
|
loki_result: list[dict[str, Any]] = []
|
|
for (source_type, source_identifier), log_lines in stream_map.items():
|
|
log_lines.sort(key=lambda x: x[0])
|
|
loki_result.append(
|
|
{
|
|
"stream": {
|
|
"source_type": source_type,
|
|
"source_identifier": source_identifier,
|
|
},
|
|
"values": log_lines,
|
|
}
|
|
)
|
|
|
|
return {
|
|
"status": "success",
|
|
"data": {
|
|
"resultType": "streams",
|
|
"result": loki_result,
|
|
},
|
|
}
|
|
|
|
|
|
def format_ruler_rules(alert_fixture: dict[str, Any]) -> dict[str, Any]:
|
|
labels: dict[str, str] = dict(alert_fixture.get("commonLabels", {}))
|
|
annotations: dict[str, str] = dict(alert_fixture.get("commonAnnotations", {}))
|
|
|
|
alert_name = labels.get("alertname", alert_fixture.get("title", "UnknownAlert"))
|
|
group_name = labels.get("pipeline_name", "synthetic")
|
|
|
|
grafana_state = "firing" if alert_fixture.get("state", "") == "alerting" else "inactive"
|
|
|
|
rule: dict[str, Any] = {
|
|
"state": grafana_state,
|
|
"name": alert_name,
|
|
"labels": labels,
|
|
"annotations": annotations,
|
|
}
|
|
|
|
return {
|
|
"groups": [
|
|
{
|
|
"name": group_name,
|
|
"rules": [rule],
|
|
}
|
|
]
|
|
}
|