Overview
Extend Sequin's YAML configuration system to support declaring monitors as part of sink definitions, enabling infrastructure-as-code workflows.
Depends on: #1 (Schema), #2 (Context Module)
YAML Schema
Monitors are nested under sink definitions:
sinks:
- name: my-webhook-sink
type: http_push
# ... existing sink config ...
monitors:
- name: "High failure rate"
metric: failed_messages # pending_messages | failed_messages
type: threshold # threshold | anomaly
threshold: 100 # required for threshold type
window: 60s # threshold debounce window (default: 60s)
cooldown: 5m # min time between re-alerts (default: 5m)
notify_on_recovery: true # send resolved notification (default: true)
channels:
- type: slack
webhook_url: "https://hooks.slack.com/services/..."
- type: discord
webhook_url: "https://discord.com/api/webhooks/..."
- type: webhook
url: "https://my-app.com/alerts"
headers:
Authorization: "Bearer token"
- type: pagerduty
routing_key: "your-key"
- type: incident_io
api_key: "inc_..."
severity: critical
- name: "Pending anomaly"
metric: pending_messages
type: anomaly
sensitivity: medium # low | medium | high
cooldown: 15m
channels:
- type: slack
webhook_url: "https://hooks.slack.com/services/..."
Duration Parsing
Support human-readable durations:
30s → 30 seconds
1m → 60 seconds
5m → 300 seconds
1h → 3600 seconds
60 → 60 seconds (plain integer = seconds)
Config Parser Changes
In Sequin.ConfigParser
- After parsing a sink consumer, check for
monitors key
- For each monitor definition:
- Validate required fields based on type
- Parse duration strings to seconds
- Create
SinkMonitor changeset
- Create nested
SinkMonitorNotificationChannel changesets for each channel
- On
apply:
- Upsert monitors by
(sink_consumer_id, name) unique key
- Remove monitors that exist in DB but not in YAML (declarative sync)
- Upsert channels within each monitor
Validation Rules
name is required
metric must be one of pending_messages, failed_messages
type must be one of threshold, anomaly
- If
type: threshold: threshold is required (positive integer)
- If
type: anomaly: sensitivity is required (low/medium/high)
channels must have at least one entry
- Each channel must have
type + required config fields for that type
Export Support
Also support exporting monitors back to YAML (for sequin export or API export):
- Add
monitors key to sink export
- Convert seconds back to human-readable durations
- Mask secrets in channel configs (show
**** for webhook URLs, keys)
Files to Modify
lib/sequin/config_parser.ex — add monitor parsing within sink parsing
test/sequin_web/controllers/yaml_controller_test.exs — add monitor YAML test cases
Implementation Notes
- Follow existing YAML parsing patterns in
config_parser.ex
- Monitors should be processed AFTER the sink is created/found (they reference
sink_consumer_id)
- Use the same
Repo.transact pattern as other YAML entities
- Channel config validation should match the schema validation in the Ecto changeset
- Secret values in YAML should be handled consistently with existing secret handling (env var references, etc.)
Acceptance Criteria
Overview
Extend Sequin's YAML configuration system to support declaring monitors as part of sink definitions, enabling infrastructure-as-code workflows.
Depends on: #1 (Schema), #2 (Context Module)
YAML Schema
Monitors are nested under sink definitions:
Duration Parsing
Support human-readable durations:
30s→ 30 seconds1m→ 60 seconds5m→ 300 seconds1h→ 3600 seconds60→ 60 seconds (plain integer = seconds)Config Parser Changes
In
Sequin.ConfigParsermonitorskeySinkMonitorchangesetSinkMonitorNotificationChannelchangesets for each channelapply:(sink_consumer_id, name)unique keyValidation Rules
nameis requiredmetricmust be one ofpending_messages,failed_messagestypemust be one ofthreshold,anomalytype: threshold:thresholdis required (positive integer)type: anomaly:sensitivityis required (low/medium/high)channelsmust have at least one entrytype+ required config fields for that typeExport Support
Also support exporting monitors back to YAML (for
sequin exportor API export):monitorskey to sink export****for webhook URLs, keys)Files to Modify
lib/sequin/config_parser.ex— add monitor parsing within sink parsingtest/sequin_web/controllers/yaml_controller_test.exs— add monitor YAML test casesImplementation Notes
config_parser.exsink_consumer_id)Repo.transactpattern as other YAML entitiesAcceptance Criteria