Logs
Finding the line that explains the problem — filtering, following, multi-service apps, and what to log so the search works later.
Read production logs shows where they are. This page is about finding the one line that matters when there are a hundred thousand.
Narrow before you scroll
# server-side regex — the filtering happens before the data is sent $dibbla logs my-app --grep "level=error" # widen the window; the default is the last 15 minutes $dibbla logs my-app --since 24h # combine: errors from the last day, last 200 lines $dibbla logs my-app --since 24h --grep "level=(error|warn)" -n 200
$dibbla logs my-app -f $dibbla logs my-app -f --grep "checkout"
# NDJSON, one object per line: {ts, line, labels} # the log text is the string in .line — there is no .level or .msg $dibbla logs my-app --json --since 1h | jq -r 'select(.line | test("level=error")) | .line'
--grep is a server-side filter, so it is the cheap way to search a long
window. Piping to local grep fetches everything first and then throws most of
it away.
Multi-service apps
Omitting --service gives you every service, merged in time order — which
is usually what you want, because the interesting failures cross a boundary:
$dibbla logs beacon $dibbla logs beacon --service api
dibbla logs <app> --service <name> --pod-stream reads straight from the
running container instead of the log store. It needs --service and only
shows what that pod has buffered — a fallback for “is anything coming out at
all”, not a replacement.
What to log so this works
The searchability of your logs is decided when you write them, not when you read them:
- One event per line, with a level. Multi-line stack traces are one event’s worth of information spread across fifty lines your filter cannot match.
- Key-value over prose.
level=error order_id=1234 reason=timeoutcan be filtered; “Something went wrong while processing the order” cannot. - Log who did it. Your app receives the signed-in user in its
X-User-*headers. On anything that changes data, log that identity — “who did this?” is the question a shared internal tool raises most, and it is unanswerable afterwards if you did not write it down. - Never log the token. Not the API token, not the connection string, not
the
Authorizationheader. Logs are readable by everyone in the organisation who can open the console.
If one of the app’s secret values does turn up in a log line or in build
output anyway — a connection string printed at startup, say — the logs Dibbla
hands you show [secret NAME] in its place. It matches the exact value and its
base64 forms, and leaves values shorter than 8 characters alone, because those
turn up in ordinary text. It is protection against an accident, not against
someone who can deploy the app and wants a value out: they can encode it any
other way.
Metrics and alerts
Half of this exists now. Application checks run what your
app ships in dibbla-checks.yaml against the live deployment on a schedule
and on demand, and fire a typed notification when a check fails, errors or
recovers — that is the platform-native answer to “tell me when it’s broken”,
and it tests the user’s task, not just the port.
A metric store and an alert-rule engine over arbitrary timeseries still do not exist, and pretending otherwise would waste your afternoon. For everything checks can’t express, an external uptime or metric service against your app’s URL remains the honest answer.