Configuration reference
Every key in config/requizon.php, its environment variable and its default.
Requizon works with no configuration file at all. When you want to change something, publish it:
php artisan vendor:publish --tag=requizon-config
The published config/requizon.php explains every key in its comments. This page is the same information
as a table, with a link to the page that covers each group in depth.
Laravel merges the package defaults into your file one top-level key at a time. If your file has a
recording array, it replaces the whole default recording array, so a key you leave out
of it is missing rather than defaulted. Keep each nested array complete, and re-check it after upgrading
Requizon.
Switches#
| Key | Env | Default | Purpose |
|---|---|---|---|
enabled |
REQUIZON_ENABLED |
true |
The master switch. false registers no recording middleware, no dashboard routes and no scheduled commands. Migrations still load. |
instrument.laravel_client |
REQUIZON_INSTRUMENT_LARAVEL |
true |
Installs the recording middleware on Laravel's HTTP client. false leaves the client alone and records only the Guzzle stacks you instrument. |
instrument.promise_fallback |
REQUIZON_PROMISE_FALLBACK |
true |
Records a transfer whose handler never reported transfer stats, timing it by wall clock. See the promise fallback. |
instrument.discovery |
REQUIZON_DISCOVERY |
false |
Hands a recording client to SDKs that resolve a PSR-18 client through php-http/discovery. Does nothing unless that package is installed. See client discovery. |
What is recorded, and under which name#
| Key | Default | Purpose |
|---|---|---|
ignore_hosts |
[] |
Str::is() host patterns that are never recorded. Ignoring hosts |
apis |
[] |
API name to Str::is() host patterns, and the redaction keys that API alone gets. A host no pattern matches is named after itself. Naming APIs |
paths.max_segments |
4 |
Path segments kept before the rest is replaced with /*. |
paths.max_segment_length |
40 |
A longer segment is treated as an identifier and stored as :id. |
paths.max_length |
255 |
The stored path is cut to this many bytes. It must fit the VARCHAR(255) column. |
paths.rewrite |
[] |
Str::is() patterns matched against the raw path, each mapped to the path to record instead, for identifiers the normaliser cannot recognise. First match wins. Rewriting paths |
paths.patterns |
[] |
An allow-list of normalised paths. When set, anything unmatched is stored under other_label. Paths and table size |
paths.other_label |
'other' |
The path recorded for calls that match none of paths.patterns. |
paths.store_raw |
true |
Keep the path each call was made to beside the normalised one. REQUIZON_STORE_RAW_PATHS sets it from the environment. The path as it was called |
paths.raw_long_segments |
false |
Keep segments longer than max_segment_length in the raw path instead of storing them as ***. |
paths.raw_unmasked |
[] |
Str::is() patterns for raw paths stored as called, unmasked by rewrites or the length rule. The redaction rules still apply. |
An apis entry is either its host patterns, or an array that names them under hosts
alongside the redaction keys that apply to that API alone. Both shapes can sit in the same list, and an entry that
leaves its patterns bare can still carry the keys:
'apis' => [
'nausys' => ['ws.nausys.com', '*.nausys.com', 'redact' => ['l']],
'stripe' => [
'hosts' => ['api.stripe.com', 'files.stripe.com'],
'redact' => ['card_number', 'cvc'],
],
'sedna' => [
'hosts' => ['sedna.example.com'],
'redact_exact' => ['l', 'p'],
],
],
redact matches a parameter name by substring and redact_exact by the whole name, the same
split as the two global lists below, and both are added to them for that API rather than replacing them. Rules are
keyed by the resolved API name, so an entry with keys and no hosts carries them for a name that
resolveApiUsing() mints. What they cover is on
Redaction and stored data.
Recording and redaction#
| Key | Default | Purpose |
|---|---|---|
recording.response_body_max_bytes |
65536 |
How much of a stored response body is kept, cut after redaction. |
recording.response_body_read_bytes |
262144 |
How far a response body is read for the failure detector and for redaction, separately from how much is stored. A JSON response past it is cut before its end and reaches the detector as a raw string. When response_body_max_bytes is larger, that is the limit instead. |
recording.request_body_max_bytes |
4096 |
How much of an unparsed request body is stored when store_unparsed_bodies is on. |
recording.query_max_bytes |
4096 |
The cap on a stored query string's JSON. Parameters that do not fit are dropped whole and counted under _truncated, so a thousand ids[] cost one row and not the table. |
recording.max_body_read_bytes |
262144 |
A request body larger than this is never read, only measured. Keeps file uploads out of memory. |
recording.store_unparsed_bodies |
false |
Store XML, SOAP and other bodies that cannot be parsed into named parameters verbatim, instead of by shape. |
recording.success_bodies |
false |
Keep the response bodies of successful calls too: true for every API, or a list of API names and host patterns. REQUIZON_SUCCESS_BODIES takes true or a comma separated list. Successful response bodies |
recording.success_body_sample_rate |
1.0 |
The share of covered successes whose body is kept, from 0.0 to 1.0. REQUIZON_SUCCESS_BODY_SAMPLE_RATE sets it from the environment. |
recording.redact_patterns |
pass, secret, token, apikey, api_key, auth |
A parameter whose lowercased name contains one of these is stored as ***. It covers the query, the request body, the parsed body of a failed response and header names, on every API. |
recording.redact_exact |
p, l, pwd |
A parameter with exactly this name is stored as ***. One API's own keys go on its apis entry instead. Redaction and stored data |
Header capture#
recording.headers decides which headers are stored, with a mode per direction. Requests and responses
each take none, failures (calls recorded as a failure, and successes whose body is kept)
or all.
| Key | Env | Default | Purpose |
|---|---|---|---|
recording.headers.request |
REQUIZON_REQUEST_HEADERS |
'none' |
Request headers are not stored until you ask for them. |
recording.headers.response |
REQUIZON_RESPONSE_HEADERS |
'failures' |
Response headers are stored on the rows that keep a response body: failures, and the successes success_bodies keeps. |
recording.headers.only |
— | [] |
When set, only headers matching these Str::is() patterns are stored, such as x-ratelimit-* or retry-after. |
recording.headers.except |
— | [] |
Patterns removed from whatever only left. |
recording.headers.redact |
— | authorization, proxy-authorization, cookie, set-cookie, *api-key*, *subscription-key*, x-functions-key |
Header names kept with every value replaced by ***, matched case-insensitively as Str::is() patterns. Your list replaces this one, though a published config with no headers.redact key at all still gets it. Headers |
recording.headers.max_bytes |
— | 16384 |
The cap on each message's stored header JSON. A header that does not fit is dropped whole and counted under _truncated. |
The names in redact_patterns and redact_exact, and the ones an API's apis
entry adds, mask a header as well as a parameter, so a provider's X-Partner-Key named there is masked
without being named twice.
Dashboard#
| Key | Env | Default | Purpose |
|---|---|---|---|
path |
REQUIZON_PATH |
'requizon' |
The URI the dashboard is served from. |
domain |
REQUIZON_DOMAIN |
null |
Serve the dashboard from a dedicated host. null serves it on every host the application answers. |
middleware |
— | ['web'] |
Applied to every dashboard route, before Requizon's own check of the viewRequizon gate. |
dashboard.windows |
— | [24, 72, 168, 336] |
The time windows, in hours, offered by the window selector. |
dashboard.default_window |
— | 72 |
The window shown first. A value not in windows falls back to the first entry. |
dashboard.per_page |
— | 50 |
Rows per page on the requests list. The dashboard |
dashboard.recent_minutes |
REQUIZON_RECENT_MINUTES |
15 |
What every page counts as "right now": failures in this stretch are called out above the charts and sort their rows to the top. Failures right now |
dashboard.max_paths |
— | 500 |
The most rows on an API's paths page: those with the most failures, then the most requests. A guard for APIs whose paths are not bounded yet. |
Calls that fail every time#
| Key | Default | Purpose |
|---|---|---|
fingerprint.ignore |
[] |
Parameter names, as Str::is() patterns in any case and at any depth, left out of the fingerprint because they change on every call: timestamps, nonces, request ids. |
fingerprint.min_attempts |
3 |
Failures a call needs before it is listed. |
fingerprint.min_span_minutes |
10 |
The least time between its first and last failure, so one call retried in a burst is not listed. |
fingerprint.max_results |
100 |
The most calls listed on a paths page. Calls that fail every time |
Storage, retention and scheduling#
| Key | Env | Default | Purpose |
|---|---|---|---|
connection |
REQUIZON_DB_CONNECTION |
null |
The database connection Requizon's tables live on. null is the default connection. MySQL 8.0.19+, MariaDB 10.5+, PostgreSQL 9.5+ and SQLite 3.24+ are supported. |
retention.detail_days |
— | 14 |
Days requizon_http_requests rows are kept. |
retention.aggregate_days |
— | 365 |
Days hourly rollup rows are kept. |
schedule.enabled |
REQUIZON_SCHEDULE |
true |
Register Requizon's commands on Laravel's scheduler: aggregate, prune, detect and the daily digest. false leaves scheduling to you. |
schedule.aggregate_hours |
— | 2 |
How many closed hours before the one under way each scheduled aggregate run rebuilds. Hours missed while the scheduler was down are caught up whatever this is. |
schedule.prune_at |
— | '03:00' |
The daily time requizon:prune runs, in the scheduler's timezone. Retention and scheduling |
schedule.daily_digest_at |
REQUIZON_DAILY_DIGEST_AT |
'09:00' |
The daily time requizon:daily-digest sends the alerts set to go out in the digest. |
Alerts and notifications#
alerts.detectors holds one entry per alert, each with enabled and its thresholds. They are
listed with their defaults on Alerts, and the
one that does nothing until configured is alerts.detectors.latency_high.targets.
| Key | Env | Default | Purpose |
|---|---|---|---|
alerts.notifications.channels |
REQUIZON_NOTIFY_CHANNELS |
[] |
Any of mail, slack and webhook, comma separated in the environment. Empty sends nothing, and the alerts page is the only record. |
alerts.notifications.mail.to |
REQUIZON_NOTIFY_MAIL |
[] |
The addresses alerts are mailed to, comma separated in the environment. |
alerts.notifications.slack.webhook_url |
REQUIZON_SLACK_WEBHOOK_URL |
null |
An incoming webhook URL, or a channel to post to through the bot token in services.slack.notifications. Needs laravel/slack-notification-channel. |
alerts.notifications.webhook.url |
REQUIZON_WEBHOOK_URL |
null |
Where the webhook channel POSTs its JSON. webhook.headers adds headers to it, and webhook.timeout (5 seconds) bounds it. |
alerts.notifications.routes |
— | [] |
Channels per severity (critical, warning, info) and for the digest. A severity not listed goes to every channel. |
alerts.notifications.repeat_minutes |
REQUIZON_NOTIFY_REPEAT_MINUTES |
360 |
How often an open alert is sent again until someone acknowledges it. 0 sends no reminders. |
alerts.notifications.resolved |
— | true |
Send a recovery once an alert clears. |
alerts.notifications.cooldown_minutes |
— | 60 |
An alert that clears and comes back within this long of its latest notification stays quiet. |
alerts.notifications.types |
— | every type, immediate |
Each alert's severity, and whether it is sent immediately, in the digest or not at all (none), with its own repeat_minutes and resolved if you like. Severities, routes and types |
Callbacks#
Some behaviours need code rather than a value, and are registered on BoringO11y\Requizon\Requizon,
usually in the boot() method of your published RequizonServiceProvider:
| Method | Replaces | Covered in |
|---|---|---|
resolveApiUsing() |
The apis host map. Returning null falls back to it. |
Naming APIs |
resolvePathUsing() |
The built-in path normaliser. Returning null falls back to it. |
Paths and table size |
redactUsing() |
Nothing. It receives what the name rules already redacted, for request parameters and for the parsed body of a failed response. | Redaction and stored data |
redactPathUsing() |
Nothing. It receives the raw path's segments after the built-in masking and returns the ones to store. | Paths and table size |
detectFailuresUsing() |
Nothing. Without it no successful response body is read. | Failure detection |
fingerprintUsing() |
The built-in fingerprint of method, host, raw path and parameters. Returning null falls back to it. |
Failure detection |
discoverUsing() |
The plain Guzzle client handed to SDKs through client discovery. | What gets recorded |
routeMailNotificationsTo(), routeSlackNotificationsTo(), routeWebhookNotificationsTo() |
Nothing. They set where alerts go, and a destination in the config wins over them. | Alerts |
auth() |
The viewRequizon gate check. The base provider registers one for you. |
The dashboard |
After changing configuration#
If you cache configuration in production, run php artisan config:cache again after editing the file, and
restart long-running processes (queue workers, Octane) so they pick up the new values.
php artisan about shows whether the HTTP client is instrumented and the path the dashboard is served
from, which is a quick way to confirm what the running configuration actually is.
A change to paths applies to calls recorded from then on. To fold the rows already stored into the new
paths, run requizon:merge-paths
once the new configuration is live everywhere.