UNPKG

openclaw-grafana-lens

Version:

OpenClaw plugin that gives AI agents full Grafana access — 18 composable tools for PromQL/LogQL/TraceQL queries, dashboard creation, alerting, SRE investigation, security monitoring, data collection pipeline management via Grafana Alloy (29 recipes), and

88 lines (87 loc) 3.15 kB
/** * Health context for well-known OpenClaw metrics. * * When grafana_query returns a value for a known metric, this module * provides SRE-grade interpretive context: status, thresholds, and * a human-readable description. This lets the agent act as a virtual * SRE without memorizing operational thresholds. * * Thresholds are defined in the shared metric-definitions registry * (src/metric-definitions.ts) — single source of truth. */ import { HEALTH_RULES_MAP } from "../metric-definitions.js"; /** * Well-known OpenClaw gauge metrics with operational thresholds. * Derived from the shared metric-definitions registry. * Only gauge metrics make sense here — counter/histogram values are * cumulative and need rate() for meaningful health assessment. */ const HEALTH_RULES = HEALTH_RULES_MAP; /** * Evaluate a numeric value against a health rule. */ function evaluateHealth(value, rule) { if (rule.direction === "higher_is_worse") { if (value >= rule.critical) return "critical"; if (value >= rule.warning) return "warning"; return "healthy"; } // lower_is_worse if (value <= rule.critical) return "critical"; if (value <= rule.warning) return "warning"; return "healthy"; } /** * Extract a plain metric name from a PromQL expression. * Returns the name only for simple expressions (bare metric name, * optionally with label selectors). Complex expressions (rate, sum, * binary operators) return undefined — health context doesn't apply. */ export function extractMetricName(expr) { // Match: metric_name or metric_name{labels} const match = expr.match(/^([a-zA-Z_:][a-zA-Z0-9_:]*)(\s*\{.*\})?\s*$/); return match?.[1]; } /** * Resolve the health rule for a PromQL expression, if the metric is well-known. * Extracts the plain metric name and looks up the rule once. Use this to avoid * re-parsing the same expression in a loop (e.g., per instant query result). */ export function getHealthRule(expr) { const metricName = extractMetricName(expr); if (!metricName) return undefined; return HEALTH_RULES[metricName]; } /** * Evaluate a value against a resolved health rule. * Use with `getHealthRule()` for per-result evaluation without re-parsing expr. */ export function evaluateHealthContext(rule, value) { const numValue = parseFloat(value); if (!isFinite(numValue)) return undefined; return { status: evaluateHealth(numValue, rule), thresholds: { warning: rule.warning, critical: rule.critical }, description: rule.description, direction: rule.direction, }; } /** * Get health context for a metric value, if the metric is well-known. * Returns undefined for unknown metrics or complex PromQL expressions. * Convenience wrapper over getHealthRule() + evaluateHealthContext(). */ export function getHealthContext(expr, value) { const rule = getHealthRule(expr); if (!rule) return undefined; return evaluateHealthContext(rule, value); } /** Exported for testing. */ export const _HEALTH_RULES = HEALTH_RULES;