Beiträge Tageszeitabhängiger Alarm mit Grafana
Post
Cancel

Tageszeitabhängiger Alarm mit Grafana

Grafana

Grafana ist ein tolles Werkzeug, um den Überblick über Ereignisse in den Systemen zu behalten. Das können technische Aspekte wie CPU Auslastung, Speicherverbrauch oder Anzahl der Dockercontainer auf einem Host sein. Aber auch fachliche wie Verkaufsabschlüsse im Onlineshop oder BesucherInnen im Laden. Solange man die Daten in einer der vielen unterstützten Datenbanken und -quellen ablegen kann, kann man sie auch auswerten.

Besonders praktisch sind die Alarmierungsmöglichkeiten. Ich möchte ja nicht den ganzen Tag auf einen Monitor starren und mich durch alle Dashboards und Grafiken klicken, bis ich etwas auffälliges finde. Daher kann man in Grafana einen Alert auf einem Panel einrichten, der anschlägt, wenn bestimmte Werte unter- oder überschritten werden.

Alarm nur zu bestimmten Tageszeiten

Leider unterstützt Grafana zum aktuellen Zeitpunkt noch keine Alarmierung zu bestimmten Tageszeiten. Wenn ich also testen möchte, ob ein Heartbeat während den Geschäftszeiten ausgeblieben ist, gilt das für alle Tageszeiten. Wenn ich nachts die Rechner im Geschäft herunterfahre, bleiben die Heartbeats aus und der Alarm geht los. Das ist nicht nur unpraktisch, sondern die Falschmeldungen sorgen dafür, dass echte Meldungen untergehen und ignoriert werden.

Workaround mit SQL

Mit einem kleinen Trick kann man dieses Einschränkung aber umgehen. Mit einer SQL Datenbank (hier MS SQL) kann eine Zeitreihe mit der aktuellen Uhrzeit generiert werden. Der Speicherverbrauch ist minimal, da keine Daten abgelegt werden, sondern die Zeitreihe rekursiv zur Laufzeit erzeugt wird. Falls man zu viele Abfragen gleichzeitig oder zu große Zeiträume hat und die Aufrufe auf die Datenbank zu lange dauern, kann man das Ergebnis auch in einer Tabelle persistieren und dann direkt darauf zugreifen.

Die Datenbank muss in Grafana als neue Datenquelle eingerichtet werden.

Nun muss man einen Graphen mit einer Mixed Query anlegen. Für die erste Query wähle ich Microsoft SQL Server aus und füge den folgenden SQL Code ein.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
WITH d AS (
SELECT dateadd(hour, datediff(hour, 0, cast($__timeFrom() AS datetime)),0) AT TIME ZONE 'Central European Standard Time' AS dte
UNION ALL
SELECT dateadd(MINUTE, 15, dte)
FROM d
WHERE dateadd(MINUTE, 15, dte) < dateadd(hour, 1, $__timeTo())
)
SELECT
dte AS time,
DATEPART(HOUR, dte) AS hour
FROM d
WHERE $__timeFilter(dte)
ORDER BY 1
OPTION (maxrecursion 0);

Der rekursive Aufruf von d erzeugt für den in Grafana ausgewählten Zeitraum ($__timeFrom() bis $__timeTo() + 1 Stunde) alle 15 Minuten einen Datensatz aus Zeitstempel und Stunde. Der zeitliche Abstand sollte kleiner sein, als das minimale Zeitintervall Min interval der Query, damit in jedem Bucket mindestens ein Eintrag der Reihe liegt. Bei Format as wähle ich Time series.

Danach füge ich die eigentliche Query ein, für die ich einen Alarm einrichten möchte.

Beim Alarm selbst muss ich nun nur eine logische UND-Verknüpfung zwischen der Abfrage der Uhrzeit und der eigentlichen Abfrage herstellen. Beispiel Alarm mit Tageszeit Generell muss man mit den logischen Verknüpfungen von Regeln bei Grafana etwas aufpassen. Da es keine Klammerung gibt, werden die Bedingungen immer seriell ausgewertet. A OR B AND C wird nicht wie in der Prädikatenlogik als A OR (B AND C) sondern als (A OR B) AND C behandelt.

Bis bald,

seism0saurus

Dieser Blogbeitrag wurde vom Autor unter der CC BY 4.0 lizenziert.