Alerting

Email and webhook alerts for errors, updates and certificates.

sbox-ns can notify operators when it captures errors: Discord channel messages via an incoming webhook, and plain-text email via SMTP. Both are disabled by default, best-effort (a failed send is logged and never fails the request that triggered it), and configured entirely through alerts.toml, conf.d/ overrides, or NS_ environment variables.

What triggers an alert

Every error that reaches the shared error pipeline fans out to the log plus any configured channel:

  • Unhandled request exceptions captured for /admin/errors (5xx, plus 503 database outages).
  • Native endpoint-execution shadow failures (EndpointShadowReporter): executor exceptions, 5xx results, and 409 data-integrity conflicts (SAVE_REGRESSION_BLOCKED / STALE_SAVE). Repeated identical conflicts are throttled so a looping autosave cannot flood the channel.
  • Compatibility-proxy captures (ProxyErrorReporter) and handler-caught exceptions reported via HandlerErrorReporter.
  • Data-plane storage errors (INetworkStorageErrorAlertSink), e.g. unconfirmed saves.

Each alert carries the correlation ID, route, classification, project, and timestamp so it can be matched against /admin/errors entries and logs.

Discord setup

  1. In the Discord channel: Edit Channel → Integrations → Webhooks → New Webhook, copy the webhook URL.
  2. Store the URL in a secret file (recommended) or directly in config:
# alerts.toml
[alerts.discord]
enabled = true
webhook_url_file = "secrets/discord_webhook_url"
username = "sbox-ns"

or with environment variables:

NS_ALERTS__DISCORD__ENABLED=true
NS_ALERTS__DISCORD__WEBHOOK_URL_FILE=/run/secrets/discord_webhook

webhook_url and webhook_url_file are mutually exclusive; setting both is a validation error. Relative *_file paths resolve against the config folder. The message is a single embed (title, description, route / status / classification / correlation ID / project fields).

SMTP setup

# alerts.toml
[alerts.smtp]
enabled = true
host = "mail.example.com"
port = 587
username = "sbox-ns@example.com"
password_file = "secrets/smtp_password"
from = "sbox-ns@example.com"
to = "ops@example.com, oncall@example.com"
use_tls = true

password and password_file are mutually exclusive. Empty username means no authentication. to accepts comma- or semicolon-separated addresses. Mail is plain text with subject [sbox-ns] <Classification> <Method> <Path> (<CorrelationId>) and a field-list body; delivery uses a 10-second timeout and STARTTLS when use_tls is true.

Secrets handling

  • alerts.discord.webhook_url and alerts.smtp.password are flagged secret: sbox-ns config show prints "********" unless --show-secrets is passed, and the values never appear in logs or alert payloads.
  • Prefer *_file so secrets live outside the TOML files (same pattern as database.postgres.password_file). The first line of the file is used.

Checking the configuration

sbox-ns config validate                 # parse + combination checks with file:line
sbox-ns config show                     # merged effective config, secrets redacted
sbox-ns config set alerts.discord.enabled true
sbox-ns config get alerts.smtp.host

config set/get work for every alerts.* key through the generic mechanism — no special subcommands exist. There is no dry-run send command; to verify delivery, enable a channel and trigger a real capture (for example an invalid request against a test project), then confirm the correlation ID matches between the Discord/email alert, the server log, and /admin/errors.

Generated from sbox-cool/sbox-network-storage-server/docs/alerting.md at v0.1.0 (5aeb8e2).

Publication and source

GitHub source; s&box publication unverified. No confirmed package revision. All versions

Server: 0.1.0 (0.1.0), GitHub source sbox-cool/sbox-network-storage-server at v0.1.0 (5aeb8e2). Library: 1.1.0 source (13f51a8) (source-13f51a8), GitHub source sbox-cool/sbox-network-storage at 13f51a81f046b1722a6b747712afebccaa9559b3 (13f51a8).