Configuration¶
Runtime Settings¶
NyxMon’s agent is configured primarily through CLI flags. When running uv run start-agent, you can provide:
--db: Path to the SQLite database file (required)--interval: Polling interval in seconds (default: 5)--cleanup-interval: Seconds between result-cleanup runs (default: 3600)--retention-period: Seconds to keep historical results (default: 86400)--batch-size: Maximum results deleted per cleanup batch (default: 1000)--disable-cleaner: Skip starting the results cleaner--log-level: Logging level (DEBUG,INFO,WARNING,ERROR,CRITICAL)--enable-telegram: Turn on Telegram notifications (requires credentials below)
Environment Variables¶
Telegram notifications read:
TELEGRAM_BOT_TOKEN: Bot token from BotFatherTELEGRAM_CHAT_ID: Chat ID for notificationsNYXMON_NOTIFY_CONSECUTIVE_FAILURES: Consecutive warning/error samples required before sending Telegram notifications or creating OpsGate tickets (default2; set1for immediate first-failure alerts)
OpsGate producer integration (optional) reads:
OPSGATE_SUBMIT_BASE_URL: OpsGate base URL (for examplehttp://studio.tailde2ec.ts.net:8711)OPSGATE_SUBMIT_TOKEN: Nyxmon submit token for OpsGateOPSGATE_APPROVAL_BASE_URL: Base URL used for approval links in notifications (defaults to submit base URL)OPSGATE_TICKET_EXPIRES_SECONDS: Ticket expiry window in seconds (default14400)OPSGATE_SUBMIT_TIMEOUT_SECONDS: Submit HTTP timeout in seconds (default10)OPSGATE_SUBMIT_INCLUDE_WARNINGS: Whether warning checks also create tickets (falseby default)
Django Settings¶
Django configuration is managed through environment variables in the src/django/config/settings/ directory.
DJANGO_SECRET_KEY: Secret key for Django (required in production)DJANGO_DEBUG: Enable debug mode (default: False in production)DJANGO_ALLOWED_HOSTS: Comma-separated list of allowed hosts
Check Types¶
HTTP Checks¶
The built-in HTTP executor issues a GET request and treats only 2xx responses as success. Redirects are followed automatically before the final response status is evaluated:
{
"type": "http",
"url": "https://example.com/health",
"data": {
"timeout": 10.0,
"retries": 3,
"retry_delay": 10.0,
"retry_status_codes": [502, 503, 504]
}
}
timeout defaults to 10.0, retries defaults to 0, retry_delay defaults to 2.0, and retry_status_codes defaults to [502, 503, 504]. Timeouts and request/connection errors also retry when retries is greater than zero. Non-transient HTTP statuses such as 404 do not retry unless explicitly listed in retry_status_codes.
Additional response validation (JSON assertions, headers, etc.) is planned.
TCP Checks¶
The TCP executor validates that a port is reachable and, optionally, that TLS negotiation works and certificates are not close to expiry:
{
"type": "tcp",
"url": "smtp.home.wersdoerfer.de",
"port": 587,
"tls_mode": "starttls", # "none", "implicit", or "starttls"
"connect_timeout": 10,
"tls_handshake_timeout": 10,
"retries": 1, # retry transient socket or TLS failures
"check_cert_expiry": true, # optional certificate age check
"min_cert_days": 14, # warning if below this threshold
"verify": true, # set false to skip certificate validation (e.g., self-signed tests)
"starttls_command": "STARTTLS\r\n" # override if a different upgrade command is required
}
If certificate expiry falls below min_cert_days, the executor returns an error result with error_type="cert_expiry" and severity="warning" in the payload.
SMTP Checks¶
Sends an authenticated message (typically for outbound flow checks):
{
"type": "smtp",
"url": "smtp.home.wersdoerfer.de", # host
"port": 587,
"tls": "starttls", # "none", "starttls", "implicit"
"username": "monitor@xn--wersdrfer-47a.de",
"password_secret": "nyxmon_local_monitor_password", # or password
"from_addr": "monitor@xn--wersdrfer-47a.de",
"to_addr": "wersdoerfer.mailmon@gmail.com",
"subject_prefix": "[nyxmon-outbound]",
"timeout": 30,
"retries": 2,
"retry_delay": 5
}
Returns error_type on auth failures, 4xx/5xx responses, or timeouts; includes attempts count for retry visibility.
IMAP Checks¶
Searches a mailbox for recent messages by subject and optionally deletes them:
{
"type": "imap",
"url": "imap.gmail.com", # host
"port": 993,
"tls_mode": "implicit", # "implicit", "starttls", "none"
"username": "wersdoerfer.mailmon@gmail.com",
"password_secret": "nyxmon_gmail_app_password", # or password
"folder": "INBOX",
"search_subject": "[nyxmon-outbound]",
"max_age_minutes": 30,
"delete_after_check": true,
"timeout": 30,
"retries": 2,
"retry_delay": 10
}
On success returns matched_uids and latest_internaldate; empty searches are retried according to retries/retry_delay before returning no_recent_message, and other failures include error_type values such as timeout or execution_error.
JSON Metrics Checks¶
Fetches a JSON endpoint (e.g., /.well-known/health) and evaluates threshold rules:
{
"type": "json-metrics",
"url": "http://macmini.tailde2ec.ts.net:9100/.well-known/health",
"auth": {"username": "nyxmon", "password": "secret"}, # optional basic auth
"timeout": 10,
"retries": 1,
"retry_delay": 2,
"checks": [
{"path": "$.mail.queue_total", "op": "<", "value": 100, "severity": "warning"},
{"path": "$.services.postfix", "op": "==", "value": "active", "severity": "critical"}
]
}
Supports operators <, <=, >, >=, ==, !=; severities warning/critical; simple path resolver $.field.subfield or $.items.0.value. Failures return error_type="threshold_failed" with all failing rules.
Ping Checks (planned)¶
Not yet implemented: Future work will add ICMP reachability checks.
DNS Checks¶
DNS checks verify that resolved records include at least one expected IP and support optional resolver overrides:
{
"type": "dns",
"url": "example.com",
"expected_ips": ["93.184.216.34"],
"dns_server": "8.8.8.8", # optional
"source_ip": "192.0.2.10", # optional, source address to bind
"query_type": "A", # optional, defaults to "A"
"timeout": 5.0 # optional, seconds
}
See DNS Check Configuration Examples for more configuration scenarios.
Deployment Configuration¶
systemd (Linux)¶
NyxMon uses systemd for service management on Linux:
[Unit]
Description=NyxMon Monitoring Agent
After=network.target
[Service]
Type=simple
User=nyxmon
WorkingDirectory=/home/nyxmon
ExecStart=/usr/local/bin/start-agent --db /var/lib/nyxmon/db.sqlite
Restart=always
[Install]
WantedBy=multi-user.target
launchd (macOS)¶
For macOS deployment, NyxMon uses launchd:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nyxmon.agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/start-agent</string>
<string>--db</string>
<string>/var/lib/nyxmon/db.sqlite</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
WSGI Server¶
NyxMon uses granian as its WSGI server (instead of gunicorn):
granian --interface wsgi config.wsgi:application --host 0.0.0.0 --port 8000
Repository Configuration¶
In-Memory Store¶
For tests or demos you can use the in-memory store bundle:
from nyxmon.adapters.repositories.in_memory import InMemoryStore
store = InMemoryStore()
SQLite Store¶
The production-ready store persists to SQLite:
from nyxmon.adapters.repositories.sqlite_repo import SqliteStore
store = SqliteStore(db_path="/path/to/database.sqlite")