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
80 lines (79 loc) • 2.69 kB
TypeScript
/**
* Alert Webhook Handler Service
*
* Receives Grafana alert notifications via HTTP webhook, stores them in a
* bounded in-memory queue, and makes them available to the agent via the
* `grafana_check_alerts` tool.
*
* The flow:
* Grafana alert fires → POST to /grafana-lens/alerts → stored here
* → agent sees alerts in prompt context (before_prompt_build hook)
* → agent investigates with grafana_query + grafana_annotate
*
* Design: bounded queue (max 50, 24h TTL) keeps memory usage predictable.
* Grafana expects fast webhook responses, so we return 200 immediately
* and process asynchronously.
*/
import type { OpenClawPluginService } from "openclaw/plugin-sdk/core";
import type { ValidatedGrafanaLensConfig } from "../config.js";
export type GrafanaAlertNotification = {
receiver: string;
status: "firing" | "resolved";
orgId: number;
alerts: GrafanaAlertInstance[];
groupLabels: Record<string, string>;
commonLabels: Record<string, string>;
externalURL: string;
title: string;
state: string;
message: string;
};
export type GrafanaAlertInstance = {
status: "firing" | "resolved";
labels: Record<string, string>;
annotations: Record<string, string>;
startsAt: string;
endsAt: string;
generatorURL: string;
fingerprint: string;
values: Record<string, number>;
};
export type StoredAlert = {
id: string;
receivedAt: number;
acknowledged: boolean;
title: string;
status: "firing" | "resolved";
message: string;
alerts: GrafanaAlertInstance[];
commonLabels: Record<string, string>;
groupLabels: Record<string, string>;
externalURL: string;
};
export type AlertStore = {
getPendingAlerts(): StoredAlert[];
getAllAlerts(): StoredAlert[];
getAlert(id: string): StoredAlert | undefined;
acknowledgeAlert(id: string): boolean;
acknowledgeAll(): number;
addAlert(notification: GrafanaAlertNotification): StoredAlert;
size(): number;
/** Total received count (including evicted), partitioned by status. */
totalReceived(): {
firing: number;
resolved: number;
};
};
export declare function createAlertStore(): AlertStore;
export type AlertWebhookHttpResponse = {
writeHead(status: number, headers?: Record<string, string>): void;
end(data?: string): void;
};
export declare function createAlertWebhookService(config: ValidatedGrafanaLensConfig, registerHttpRoute: (params: {
path: string;
auth: "gateway" | "plugin";
handler: (req: unknown, res: AlertWebhookHttpResponse) => Promise<void> | void;
}) => void): {
service: OpenClawPluginService;
store: AlertStore;
};