fsl logs: read logs in the terminal
You do not need the cloud console to read your logs. fsl logs reads them from the command line and prints one JSON entry per line, for you or for a coding agent.
fsl logs asks the same questions as the Cloud Logging console, and the same command reads the emulator’s local files. Its flags are named after SQL clauses: --where severity=ERROR --since 2h --group-by labels.screen.
Guess a field that does not exist and the error names the valid ones, so the next try is right.
Production entries come through gcloud logging read. The gcloud CLI, signed in with gcloud auth login, is the only setup. It reads with its own sign-in, not the application-default credentials. No Google library is added to your install. The project id and bucket name are never printed, not even in an error.
For the project, pass --project <id>, or let it read .firebaserc. Add --local to read .fsl-logs/*.jsonl instead, with the same flags and the same output.
Examples
Section titled “Examples”# One user's story: client and server, in time ordernpx fsl logs --where labels.userId=<uid> --since 2h --select timestamp,severity,labels.screen,message
# Which screen had the most errors in a releasenpx fsl logs --where severity=ERROR --where labels.releaseId=<sha> \ --group-by labels.screen --select labels.screen,count --order-by "count desc" --limit 10
# The same, against .fsl-logs/ instead of the cloudnpx fsl logs --local --where severity=ERROR --group-by labels.screen --select labels.screen,countFields are written as Cloud Logging stores them: labels.screen, labels.userId, labels.releaseId, severity, message, timestamp. Use labels.screen, not screen. Payload fields start with jsonPayload., for example jsonPayload.error.message.
| Flag | Meaning |
|---|---|
--where field=value |
One condition. Repeat it for more. Operators: =, !=, >=, <=, ~ (contains). |
--select a,b,count |
The fields to print. Fewer fields, smaller output. With no value it prints the fields. |
--group-by field |
Count or aggregate per value. --select names the aggregate: count, min(f), max(f). |
--order-by "field desc" |
Sort order. Entries come oldest first unless you order them. |
--limit N |
Rows to print. 100 by default, 1000 at most. |
--distinct field |
The distinct values of one field. |
--since 1h |
30m, 1h, 2d, or an ISO time. 1 hour by default. |
--repeats <repeatKey> |
One repeating error: its full copies, its summaries, and a last line with the true count. Looks back 7 days unless --since says otherwise. |
--local |
Read .fsl-logs/*.jsonl instead of Cloud Logging. |
--project <id> |
The Google Cloud project. Read from .firebaserc when not given. |
Group, count and --select before you fetch whole entries. Ten lines of counts beat five thousand lines of entries. A whole entry includes its stack and breadcrumbs, so ask for them one entry at a time.
Output and errors
Section titled “Output and errors”stdout holds only entries, one JSON object per line. Everything else goes to stderr.
- No matches. stdout stays empty and one line on stderr says so, for example
0 entries matched in the last 1h.An empty result is not mistaken for a broken command. - A cut result. When
--limitcut the rows, a line on stderr says how many more there were. - A large window. A production query reads the newest 5000 entries in the window and says on stderr when it hit that. Narrow it with
--sinceor--where. - A wrong flag or field. An unknown flag is an error that lists the valid flags and shows an example. An unknown field names the nearest one and points at
fsl logs schema.
Count a repeating error
Section titled “Count a repeating error”A repeating error sends a few full copies and then one summary that counts the rest, so counting entries gives the wrong number. Take the error’s labels.repeatKey and ask for it directly:
npx fsl logs --repeats <repeatKey>See Rate limits and missing logs.
Find the labels
Section titled “Find the labels”fsl logs schema lists every label in your logs, how many entries have it, and sample values.
npx fsl logs schemanpx fsl logs schema --add venueId "the venue the order belongs to" --add tableIdnpx fsl logs schema --refresh--add records a label your code can write but the logs have not shown yet, with an optional meaning, for the next reader. --refresh re-reads the logs and keeps the --add entries. --remove <name> drops one of the --add entries, --json prints JSON, and --local reads the local files.
It reads the last 500 entries and keeps the result in .fsl-logs/schema.json for a day, in two parts: fromLogs, which --refresh rewrites, and fromCode, which --add fills and --refresh leaves alone.
Download an entry’s files
Section titled “Download an entry’s files”When an entry has labels.hasAttachments="true", fetch its files by labels.logId:
npx fsl logs attachments <logId>Files download to .fsl-logs/attachments/<logId>/ through gcloud storage, and each path is printed. The bucket comes from --bucket <name>, else FIREBASE_STORAGE_BUCKET, else VITE_FIREBASE_STORAGE_BUCKET, with .env.local loaded. See Screenshots and files.
Give it to an agent
Section titled “Give it to an agent”npx fsl install-skills installs a /fsl-logs skill that teaches a coding agent how to use fsl logs. See Skills for coding agents.
Made by Dasasian