Documentation / Observability
Searching logs
How to write a search on Runners > Logs: words, phrases, exclusions and the five filters, with worked examples, what the search holds and does not, and its limits.
Runners → Logs searches the build output of your finished jobs, across every repository, workflow and run, and shows when a message first appeared and how often. It answers "when did this error start?" without opening jobs one at a time.
Log search is not switched on for every deployment yet. Where it is not, the Logs tab says so, your job logs are unaffected, and nothing below does anything. The searches on this page are the ones it accepts once it is on.
This is not a full-text search of every log line. A build log has no severity of its own, because it is the output of your own tools, so we infer one. The search holds the error and warning lines of each finished job, found by the same rules as Jump to first error on a job's page, and nothing else:
A line is an error line if it looks like a failure: GitHub's
##[error]annotation,error:orfatal:orpanic:,FAILED,npm ERR!, aTypeError:-shaped exception, a TypeScripterror TS…, a non-zeroexit code.A line is a warning line if it looks like
warning:,WARN,[warn],npm warn, GitHub's##[warning]annotation or a deprecation notice.Everything else, including every ordinary line of output, is not kept, and a search cannot find it.
So "no results" is a statement about those lines. A message your tool printed as plain output is not found by searching for it; open the job and use its Search the log box.
Each job contributes at most 200 lines, errors before warnings, and each line is kept to its first 512 characters.
Words match whole words, ignoring case.
timedoes not findtimeout, andfailingdoes not findfailed: nothing is stemmed.A word with punctuation in it, such as a file path, needs every part of it to be present in the line.
Several words are ANDed: a line must contain all of them.
A word with a colon that is not one of the filters below, such as
Error:ora:b, is ordinary text.
| write | to find |
|---|---|
timeout | lines containing the word |
"connection reset" | lines containing the words next to each other, in that order |
-deprecated or -"retry later" | lines that do not contain it |
level:error,warn | only those levels (see Filters) |
branch:main repo:acme/api | only jobs from that branch and repository |
Words, phrases and filters can be combined in any order. Different filters are ANDed; the alternatives listed inside one filter are ORed.
| filter | takes | matches |
|---|---|---|
level: | error, warn or info, comma separated; warning is accepted for warn | the inferred level of the line. info is accepted but, as above, no info line is kept |
branch: | branch names, comma separated | the branch exactly, as typed (main, not refs/heads/main, which is also accepted) |
repo: | owner/name | the repository, ignoring case, in full |
workflow: | a workflow's name | the name in full, ignoring case |
job: | a job's name | the name in full, ignoring case |
A value is matched in full, not as a part: workflow:CI does not find a workflow called CI build. Put a value that contains a space in quotes: workflow:"CI build". A quoted workflow or job name may contain commas. A filter with no value, such as branch:, is refused.
The level, repository, workflow and branch can also be set with the controls beside the search box instead of being typed.
| search | what it finds |
|---|---|
timeout | every error or warning line that mentions a timeout |
"connection reset" | the phrase, in order |
ECONNRESET -retry | ECONNRESET lines that do not also say retry |
level:error | error lines only, whatever they say |
level:error,warn deprecated | errors and warnings that mention deprecated |
level:error branch:main | errors in jobs that ran for main |
level:error branch:main,develop | errors in jobs that ran for either branch |
repo:acme/api level:warn | warnings in one repository |
workflow:"CI build" "out of memory" | the phrase, only in the workflow named CI build |
job:test level:error -flaky | errors in jobs named test, leaving out lines that say flaky |
Error: Cannot find module | ordinary text: Error: is not a filter, so all four words are searched for |
level:error repo:acme/api branch:main workflow:CI job:test "exit code" | all five filters at once |
The search says what is wrong and runs nothing.
| search | why |
|---|---|
-level:error | a filter cannot be negated; "every line not from this branch" is the whole table |
"retry later | a quotation mark was opened and never closed |
level:fatal | a level must be error, warn or info |
branch: | a filter needs a value |
--- | a word needs a letter or digit in it |
| limit | value |
|---|---|
| Characters in a whole search | 200 |
| Words, phrases and exclusions together | 8 |
| Characters in one word or phrase | 64 |
| Values one filter may list | 5 |
| Characters in one filter value | 100 |
| Lines kept from one job | 200 |
| Characters kept of one line | 512 |
| Results one search returns at most | 100 |
| Longest range, in days | 90 |
A search covers the last 1, 7, 14, 30 or 90 days, chosen beside the search box; the page starts at 14 days. A result is a line with the job it came from, and opens that job at that line.
A search covers your own organisation's jobs and nobody else's; there is no way to name another organisation in a search. A result is a copy of a line from a job log, so it is deleted on the same clock as the log it came from: 90 days after the job, as set out in the privacy policy. Deleting a job deletes its lines.
Watching a job for the log of one job and its Search the log box.
Notifications to be told when a job fails instead of searching for why.