SimpleLogSearch

Log Search Query Syntax: AND, OR, NOT, and Quoted Phrases

SimpleLogSearch speaks one small query language: AND, OR, NOT and double-quoted phrases — the entire syntax. Every rule below runs against a 24-line sample application log, so you can see exactly which lines each query returns.

The basic idea: terms and phrases

Two blocks build every query:

Both are tested per line as a case-insensitive substring — grep-style: no word boundaries, no wildcards, no field syntax.

The three operators

AND keeps lines matching every branch; OR keeps at least one; NOT removes any line its argument appears on. Six examples against the 24-line sample log:

OperatorExample queryWhat it matches in the sample log
AND"status=500" AND paymentsLines carrying both the failed request and the payments dependency — the "what broke, and why" pair.
error AND timeoutAny line mentioning both words; order and distance do not matter.
OR"status=200" OR "status=500"Every healthy or failed request line: 6, 11 and 15.
"svc=api" OR "svc=db"All API-service and database-service lines — a broad first pass.
NOTNOT "192.168.1.1"Lines not mentioning that IP — 17 of the 24 sample lines; line 10 is excluded too (its 192.168.1.10 still contains it).
"svc=db" NOT vacuumDatabase lines minus routine maintenance noise.

Operator tokens match as whole words in any casing — and, And and AND parse identically; a bare and is therefore always an operator (mistake five).

Precedence and parentheses

Without parentheses, NOT binds tightest, then AND, then OR — so a OR b AND c means a OR (b AND c). Parentheses override completely.

The engine's canonical example, worked step by step against the 24-line sample log:

"MID 123456" and "MID 123654" not "192.168.1.1"

Step 1 — apply precedence. No parentheses: not claims only its immediate argument, and the and chain evaluates left to right:

("MID 123456" AND "MID 123654") AND NOT "192.168.1.1"

Step 2 — the inner AND. The line must contain both IDs; exactly two qualify:

Step 3 — the NOT exclusion. NOT filters whole lines, so line 20 — which ends with via 192.168.1.1 — is removed even though that IP sits outside the matched phrases. Final result: line 7, the one place both IDs appear without the noisy address.

Key takeaway: an exclusion applies to the entire line, not just to what the AND matched — appending not "noise" removes every line where it appears.

When no line contains every term

AND matches only lines carrying all of its terms. If no line does, SimpleLogSearch falls back to the lines matching any of the query's positive terms — every NOT exclusion still applies — and says so in the status row. On a web access log, GET AND POST NOT healthz has no single line with both methods, so it returns the GET and POST lines without healthz. The fallback only ever fills an empty result: when some line does contain every term, that is what you get.

Implicit AND

Two operands side by side are ANDed — whitespace is itself the operator. Unquoted MID 123456 means term MID AND term 123456: any line containing both, in either order. Quoted "MID 123456" demands the exact adjacent sequence; on messier files the two can diverge, so quote whenever you mean the literal sequence.

Case-insensitive matching — and one substring caveat

Every test is case-insensitive: mid 123456, MID 123456 and "Status=200" all match. The caveat: no word boundaries, so "192.168.1.1" also matches a line containing only 192.168.1.10 (sample line 10). The fix — quote one extra character of context, usually a trailing space: "192.168.1.1 " narrows the sample log to line 16 alone; the same trick disambiguates any prefix collision.

Twelve queries, annotated

Each row ran against the same 24-line sample log; line numbers are original, 1-based.

#QueryWhat it matches
1"MID 123456"The exact phrase — lines 2, 4, 7, 8, 16, 20 and 23.
2MID 123456The unquoted, implicit-AND spelling of row 1 — the same seven lines here.
3"MID 123456" and "MID 123654"Only lines carrying both correlation IDs: 7 and 20.
4"MID 123456" and "MID 123654" not "192.168.1.1"The canonical query — row 3 minus the IP: line 7 alone (worked above).
5not "192.168.1.1"All lines without that substring: 17 of 24 (line 10's .10 address still contains it).
6"status=200" OR "status=500"The healthy and failed request lines: 6, 11 and 15.
7"svc=db" AND ("deadlock" OR "replication")Database lines about the two serious failure modes: 5 (deadlock), 20 (replication lag).
8("svc=api" OR "svc=db") AND errorERROR-level lines from either service: 5, 12, 20, 23 — parentheses change the answer versus "svc=api" OR ("svc=db" AND error).
9"192.168.1.1"The substring trap: lines 1, 4, 8, 16, 17, 20 — plus line 10 (its .10 address still contains it).
10"192.168.1.1 "Same phrase with a trailing space: only line 16.
11"svc=api" "status=200"Implicit AND of two phrases — successful API lines: 6 and 15.
12"and"The quoted operator as literal text: line 7, whose message contains the word "and".

Five common mistakes

  1. Missing quotes on a multi-word phrase. timeout after without quotes is two terms ANDed; only "timeout after" demands the exact sequence.
  2. Believing operators must be typed in one case. They are whole-token matches in any casing: and, And and AND parse identically (same for OR/NOT).
  3. Empty phrases. "" is a rejected query ("empty phrase"), not a zero-result search — nothing for it to match.
  4. Dangling operators. Every NOT, AND and OR needs a term on each side: "svc=api" AND and OR OR are rejected with "missing a search term".
  5. Searching for the literal word "and" unquoted. A bare operator token is always an operator — quote it: "and" matches the word itself (row 12).

That is the whole language: three operators, one quoting rule, one precedence chain. Load a sample log from the home page and run every query on this page — the result window keeps original line numbers. For the investigation workflow, see the How-To Guide; for privacy questions, the FAQ.