Configuration reference
Every environment variable, its default, and the parts of config/sailfish.php that have none.
Sailfish works with no configuration on an application that watches its own database. Everything it reads is set by environment variables with the defaults below. Detector thresholds, notification types and retention have no environment variable; change them in the published config:
php artisan vendor:publish --tag=sailfish-config
Environment variables#
| Variable | Default | What it does |
|---|---|---|
SAILFISH_ENABLED | true | Master switch. When false Sailfish registers no commands, no schedule and no dashboard. Its migrations still load. |
SAILFISH_DB_CONNECTION | app default | Read performance_schema from here, and store the sailfish_* tables here |
SAILFISH_SCHEMAS | the connection's database | Comma-separated databases whose tables, indexes and statements are recorded |
SAILFISH_DIGEST_LIMIT | 1000 | Most statement digests read per collection |
SAILFISH_SCHEDULE_ENABLED | true | Put the commands on the scheduler. False to schedule them yourself. |
SAILFISH_PATH | sailfish | Where the dashboard is served |
SAILFISH_DOMAIN | none | Serve the dashboard on this domain only |
SAILFISH_NOTIFY_CHANNELS | none | Comma-separated: mail, slack, webhook |
SAILFISH_NOTIFY_MAIL | none | Comma-separated addresses |
SAILFISH_SLACK_WEBHOOK_URL | none | An incoming webhook, or a #channel to post to through the bot token |
SAILFISH_WEBHOOK_URL | none | Where the webhook channel POSTs JSON |
SAILFISH_NOTIFY_REPEAT_MINUTES | 360 | Send an immediate event again while it stays open this long. 0 never repeats. |
SAILFISH_DAILY_DIGEST_AT | 09:00 | When the daily digest goes out |
SAILFISH_ROLLUP_AT | 03:00 | When sailfish:rollup runs |
Connection and schemas#
Sailfish uses one connection for both jobs. Leaving SAILFISH_DB_CONNECTION empty uses the application's
default, and leaving SAILFISH_SCHEMAS empty watches the database that connection points at, which is
the right answer for an application watching itself.
To keep the performance_schema grant off your application's user, define a second connection to the same server with a user that has it, and name that one:
SAILFISH_DB_CONNECTION=mysql_sailfish
SAILFISH_SCHEMAS=app,billing
performance_schema is server-wide, so a connection on the same server can watch any schema on it. The
sailfish_* tables are written to the database that connection points at.
Statement digests#
Each collection reads only the digests that ran since the previous one, most recently run first, up to
SAILFISH_DIGEST_LIMIT. The cap matters only after a long gap. A digest it skips is not lost: its
counters are cumulative, so the next collection that reads it records everything it missed. If your digests are
empty, see statement digests.
Dashboard#
'domain' => env('SAILFISH_DOMAIN'),
'path' => env('SAILFISH_PATH', 'sailfish'),
'middleware' => ['web'],
'dashboard' => [
'windows' => [1, 7, 30, 90], // days the charts offer
'default_window' => 7,
'per_page' => 100,
],
The dashboard runs through middleware and then Sailfish's own check against the
viewSailfish gate. default_window should be one of windows.
Detectors#
Every detector has a key under detectors with an enabled flag and its thresholds. To turn
one off, or to make the table-scan surge less sensitive:
'detectors' => [
'scan_surge' => [
'enabled' => true,
'history_days' => 7,
'ratio' => 3,
'min_rows_per_hour' => 100_000,
],
'no_primary_key' => [
'enabled' => false,
],
// ...
],
Events lists every detector with its key and the thresholds it takes.
Notifications#
notifications.types gives each event type a severity (critical, warning or
info) and says whether it is sent immediately, in the digest, or
none at all. notifications.routes picks channels per severity. Both are covered in
notifications.
Retention#
'retention' => [
'raw_days' => 7,
'hourly_days' => 90,
'digest_days' => 90,
],
null keeps that granularity, or those digests, forever. See
retention and rollups.