Advanced Log Filtering
Querying the logs
Understanding field references
The log tables are queried with a subset of BigQuery SQL syntax. They all have three columns: event_message, timestamp, and metadata.
| column | description |
|---|---|
| timestamp | time event was recorded |
| event_message | the log's message |
| metadata | information about the event |
The metadata column is an array of JSON objects that stores important details about each recorded event. For example, in the Postgres table, the metadata.parsed.error_severity field indicates the error level of an event. To work with its values, you need to unnest them using a cross join.
This approach is commonly used with JSON and array columns, so it might look a bit unfamiliar if you're not used to working with these data types.
1select2 event_message,3 parsed.error_severity,4 parsed.user_name5from6 postgres_logs7 -- extract first layer8 cross join unnest(postgres_logs.metadata) as metadata9 -- extract second layer10 cross join unnest(metadata.parsed) as parsed;Expanding results
Logs returned by queries may be difficult to read in table format. A row can be double-clicked to expand the results into more readable JSON:

Filtering with regular expressions
The Logs use BigQuery Style regular expressions with the regexp_contains function. In its most basic form, it will check if a string is present in a specified column.
1select2 cast(timestamp as datetime) as timestamp,3 event_message,4 metadata5from postgres_logs6where regexp_contains(event_message, 'is present');There are multiple operators that you should consider using:
Find messages that start with a phrase
^ only looks for values at the start of a string
1-- find only messages that start with connection2regexp_contains(event_message, '^connection')Find messages that end with a phrase:
$ only looks for values at the end of the string
1-- find only messages that ends with port=123452regexp_contains(event_message, '$port=12345')Ignore case sensitivity:
(?i) ignores capitalization for all proceeding characters
1-- find all event_messages with the word "connection"2regexp_contains(event_message, '(?i)COnnecTion')Wildcards:
. can represent any string of characters
1-- find event_messages like "hello<anything>world"2regexp_contains(event_message, 'hello.world')Alphanumeric ranges:
[1-9a-zA-Z] finds any strings with only numbers and letters
1-- find event_messages that contain a number between 1 and 5 (inclusive)2regexp_contains(event_message, '[1-5]')Repeated values:
x* zero or more x
x+ one or more x
x? zero or one x
x{4,} four or more x
x{3} exactly 3 x
1-- find event_messages that contains any sequence of 3 digits2regexp_contains(event_message, '[0-9]{3}')Escaping reserved characters:
\. interpreted as period . instead of as a wildcard
1-- escapes .2regexp_contains(event_message, 'hello world\.')or statements:
x|y any string with x or y present
1-- find event_messages that have the word 'started' followed by either the word "host" or "authenticated"2regexp_contains(event_message, 'started host|authenticated')and/or/not statements in SQL:
and, or, and not are all native terms in SQL and can be used in conjunction with regular expressions to filter results
1select2 cast(timestamp as datetime) as timestamp,3 event_message,4 metadata5from postgres_logs6where7 (regexp_contains(event_message, 'connection') and regexp_contains(event_message, 'host'))8 or not regexp_contains(event_message, 'received');Filtering and unnesting example
Filter for Postgres
1select2 cast(postgres_logs.timestamp as datetime) as timestamp,3 parsed.error_severity,4 parsed.user_name,5 event_message6from7 postgres_logs8 cross join unnest(metadata) as metadata9 cross join unnest(metadata.parsed) as parsed10where regexp_contains(parsed.error_severity, 'ERROR|FATAL|PANIC')11order by timestamp desc12limit 100;Limitations
Log tables cannot be joined together
Each product table operates independently without the ability to join with other log tables. This may change in the future.
The with keyword and subqueries are not supported
The parser does not yet support with and subquery statements.
The ilike and similar to keywords are not supported
Although like and other comparison operators can be used, ilike and similar to are incompatible with BigQuery's variant of SQL. regexp_contains can be used as an alternative.
The wildcard operator * to select columns is not supported
The log parser is not able to parse the * operator for column selection. Instead, you can access all fields from the metadata column:
1select2 cast(postgres_logs.timestamp as datetime) as timestamp,3 event_message,4 metadata5from6 <log_table_name>7order by timestamp desc8limit 100;