---
title: Externe Skripte für Alarme
url: https://doc2.pstreamer.tv/de/manual/extras/alert_scripts.html
lang: de
product: Perfect Streamer
version: 2.0.2.415
---

# Externe Skripte für Alarme

Der Kanal „Prozess“ der externen Alarmzustellung startet auf dem Knoten Ihr Programm oder Skript bei jedem Ereignis eines Alarms: beim Auslösen eines Vorfalls und bei seiner Behebung. So gelangen Alarme in jedes System, das sich aus einem Skript aufrufen lässt: SMS-Gateway, Messenger, Webhook, eigene Überwachung oder Ticketsystem. Diese Seite beschreibt, wie der Knoten den Befehl startet, was dieser erhält und wie das Ergebnis verarbeitet wird, und bietet zwei fertige Vorlagen: für `/bin/sh` und für Python 3.

Das allgemeine Modell der externen Zustellung und die beiden anderen Kanäle, Telegram und E-Mail, sind in [Externe Alarmzustellung](../meshwork/alerts.md#meshwork-alert-delivery) beschrieben, das Einstellungsfenster in [Alarmziele](../webui/administration.md#webui-alert-destinations).

## Kanal einrichten

Der Kanal wird auf dem Reiter „Prozess“ des Fensters „Alarmziele“ eingerichtet. Das Fenster öffnet die Schaltfläche „Alarmziele…“ in den Einstellungen der Alarmierung ([Alarmziele](../webui/administration.md#webui-alert-destinations)). Dieselben Werte stehen im Abschnitt `alerter` der Einstellungsdatei.

| Feld | Schlüssel | Zweck |
| --- | --- | --- |
| „Prozessziel aktivieren“ | `process-enable` | Schaltet den Kanal ein. Standardmäßig ausgeschaltet. |
| „Befehl“ | `process-command` | Befehlszeile: Programm und seine Argumente. Standardmäßig leer; ein eingeschalteter Kanal mit leerem Befehl startet nichts. |
| „Mindestschweregrad“ | `process-min-severity` | Untere Schwelle für den Schweregrad eines Ereignisses: `Info` (3), `Warning` (4, Standard), `Error` (5), `Critical` (6), `AdminAction` (7). |
| „Timeout, ms“ | `process-timeout-ms` | Wie viele Millisekunden ein einzelner Lauf dauern darf: von 100 bis 600000, standardmäßig 5000. |

Alle vier Werte werden bei jedem Ereignis neu gelesen, daher wirkt eine Änderung ab dem nächsten Alarm, ohne Neustart des Dienstes.

## Wie der Befehl gestartet wird

**Ohne Shell.** Die Zeile „Befehl“ wird nach den Regeln der Shell in Wörter zerlegt, eine Shell selbst wird aber nicht gestartet. Wörter werden durch Leerzeichen getrennt; Text in einfachen Anführungszeichen wird unverändert übernommen; in doppelten Anführungszeichen maskiert der Backslash nur `"` und `\`; außerhalb von Anführungszeichen maskiert der Backslash das folgende Zeichen; leere Anführungszeichen `''` ergeben ein leeres Argument. Das erste Wort ist das Programm, die übrigen sind seine Argumente. Pipes `|`, Umleitungen `>`, Variablenersetzung `$VAR`, `~` und Dateinamensmuster funktionieren nicht: Sie gehen als gewöhnlicher Text an das Programm. All das erledigen Sie im Skript.

**Programmsuche.** Enthält das erste Wort ein `/`, ist es ein Dateipfad: Die Datei muss existieren und ausführbar sein, sonst endet jedes Ereignis mit dem Fehler `process-command not executable`. Ein Name ohne `/` wird im `PATH` des Dienstes gesucht. Zuverlässiger ist es, immer den vollständigen Pfad anzugeben.

**Laufzeitumgebung.**

- Benutzer und Gruppe sind dieselben wie beim Dienst: `pss`.
- Das Arbeitsverzeichnis ist die Wurzel `/`; geben Sie Pfade im Skript vollständig an.
- Umgebungsvariablen werden vom Dienst geerbt (einschließlich seines `PATH`), hinzu kommen die Variablen `PSS_ALERT_*`.
- Geöffnete Dateien und Sockets des Dienstes werden nicht an das Skript weitergegeben: Es hat nur Standardeingabe, Standardausgabe und Standardfehlerausgabe.
- Die Standardausgabe des Skripts geht in das Systemjournal des Dienstes, also in die Ausgabe von `journalctl -u pss` ([Protokoll des Dienstes](../support/index.md#support-logs)). Die Standardfehlerausgabe liest der Knoten selbst, nach dem Ende des Skripts (Ergebnis, Timeout und Protokoll).

## Was das Skript erhält

Jedes Ereignis wird auf zwei Wegen zugleich übergeben: als einzelne Felder in Umgebungsvariablen und vollständig als JSON auf der Standardeingabe. Argumente vom Knoten gibt es keine, nur die in „Befehl“ eingetragenen.

**Umgebungsvariablen**

| Variable | Wert |
| --- | --- |
| `PSS_ALERT_ID` | Stabile Kennung des Vorfalls, gleich bei seinem Auslösen und seiner Behebung, zum Beispiel `2:12:3`. |
| `PSS_ALERT_STATE` | `raised` — der Vorfall ist aufgetreten, `cleared` — er wurde behoben. |
| `PSS_ALERT_SEVERITY` | Schweregrad als Zahl: 3–7 (siehe „Mindestschweregrad“ oben). |
| `PSS_ALERT_SEVERITY_STR` | Schweregrad als Wort: `Info`, `Warning`, `Error`, `Critical`, `AdminAction`. |
| `PSS_ALERT_CODE` | Code der Vorfallsart als Zahl ([Katalog der Alarmcodes](../meshwork/alerts.md#meshwork-alert-codes)). |
| `PSS_ALERT_CODE_STR` | Derselbe Code als Textbezeichnung, zum Beispiel `no-data`, `io-error`. |
| `PSS_ALERT_SRC_TYPE` | Quelltyp: `System`, `Stream`, `Cluster`, `EPG`, `Mosaic`, `DVB` oder `CS`. |
| `PSS_ALERT_SRC_ID` | Kennung der Quelle, zum Beispiel die Nummer des Streams. |
| `PSS_ALERT_NODE` | Name des Knotens, auf dem der Vorfall aufgetreten ist. Bei einem Alarm, der von einem Nachbarn in der Meshwork-Domäne stammt, ist es der Name dieses Nachbarn. |
| `PSS_ALERT_DISPLAY_NAME` | Lesbarer Name des Objekts, zum Beispiel der Name des Streams. |
| `PSS_ALERT_MESSAGE` | Text des Alarms. |
| `PSS_ALERT_TS` | Zeitpunkt dieses Ereignisses, Unix-Sekunden (UTC). |
| `PSS_ALERT_RAISED_TS` | Zeitpunkt, zu dem der Vorfall aufgetreten ist. |
| `PSS_ALERT_CLEARED_TS` | Zeitpunkt der Behebung; `0`, solange der Vorfall aktiv ist. |

Die Variablen sind in `/bin/sh` praktisch: Text mit Leerzeichen und Zeilenumbrüchen kommt darin unverfälscht an, und in der Prozessliste (`ps`) sind sie nicht sichtbar.

**JSON auf der Standardeingabe.** Eine Zeile ohne abschließenden Zeilenumbruch, danach wird die Eingabe geschlossen. Das JSON enthält dieselben Angaben, Schweregrad und Quelltyp jedoch nur als Zahlen (Quelltyp: 1 — `System`, 2 — `Stream`, 3 — `Cluster`, 4 — `EPG`, 5 — `Mosaic`, 6 — `DVB`, 7 — `CS`), und Textbezeichnungen für Code und Schweregrad fehlen. Felder:

- immer — `id`, `state`, `ts`, `raised_ts`, `cleared_ts`, `severity`, `src_type`, `src_id`, `node`, `display_name`, `code`, `message`;
- bei Vorfällen eines einzelnen Eingangs oder Ausgangs — `io_id` und `io_kind` (`input` oder `output`);
- bei Alarmen `AdminAction` — `admin_action_src`;
- bei einem „flackernden“ Vorfall — `flapping` (`true`) und `flap_cycles`, die Zahl seiner Zyklen (Wann das Skript gestartet wird).

Das Skript muss die Standardeingabe nicht lesen: Alles Nötige steht auch in den Variablen. Liest es die Eingabe doch, dann bis zum Ende und nicht nur eine Zeile.

Beispiel: Auf dem Knoten `edge-1` kommen beim Stream `Sport HD` (Nummer 12) seit 15 Sekunden keine Daten an. Auslösen:

```json
{"id":"2:12:3","state":"raised","ts":1761134400,"raised_ts":1761134400,
 "cleared_ts":0,"severity":4,"src_type":2,"src_id":12,"node":"edge-1",
 "display_name":"Sport HD","code":3,
 "message":"[Sport HD] no data 15s (no-data threshold 15s)"}
```

Behebung desselben Vorfalls zwei Minuten später:

```json
{"id":"2:12:3","state":"cleared","ts":1761134520,"raised_ts":1761134400,
 "cleared_ts":1761134520,"severity":4,"src_type":2,"src_id":12,"node":"edge-1",
 "display_name":"Sport HD","code":3,
 "message":"[Sport HD] no data 15s (no-data threshold 15s)"}
```

Zur besseren Lesbarkeit ist das JSON hier auf mehrere Zeilen umbrochen; der Knoten übergibt es als eine Zeile. Bei der Behebung bleiben Schweregrad und Text des Vorfalls erhalten. Einen Text wie „wiederhergestellt“ gibt es nicht, die Behebung erkennt man am Feld `state`. Die Umgebungsvariablen desselben Auslösens:

```sh
PSS_ALERT_ID=2:12:3
PSS_ALERT_STATE=raised
PSS_ALERT_SEVERITY=4
PSS_ALERT_SEVERITY_STR=Warning
PSS_ALERT_CODE=3
PSS_ALERT_CODE_STR=no-data
PSS_ALERT_SRC_TYPE=Stream
PSS_ALERT_SRC_ID=12
PSS_ALERT_NODE=edge-1
PSS_ALERT_DISPLAY_NAME=Sport HD
PSS_ALERT_MESSAGE=[Sport HD] no data 15s (no-data threshold 15s)
PSS_ALERT_TS=1761134400
PSS_ALERT_RAISED_TS=1761134400
PSS_ALERT_CLEARED_TS=0
```

## Wann das Skript gestartet wird

- **Auslösen und Behebung.** Das Skript wird einmal beim Auslösen eines Vorfalls und einmal bei seiner Behebung gestartet. Zwischenzeitliche Aktualisierungen eines aktiven Vorfalls (Wiederholung, neuer Text, geänderter Schweregrad) erhält das Skript nicht.
- **Schwelle des Schweregrads.** „Mindestschweregrad“ gilt für den Vorfall, nicht für jedes einzelne Ereignis. Ein Vorfall unterhalb der Schwelle wird nicht übergeben. Steigt sein Schweregrad später bis zur Schwelle, erhält das Skript einmal `raised`, im Moment dieser Erhöhung. `cleared` kommt genau dann, wenn `raised` übergeben wurde, unabhängig vom Schweregrad zum Zeitpunkt der Behebung. Als übergeben gilt ein Ereignis, sobald es dem Kanal übergeben wurde: Ist die Zustellung fehlgeschlagen, gilt der Vorfall trotzdem als offen, und seine Behebung wird übergeben.
- **Hauptschalter.** Ist die Alarmierung des Knotens ausgeschaltet ([Alarmierung](../webui/administration.md#webui-alerter)), wird das Skript überhaupt nicht gestartet, auch nicht für die Behebung eines bereits gemeldeten Vorfalls.
- **Alarme der Domäne.** Werden Alarme über die Meshwork-Domäne repliziert, erhält das Skript auch die Alarme der Nachbarn; der Quellknoten steht in `PSS_ALERT_NODE` ([Domänenweite Replikation von Benachrichtigungen](../meshwork/alerts.md#meshwork-alert-replication)). Ist der Kanal auf mehreren Knoten der Domäne eingeschaltet, meldet jeder von ihnen denselben Vorfall. Um doppelte Meldungen zu vermeiden, schalten Sie den Kanal nur auf einem Knoten ein.
- **Flackernde Vorfälle.** Wird ein Vorfall immer wieder ausgelöst und behoben (standardmäßig drei Zyklen in Folge mit Abständen von höchstens 600 Sekunden), behebt der Knoten ihn nicht mehr bei jedem Zyklus: Der Vorfall bleibt aktiv, und eine einzige Behebung folgt, wenn die Bedingung mindestens 600 Sekunden lang wiederhergestellt geblieben ist. Das Skript erhält ein Auslösen und eine Behebung statt eines Paares pro Zyklus. Die Werte werden mit den Schlüsseln `flap-suppress`, `flap-cycles`, `flap-window-sec` und `flap-settle-sec` im Abschnitt `alerter` der Einstellungsdatei festgelegt ([Die Einstellungsdatei pss.json](config_file.md#extras-config-file)).
- **Haftende Alarme,** die nur manuell behoben werden, melden die Behebung, wenn der Bediener den Alarm behebt ([Alarme anzeigen und beheben](../meshwork/alerts.md#meshwork-alerts-view)).
- **Neustart des Dienstes.** Die Liste aktiver Vorfälle wird im Speicher gehalten und geht beim Neustart des Dienstes ohne Behebungen verloren. Eine Bedingung, die noch besteht, löst erneut aus, und das Skript erhält ein zweites `raised` mit derselben `PSS_ALERT_ID`.

Werten Sie ein Ereignis deshalb am besten anhand von `PSS_ALERT_ID` und `PSS_ALERT_STATE` aus: Ein wiederholtes `raised` aktualisiert einen bekannten Vorfall und eröffnet keinen neuen.

## Warteschlange und Reihenfolge

- Das Skript wird strikt einzeln gestartet: Der nächste Lauf beginnt nach dem Ende des vorherigen, die Ereignisse werden in der Reihenfolge ihres Eintreffens abgearbeitet.
- Die Läufe steuert ein eigener Hintergrund-Thread des Kanals. Ein langsames Skript hält weder andere Kanäle noch den Betrieb des Knotens auf, wohl aber die folgenden Ereignisse desselben Kanals.
- Solange das Skript läuft, warten neue Ereignisse in der Warteschlange des Kanals, die 512 Ereignisse fasst. Ist die Warteschlange voll, werden die neuesten Ereignisse verworfen, und im Protokoll des Dienstes erscheint `delivery queue full, dropped alert(s)`.
- Beim Beenden und Neustart des Dienstes werden die Ereignisse in der Warteschlange verworfen; der Dienst wartet nur das Ende eines bereits laufenden Starts ab.

Rechnen Sie mit der Laufzeit: Bei einem Sturm von hundert Ereignissen liegt ein Skript, das zwei Sekunden läuft, um mehr als drei Minuten hinter den Ereignissen zurück. Verlagern Sie eine lange Zustellung in den Hintergrund (siehe den nächsten Abschnitt).

## Ergebnis, Timeout und Protokoll

- **Exit-Code 0** — das Ereignis ist zugestellt.
- **Exit-Code ungleich null** — Zustellfehler. Im Protokoll des Dienstes ([Protokoll des Dienstes](../support/index.md#support-logs)) erscheint eine Zeile der Form `[alert:process] deliver failed: process-command '/usr/local/bin/pss-alert.sh' exit 1: <Text aus stderr>` mit den letzten 4 KB der Fehlerausgabe.
- **Die Standardfehlerausgabe** liest der Knoten, während das Skript läuft, und zeigt sie nur zusammen mit einem Exit-Code ungleich null an. Ausgaben nach stderr bei Code 0 gelten nicht als Fehler und wirken sich auf nichts aus; umfangreiche Ausgaben nach stderr verlangsamen das Skript nicht und führen nicht zu einem Timeout.
- **Timeout.** Hat sich das Skript nicht innerhalb von „Timeout, ms“ beendet, beendet der Knoten es zwangsweise (`SIGKILL`) und schreibt `timed out after <N> ms`. Beendet wird nur das Skript selbst; von ihm gestartete Prozesse laufen weiter.
- **Keine Wiederholungen.** Ein fehlgeschlagenes Ereignis wird nicht erneut gesendet; der Kanal geht zum nächsten über.
- **Begrenzte Protokollhäufigkeit.** Der erste Fehler eines Kanals wird sofort protokolliert, die folgenden höchstens einmal pro Minute, mit der Zahl der Fehler in diesem Zeitraum am Zeilenende (`(x12)`).

> **Bemerkung**
>
> **Hintergrundprozesse.** Ein Prozess, den das Skript im Hintergrund zurücklässt, hält die nächsten Ereignisse des Kanals nicht auf, auch wenn er die Fehlerausgabe geerbt hat. In Versionen vor 2.0.2.415 hielt ein solcher Prozess den Kanal bis zu seinem Ende an. Starten Sie Hintergrundarbeit deshalb auf Knoten, auf denen frühere Versionen laufen können, und ohnehin der Sauberkeit halber mit geschlossener Ein- und Ausgabe:
>
> ```sh
> some-command </dev/null >/dev/null 2>&1 &
> ```
>
> oder mit Umleitung in eine eigene Protokolldatei:
>
> ```sh
> setsid some-command </dev/null >>/var/log/pss-alerts/bg.log 2>&1 &
> ```

## Sicherheit

- Das Skript läuft mit den Rechten des Dienstes, also des Benutzers `pss`. Machen Sie `root` zum Eigentümer der Skriptdatei und geben Sie dem Benutzer `pss` nur Lese- und Ausführungsrechte (Modus `750`, Gruppe `pss`): Dann kann der Dienst das Skript, das er selbst startet, nicht ändern.
- Übergeben Sie keine Geheimnisse in den Argumenten von „Befehl“. Argumente sind für alle Benutzer des Systems in der Prozessliste (`ps`) sichtbar, werden in der Einstellungsdatei gespeichert und sind in der Weboberfläche für die Rolle Admin sichtbar (den Rollen Restricted admin und Viewer wird die Befehlszeile verborgen angezeigt). Bewahren Sie Tokens und Passwörter im Skript selbst oder in einer separaten Datei auf, die nur der Benutzer `pss` lesen darf.
- Der Text eines Alarms (Stream-Name, Meldung) stammt aus den Einstellungen und von den Quellen. Setzen Sie ihn nicht ohne Anführungszeichen in Shell-Befehle ein und übergeben Sie ihn nicht an `eval`. Die Vorlagen unten übergeben Werte nur in Anführungszeichen.

## Vorlage für /bin/sh

Das Skript schreibt für jedes Ereignis eine Zeile ins Protokoll und endet mit Code 0. Die Stelle für die eigentliche Zustellung ist mit einem Kommentar markiert.

```sh
#!/bin/sh
# Empfänger für Alarme von Perfect Streamer (Kanal „Prozess“).
# Der Knoten startet das Skript bei jedem Auslösen und jeder Behebung eines Vorfalls.
# Die Ereignisfelder stehen in den Variablen PSS_ALERT_*, das ganze JSON auf der Standardeingabe.

LOG=/var/log/pss-alerts/alerts.log

# JSON von der Standardeingabe: eine Zeile ohne Zeilenumbruch am Ende,
# daher mit cat lesen, nicht mit read.
json=$(cat)

# Eine Zeile ins Protokoll. Schreibfehler - Exit-Code ungleich null: Der Knoten
# schreibt ihn zusammen mit dem Text aus stderr in sein Protokoll.
printf '%s %s %s %s [%s] %s: %s\n' \
    "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$PSS_ALERT_STATE" "$PSS_ALERT_SEVERITY_STR" \
    "$PSS_ALERT_NODE" "$PSS_ALERT_CODE_STR" "$PSS_ALERT_DISPLAY_NAME" \
    "$PSS_ALERT_MESSAGE" >> "$LOG" || exit 1

# Hier wird die eigentliche Zustellung angebunden, zum Beispiel ein Webhook.
# Ein synchroner Aufruf muss in „Timeout, ms“ passen (Standard 5 s):
#
# printf '%s' "$json" | curl -sS -m 3 -X POST \
#     -H 'Content-Type: application/json' --data-binary @- \
#     https://hooks.example.com/pss >/dev/null || exit 1
#
# Lange Zustellung nur im Hintergrund und nur mit geschlossener Ein- und Ausgabe,
# sonst bleibt der Kanal stehen (siehe „Ergebnis, Timeout und Protokoll“):
#
# ( printf '%s' "$json" | curl -sS -m 30 -X POST \
#     -H 'Content-Type: application/json' --data-binary @- \
#     https://hooks.example.com/pss ) </dev/null >/dev/null 2>&1 &

exit 0
```

## Vorlage für Python 3

Dasselbe in Python 3, nur mit der Standardbibliothek (Python 3.6 und neuer).

```python
#!/usr/bin/env python3
# Empfänger für Alarme von Perfect Streamer (Kanal „Prozess“).
# Der Knoten startet das Skript bei jedem Auslösen und jeder Behebung eines Vorfalls.
# Die Ereignisfelder stehen in den Variablen PSS_ALERT_*, das ganze JSON auf der Standardeingabe.

import json
import os
import sys
import time

LOG = "/var/log/pss-alerts/alerts.log"

def main():
    # Die ganze Standardeingabe: eine JSON-Zeile ohne Zeilenumbruch am Ende.
    raw = sys.stdin.read()
    alert = json.loads(raw) if raw else {}
    env = os.environ

    line = "{} {} {} {} [{}] {}: {}\n".format(
        time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        alert.get("state", env.get("PSS_ALERT_STATE", "")),
        env.get("PSS_ALERT_SEVERITY_STR", ""),
        alert.get("node", ""),
        env.get("PSS_ALERT_CODE_STR", ""),
        alert.get("display_name", ""),
        alert.get("message", ""),
    )
    # Ein Schreibfehler beendet das Skript mit einem Exit-Code ungleich null,
    # der Fehlertext geht nach stderr - der Knoten schreibt ihn in sein Protokoll.
    with open(LOG, "a", encoding="utf-8") as f:
        f.write(line)

    # Hier wird die eigentliche Zustellung angebunden, zum Beispiel ein Webhook.
    # Der Aufruf muss in „Timeout, ms“ passen (Standard 5 s):
    #
    # import urllib.request
    # req = urllib.request.Request(
    #     "https://hooks.example.com/pss",
    #     data=raw.encode("utf-8"),
    #     headers={"Content-Type": "application/json"},
    # )
    # urllib.request.urlopen(req, timeout=3).close()
    #
    # Hintergrundprozesse (subprocess.Popen) mit
    # stdin/stdout/stderr=subprocess.DEVNULL und start_new_session=True starten
    # (siehe „Ergebnis, Timeout und Protokoll“).

    return 0

if __name__ == "__main__":
    sys.exit(main())
```

## Installation und Prüfung

1. Legen Sie ein Protokollverzeichnis an, in das der Benutzer `pss` schreiben darf:

   ```sh
   sudo install -d -o pss -g pss -m 750 /var/log/pss-alerts
   ```
2. Speichern Sie die Vorlage, zum Beispiel als `/usr/local/bin/pss-alert.sh` (oder `pss-alert.py`), und setzen Sie Eigentümer und Rechte:

   ```sh
   sudo chown root:pss /usr/local/bin/pss-alert.sh
   sudo chmod 750 /usr/local/bin/pss-alert.sh
   ```
3. Testen Sie das Skript manuell als Benutzer `pss` mit einem Beispielereignis:

   ```sh
   echo '{"id":"2:12:3","state":"raised","severity":4,"node":"edge-1","display_name":"Sport HD","code":3,"message":"test"}' | \
     sudo -u pss env PSS_ALERT_ID=2:12:3 PSS_ALERT_STATE=raised \
       PSS_ALERT_SEVERITY=4 PSS_ALERT_SEVERITY_STR=Warning \
       PSS_ALERT_CODE=3 PSS_ALERT_CODE_STR=no-data \
       PSS_ALERT_NODE=edge-1 PSS_ALERT_DISPLAY_NAME='Sport HD' \
       PSS_ALERT_MESSAGE=test \
       /usr/local/bin/pss-alert.sh
   echo "exit=$?"
   tail -n 1 /var/log/pss-alerts/alerts.log
   ```

   Erwartet werden `exit=0` und eine neue Zeile im Protokoll. Messen Sie dabei auch die Zeit: Sie sollte deutlich unter „Timeout, ms“ liegen.
4. Tragen Sie auf dem Reiter „Prozess“ des Fensters „Alarmziele“ in „Befehl“ den vollständigen Pfad `/usr/local/bin/pss-alert.sh` ein, legen Sie „Mindestschweregrad“ fest, aktivieren Sie das Ziel und speichern Sie.
5. Prüfen Sie die Zustellung an einem Test-Stream: Unterbrechen Sie die Datenzufuhr an seinem Eingang (zum Beispiel, indem Sie den Sender anhalten). Nach dem Timeout für fehlende Daten (standardmäßig 15 Sekunden, [Alerter-Einstellungen](../meshwork/alerts.md#meshwork-alerts-settings)) wird ein Alarm `no-data` mit dem Schweregrad `Warning` ausgelöst und nach der Wiederaufnahme der Daten behoben. Im Protokoll des Skripts müssen die Zeilen `raised` und danach `cleared` erscheinen.

## Typische Probleme

- **Das Skript startet überhaupt nicht.** Prüfen Sie den Hauptschalter der Alarmierung und „Prozessziel aktivieren“, ob „Befehl“ nicht leer ist und ob der Schweregrad des Ereignisses die Schwelle erreicht. Standardmäßig liegt die Schwelle bei `Warning`: Ereignisse `Info` werden nicht nach außen gesendet.
- **Im Protokoll des Dienstes steht** `process-command not executable`. Die Datei unter dem angegebenen Pfad existiert nicht, oder der Benutzer `pss` darf sie nicht ausführen. Prüfen Sie `ls -l` und die Rechte aller Verzeichnisse im Pfad.
- **Im Protokoll des Dienstes steht** `posix_spawnp failed`. Das Programm ließ sich nicht starten: Meist ist der Name ohne Pfad angegeben und wurde im `PATH` des Dienstes nicht gefunden, oder die erste Zeile des Skripts (`#!`) ist falsch. Geben Sie den vollständigen Pfad an.
- **Im Protokoll des Dienstes steht** `exit <N>`. Das Skript wurde mit einem Fehler beendet, dessen Text aus stderr in derselben Zeile steht. Eine häufige Ursache ist ein fehlendes Schreibrecht für das Protokollverzeichnis oder für Arbeitsdateien: Das Skript läuft als `pss`, nicht als `root`, und im Verzeichnis `/`.
- **Im Protokoll des Dienstes steht** `timed out after <N> ms`. Das Skript hat den Timeout überschritten: Beschleunigen Sie die Zustellung (Timeout des Netzwerkaufrufs kleiner als „Timeout, ms“), erhöhen Sie „Timeout, ms“ oder verlagern Sie den langen Teil mit geschlossener Ausgabe in den Hintergrund.
- **Alarme kommen stark verzögert an oder gehen verloren; im Protokoll steht** `delivery queue full`. Das Skript ist für das Ereignisaufkommen zu langsam: Die Warteschlange des Kanals ist übergelaufen. Beschleunigen Sie das Skript oder erhöhen Sie „Mindestschweregrad“.
- **Der Kanal ist verstummt, ohne einen einzigen Fehler im Protokoll** (Versionen vor 2.0.2.415). Höchstwahrscheinlich hat das Skript einen Hintergrundprozess mit geerbter Fehlerausgabe hinterlassen, und der Knoten wartet auf dessen Ende. Suchen Sie den Prozess (`ps -u pss -f`), beenden Sie ihn und korrigieren Sie den Start im Hintergrund: mit `</dev/null >/dev/null 2>&1` oder mit Umleitung in eine Datei. Ab Version 2.0.2.415 hält ein solcher Prozess den Kanal nicht an.
- **Das Skript funktioniert manuell, aber nicht vom Knoten aus.** Die Ursache liegt in der Umgebung: ein anderer Benutzer (`pss`), das Arbeitsverzeichnis `/`, ein anderer `PATH`, die Variablen Ihrer Anmeldesitzung fehlen. Prüfen Sie das mit dem Befehl aus Schritt 3 im Abschnitt Installation und Prüfung, also über `sudo -u pss`.
- **Es kam ein zweites** `raised` **mit derselben** `PSS_ALERT_ID`. Der Dienst wurde neu gestartet, und der aktive Vorfall wurde erneut erkannt (siehe Wann das Skript gestartet wird).
- **Es kam kein** `cleared`. Die Alarmierung des Knotens wurde ausgeschaltet, während der Vorfall aktiv war, oder der Dienst wurde vor der Behebung neu gestartet (siehe Wann das Skript gestartet wird).
- **Derselbe Alarm kommt von mehreren Knoten.** Der Kanal ist auf mehreren Knoten der Domäne eingeschaltet, die Alarme replizieren. Lassen Sie ihn nur auf einem eingeschaltet.
- **Die Ausgabe des Skripts ist nicht zu sehen.** Die Standardausgabe geht in `journalctl -u pss`, die Fehlerausgabe gelangt nur bei einem Exit-Code ungleich null ins Protokoll des Dienstes. Schreiben Sie Diagnosen in eine eigene Protokolldatei.
