Use the Script notification channel to let Nightingale execute a local Shell/Python/any executable script and pipe the full alert event JSON via standard input.

Overview

The Script notification channel lets the n9e process execute a local script on the same host (Shell / Python / any executable). The alert events, message-template render result, custom parameters and contact list are packaged as a JSON string and piped to the script via standard input (stdin) in one go. The script can do whatever it likes next — write a file, call third-party APIs, push to an in-house IM, update tickets, … even more flexible than HTTP Callback.

  • Use cases:
    • Internal endpoints are too complex to express as an HTTP body;
    • You want to run local logic before notifying (CMDB lookup, time-of-day routing, dedup);
    • You want to print intermediate results for debugging.
  • Prerequisites: an executable script on the n9e host (either pasted into the form, or placed at a known path).
  • The whole setup has two steps: ① Create a Script channel in Nightingale, providing the script content or path → ② Pick the channel in a notification rule.

⚠️ Security: the Script channel runs whatever you provide as the n9e process user — effectively a remote-command-execution surface. Only grant this capability to trusted admins; don’t directly interpolate untrusted event fields into the script body, to avoid command injection.

How the script runs

Whether you choose “use script content” or “use a path”, n9e runs the same flow on each notification:

  1. Pack the current batch’s events, template-render result, params, and contact list into a JSON object.
  2. Spawn the configured script process and write the JSON to stdin in one go.
  3. Wait for the process to exit; if it doesn’t exit before the timeout, kill it.
  4. Collect combined stdout + stderr (at most 512 bytes, truncated beyond) and store it as the notification record’s details for post-mortem.

The JSON written to stdin (matches $events from Callback):

{
  "event": { /* shortcut to events[0], handy for single-event scenarios */ },
  "events": [ /* all events in the current batch, same structure as callback */ ],
  "tpl": {
    "title": "...",
    "content": "..."
  },
  "params": {
    "your_custom_key": "your_custom_value"
  },
  "sendtos": ["13800000000", "alice@example.com"]
}
  • event / events: the full alert event objects (schema: models.AlertCurEvent).
  • tpl: the result of rendering the rule’s “Message template” — typically tpl.title / tpl.content.
  • params: custom parameters set in the rule.
  • sendtos: recipients injected when the channel is bound to a “contact method”.

Step 1: Create a Script notification channel

  1. Sign in to Nightingale → left menu Notify → Notification Channels.

  2. Click Script in the channel-type panel on the left to enter the create page (URL /notification-channels/add?ident=script).

    Channel entry

  3. The form has two sections: Basic + Script.

    Script channel form

    Section Field Change? Notes
    Basic Name Yes e.g. Custom Script Notification — what you see when picking the channel in a rule.
    Basic Enable Keep on When off, this channel will not send.
    Variables Contact method Optional When set, the user’s phone/email/DingTalk-id is injected into stdin as sendtos[].
    Variables Parameter config Optional Custom parameters (webhook_url, env, …) flow through to stdin’s params.
    Script Timeout Usually keep default Milliseconds, default 5000ms (5 s). The process is killed on timeout.
    Script Script type Pick one “Use script content” (paste inline) or “Use path” (point to an existing file).
  4. With Use script content selected, a code editor appears below — paste your script:

    Script editor

    On save, n9e writes the script to .notify_script_<channelID> (e.g. .notify_script_25) under its current working directory and chmod 0777. Each run compares the content and rewrites only when changed.

    The first line must include a shebang (#!/bin/bash, #!/usr/bin/env python3, #!/usr/bin/env -S node, …), otherwise the system can’t pick an interpreter.

  5. With Use path selected, fill an absolute path, e.g. /opt/n9e/etc/scripts/notify.py:

    This suits longer scripts under version control. Nightingale will not deploy the file for you — you must ensure the path exists on every n9e host, is executable, and accessible to the n9e user.

  6. Click Save at the bottom-left — a “Script” channel is created.

Step 2: Use the channel in a notification rule

  1. Left menu Notify → Notification Rules → Add (or edit an existing rule).

  2. In the “Notification config” section:

    Picking the Script channel in a rule

    • Channel: pick the Script channel you just created.
    • Message template: needed only if the script reads tpl.title / tpl.content. If the script only uses events, any template works.
    • Custom parameters: any parameters added under “Variables” appear as inputs here.
    • Severity / time window / labels: filter which events get notified.
  3. After saving, click “Notification test” to send a sample event to your script. The script’s stdout/stderr (truncated to 512 bytes) is recorded in the notification history.

Script samples

Two common samples you can copy as-is.

Example 1: Python + requests, route by tag to different downstreams

#!/usr/bin/env python3
import json
import sys
import requests

data = json.load(sys.stdin)
events = data.get("events", [])
if not events:
    sys.exit(0)

# Route by tag
ROUTES = {
    "team=infra":   "https://itsm.example.com/api/n9e/infra",
    "team=biz":     "https://itsm.example.com/api/n9e/biz",
}

for ev in events:
    tags = ev.get("tags_json", {}) or {}
    tag_kv = [f"{k}={v}" for k, v in tags.items()]
    target = next((url for k, url in ROUTES.items() if k in tag_kv), None)
    if not target:
        continue
    requests.post(target, json=ev, timeout=5)

print("done")

Example 2: Append events to a local log for traceback

#!/bin/bash
mkdir -p /var/log/n9e-notify
cat >> /var/log/n9e-notify/$(date +%F).log
echo >> /var/log/n9e-notify/$(date +%F).log

Then tail -f /var/log/n9e-notify/$(date +%F).log will show what Nightingale is delivering to the script in real time — very handy when debugging.

FAQ

Q1: The script doesn’t run / permission denied?

A: Check each:

  • Under “Use path”, the file must exist and be executable by the n9e user (chmod +x).
  • Under “Use script content”, n9e auto-chmod 0777s the file, but only if it has write access to its current working directory (typically n9e’s start dir).
  • The first line must be a valid shebang, e.g. #!/usr/bin/env python3.

Q2: Script killed on timeout?

A: Default timeout is 5000ms, often not enough for scripts hitting external APIs. Raise the “Timeout” on the Script channel (e.g. 30000 for 30s). Inside the script also set per-request HTTP timeouts so a slow downstream can’t hang you.

Q3: stdin in my script gets nothing?

A: n9e closes stdin then waits for exit, so your script must “read all of stdin first, then process”. Use payload=$(cat) in Bash or json.load(sys.stdin) in Python. Blocking reads at startup like read -t 1 may miss the data.

Q4: Where does the script’s output go? How do I debug?

A: stdout and stderr are merged into the notification record’s details (max 512 bytes). To debug:

  • echo key variables in the script;
  • Tee stdin to a local log file (see Example 2);
  • Search n9e logs for event_script_notify_result — it shows the full stdin, command line, and stdout.

Q5: Can I use it inside a container?

A: Yes, but note:

  • The script must exist inside the n9e container (the “Use script content” mode writes into the container’s working directory).
  • Under “Use path”, mount the script directory into the container.
  • The container may not have bash/python3 — install them or switch to a static binary.
  • Interpreters in #!/usr/bin/env xxx must be on PATH.

Q6: How do I choose between Script and Callback?

A:

  • Downstream is a single HTTP endpoint: use Callback — simplest config.
  • Need local logic (CMDB lookup, time-of-day routing, multi-target fan-out): use Script — handle it all inside.
  • Need to archive events to a local file/queue: use Script.

References

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云