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

120 lines (119 loc) 4.21 kB
/** * Custom Metrics Store * * Manages dynamic OTel ObservableGauge/Counter instances registered at runtime * by the agent via the grafana_push_metrics tool. Provides: * * - Validation: name regex, label consistency, cardinality limits * - Persistence: gauge values survive restarts (JSON file in stateDir) * - TTL eviction: optional auto-expiry for stale metrics * * All metric names are enforced to start with `openclaw_ext_` to prevent * collision with built-in `openclaw_lens_*` metrics. * * Data flow: * Agent pushes data → store updates value maps → OTel ObservableGauge callbacks * read values at export time → OTLP push → Collector → Mimir → Grafana */ import type { Meter, Counter as OtelCounter } from "@opentelemetry/api"; import type { OtlpJsonWriter } from "./otlp-json-writer.js"; export type MetricType = "gauge" | "counter"; export type CustomMetricDefinition = { name: string; type: MetricType; help: string; labelNames: string[]; createdAt: number; updatedAt: number; ttlMs?: number; }; export type CustomMetricDataPoint = { name: string; value: number; labels?: Record<string, string>; type?: MetricType; help?: string; ttlDays?: number; /** ISO 8601 timestamp for historical data (e.g., "2025-01-15"). Omit for real-time. */ timestamp?: string; }; export type CustomMetricsLimits = { maxMetrics?: number; maxLabelsPerMetric?: number; maxLabelValues?: number; }; export type PushResult = { accepted: number; rejected: Array<{ name: string; reason: string; }>; /** Mapping of normalized metric name → exact PromQL name (counters get _total suffix). */ queryNames: Record<string, string>; }; export declare function normalizeMetricName(name: string): { normalized: string; wasAutoPrepended: boolean; }; /** Get the exact PromQL name for a metric — counters get `_total` suffix per Prometheus convention. */ export declare function getPromQLName(name: string, type: MetricType): string; type Logger = { info(msg: string): void; warn(msg: string): void; error(msg: string): void; }; export declare class CustomMetricsStore { private meter; private forceFlushFn; private stateDir; private logger; private limits; private definitions; /** Gauge value store: metricName → serializedLabels → value */ private gaugeValues; /** OTel Counter instances for counter-type metrics */ private counters; private labelValueCounts; private flushInterval; /** Set of metric names that have had ObservableGauge registered */ private registeredGaugeNames; private otlpWriter; private pushCounter; constructor(meter: Meter, forceFlush: () => Promise<void>, stateDir: string, logger: Logger, limits?: CustomMetricsLimits, otlpWriter?: OtlpJsonWriter | null, pushCounter?: OtelCounter | null); load(): Promise<void>; flush(): Promise<void>; startPeriodicFlush(): void; stopPeriodicFlush(): Promise<void>; registerMetric(def: { name: string; type: MetricType; help: string; labelNames: string[]; ttlMs?: number; createdAt?: number; updatedAt?: number; }): CustomMetricDefinition; pushValues(points: CustomMetricDataPoint[]): PushResult; /** * Force an immediate OTLP export so pushed data is available right away. */ forceFlush(): Promise<void>; /** * Record push statistics for the `openclaw_lens_custom_metrics_pushed_total` counter. */ trackPush(accepted: number, rejected: number): void; /** * Validate and normalize a data point: value check, name normalization, * auto-registration, label validation, cardinality check. * Returns { normalized, labels, def } on success, throws on failure. */ private validateAndNormalize; private pushSingleValue; pushTimestampedValues(points: CustomMetricDataPoint[]): Promise<PushResult>; listMetrics(): CustomMetricDefinition[]; deleteMetric(name: string): boolean; private trackLabelValues; private checkCardinality; private evictExpired; } export {};