SQLert.Alert behaviour (sqlert v0.0.2)
View SourceDefines an SQL-based alert (Behaviour).
SQLert alerts are modules that specify SQL queries to be executed on schedule, checking for specific conditions in your database. When these conditions are met, alerts can trigger notifications through various channels.
Alert Lifecycle
Each alert runs in its own process and follows this lifecycle:
- At the configured schedule, the alert's
query/0
callback is executed - The query result is passed to
handle_result/1
- If
handle_result/1
returns{:alert, message, metadata}
, notifications are sent - The process waits for the next scheduled
Defining Alerts
To define an alert, create a module that uses SQLert.Alert
and implement
the required callbacks:
defmodule MyApp.Alerts.HighErrorRate do
use SQLert.Alert,
schedule: "10 * * * *"
enabled: true
@impl true
def query do
"SELECT COUNT(*) FROM errors WHERE created_at > NOW() - INTERVAL '1 hour'"
end
@impl true
def handle_result([[count]]}) when count > 100 do
{:alert, "High error rate detected", %{count: count}}
end
def handle_result(_) do
{:skip, %{count: 0}}
end
@impl true
def notifiers do
[MyApp.Alerts.Notifiers.Slack]
end
end
Configuration Options
:schedule
- (String) Cron notation with the alert schedule. REQUIRED:enabled
- (Boolean) Whether this alert should run. Defaults toMix.env() == :prod
Query Types
The query/0
callback can return either a string SQL query or an Ecto query:
# Raw SQL
def query do
"SELECT COUNT(*) FROM users WHERE last_login < NOW() - INTERVAL '30 days'"
end
# Ecto query
def query do
from u in User,
where: u.last_login < ago(30, "day"),
select: count(u.id)
end
Handling Results
The handle_result/1
callback receives the query result and must return one of:
{:alert, message, metadata}
- Trigger notifications with the given message{:skip, metadata}
- Condition not met, skip notifications
For SQL queries, results come in the format %{rows: [[value]]}
. For Ecto queries,
you receive the direct query result.
Notifications
Alerts can have multiple notifiers that implement the SQLert.Notifier
behaviour.
Define them in the notifiers/0
callback:
def notifiers do
[
MyApp.Alerts.Notifiers.Slack,
MyApp.Alerts.Notifiers.Email
]
end
See SQLert.Notifier
for details on implementing notifiers.
Summary
Types
Callbacks
@callback handle_result(any()) :: alert_result()
@callback notifiers() :: [module()]
@callback query() :: query()