Skip to content

Plugin Data Contract

This document specifies the exact interface between plugins and the NetAlertX core.

Important

Every plugin must output data in this exact format to be recognized and processed correctly.

Overview

Plugins communicate with NetAlertX by writing results to a pipe-delimited log file. The core reads this file, parses the data, and processes it for notifications, device discovery, and data integration.

File Location: /tmp/log/plugins/last_result.<PREFIX>.log

Format: Pipe-delimited (|), one record per line

Required Columns: 9 (mandatory) + up to 4 optional helper columns = 13 total

Column Specification

Note

The order of columns is FIXED and cannot be changed. All 9 mandatory columns must be provided. If you use any optional column (HelpVal1), you must supply all optional columns (HelpVal1 through HelpVal4).

Mandatory Columns (0–8)

Order Column Name Type Required Description
0 Object_PrimaryID string YES The primary identifier for grouping. Examples: device MAC, hostname, service name, or any unique ID
1 Object_SecondaryID string no Secondary identifier for relationships (e.g., IP address, port, sub-ID). Use null if not needed
2 DateTime string YES Timestamp when the event/data was collected. Format: YYYY-MM-DD HH:MM:SS
3 Watched_Value1 string YES Primary watched value. Changes trigger notifications. Examples: IP address, status, version
4 Watched_Value2 string no Secondary watched value. Use null if not needed
5 Watched_Value3 string no Tertiary watched value. Use null if not needed
6 Watched_Value4 string no Quaternary watched value. Use null if not needed
7 Extra string no Any additional metadata to display in UI and notifications. Use null if not needed
8 ForeignKey string no Foreign key linking to parent object (usually MAC address for device relationship). Use null if not needed

Optional Columns (9–12)

Order Column Name Type Required Description
9 HelpVal1 string conditional Helper value 1. If used, all help values must be supplied
10 HelpVal2 string conditional Helper value 2. If used, all help values must be supplied
11 HelpVal3 string conditional Helper value 3. If used, all help values must be supplied
12 HelpVal4 string conditional Helper value 4. If used, all help values must be supplied

Usage Guide

Empty/Null Values

  • Represent empty values as the literal string null (not Python None, SQL NULL, or empty string)
  • Example: device_id|null|2023-01-02 15:56:30|status|null|null|null|null|null

Watched Values

What are Watched Values?

Watched values are fields that the NetAlertX core monitors for changes between scans. When a watched value differs from the previous scan, it can trigger notifications.

How to use them: - Watched_Value1: Always required; primary indicator of status/state - Watched_Value2–4: Optional; use for secondary/tertiary state information - Leave unused ones as null

Example: - Device scanner: Watched_Value1 = "online" or "offline" - Port scanner: Watched_Value1 = "80" (port number), Watched_Value2 = "open" (state) - Service monitor: Watched_Value1 = "200" (HTTP status), Watched_Value2 = "0.45" (response time)

Foreign Key

Use the ForeignKey column to link objects to a parent device by MAC address:

device_name|192.168.1.100|2023-01-02 15:56:30|online|null|null|null|Found on network|aa:bb:cc:dd:ee:ff
                                                                                              ↑
                                                                                        ForeignKey (MAC)

This allows NetAlertX to: - Display the object on the device details page - Send notifications when the parent device is involved - Link events across plugins

Examples

Valid Data (9 columns, minimal)

https://example.com|null|2023-01-02 15:56:30|200|null|null|null|null|null
printer-hp-1|192.168.1.50|2023-01-02 15:56:30|online|50%|null|null|Last seen in office|aa:11:22:33:44:55
gateway.local|null|2023-01-02 15:56:30|active|v2.1.5|null|null|Firmware version|null

Valid Data (13 columns, with helpers)

service-api|192.168.1.100:8080|2023-01-02 15:56:30|200|45ms|true|null|Responding normally|aa:bb:cc:dd:ee:ff|extra1|extra2|extra3|extra4
host-web-1|10.0.0.20|2023-01-02 15:56:30|active|256GB|online|ok|Production server|null|cpu:80|mem:92|disk:45|alerts:0

Invalid Data (Common Errors)

Missing required column (only 8 separators instead of 8):

https://google.com|null|2023-01-02 15:56:30|200|0.7898||null|null
                                                      ↑
                                                  Missing pipe

Missing mandatory Watched_Value1 (column 3):

https://duckduckgo.com|192.168.1.1|2023-01-02 15:56:30|null|0.9898|null|null|Best|null
                                                         ↑
                                          Must not be null

Incomplete optional columns (has HelpVal1 but missing HelpVal2–4):

device|null|2023-01-02 15:56:30|status|null|null|null|null|null|helper1
                                                                    ↑
                                                    Has helper but incomplete

Complete with helpers (all 4 helpers provided):

device|null|2023-01-02 15:56:30|status|null|null|null|null|null|h1|h2|h3|h4

Complete without helpers (9 columns exactly):

device|null|2023-01-02 15:56:30|status|null|null|null|null|null

Using plugin_helper.py

The easiest way to ensure correct output is to use the plugin_helper.py library:

from plugin_helper import Plugin_Objects

# Initialize with your plugin's prefix
plugin_objects = Plugin_Objects("YOURPREFIX")

# Add objects
plugin_objects.add_object(
    Object_PrimaryID="device_id",
    Object_SecondaryID="192.168.1.1",
    DateTime="2023-01-02 15:56:30",
    Watched_Value1="online",
    Watched_Value2=None,
    Watched_Value3=None,
    Watched_Value4=None,
    Extra="Additional data",
    ForeignKey="aa:bb:cc:dd:ee:ff",
    HelpVal1=None,
    HelpVal2=None,
    HelpVal3=None,
    HelpVal4=None
)

# Write results (handles formatting, sanitization, and file creation)
plugin_objects.write_result_file()

The library automatically: - Validates data types - Sanitizes string values - Normalizes MAC addresses - Writes to the correct file location - Creates the file in /tmp/log/plugins/last_result.<PREFIX>.log

De-duplication

The core runs de-duplication once per hour on the Plugins_Objects table:

  • Duplicate Detection Key: Combination of Object_PrimaryID, Object_SecondaryID, Plugin (auto-filled from unique_prefix), and UserData
  • Resolution: Oldest duplicate entries are removed, newest are kept
  • Use Case: Prevents duplicate notifications when the same object is detected multiple times

DateTime Format

Required Format: YYYY-MM-DD HH:MM:SS

Examples: - 2023-01-02 15:56:30 ✅ - 2023-1-2 15:56:30 ❌ (missing leading zeros) - 2023-01-02T15:56:30 ❌ (wrong separator) - 15:56:30 2023-01-02 ❌ (wrong order)

Python Helper:

from datetime import datetime

# Current time in correct format
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# Output: "2023-01-02 15:56:30"

Bash Helper:

# Current time in correct format
date '+%Y-%m-%d %H:%M:%S'
# Output: 2023-01-02 15:56:30

Validation Checklist

Before writing your plugin's script.py, ensure:

  • 9 or 13 columns in each output line (8 or 12 pipe separators)
  • Mandatory columns filled:
  • Column 0: Object_PrimaryID (not null)
  • Column 2: DateTime in YYYY-MM-DD HH:MM:SS format
  • Column 3: Watched_Value1 (not null)
  • Null values as literal string null (not empty string or special chars)
  • No extra pipes or misaligned columns
  • If using optional helpers (columns 9–12), all 4 must be present
  • File written to /tmp/log/plugins/last_result.<PREFIX>.log
  • One record per line (newline-delimited)
  • No header row (data only)

Debugging

View raw plugin output:

cat /tmp/log/plugins/last_result.YOURPREFIX.log

Check line count:

wc -l /tmp/log/plugins/last_result.YOURPREFIX.log

Validate column count (should be 8 or 12 pipes per line):

cat /tmp/log/plugins/last_result.YOURPREFIX.log | awk -F'|' '{print NF}' | sort | uniq
# Output: 9 (for minimal) or 13 (for with helpers)

Check core processing in logs:

tail -f /tmp/log/stdout.log | grep -i "YOURPREFIX\|Plugins_Objects"

See Also