高级日志过滤
查询日志
理解字段引用
日志表使用BigQuery SQL语法子集进行查询。所有日志表都包含三列:event_message
、timestamp
和metadata
。
列名 | 描述 |
---|---|
timestamp | 事件记录时间 |
event_message | 日志消息 |
metadata | 事件相关信息 |
metadata
列是一个JSON对象数组,存储了每个记录事件的重要细节。例如在Postgres表中,metadata.parsed.error_severity
字段表示事件的错误级别。要处理这些值,需要使用cross join
进行unnest
操作。
这种方法常用于JSON和数组列,如果您不熟悉这些数据类型,可能会觉得这种语法有些陌生。
12345678910select event_message, parsed.error_severity, parsed.user_namefrom postgres_logs -- 提取第一层 cross join unnest(postgres_logs.metadata) as metadata -- 提取第二层 cross join unnest(metadata.parsed) as parsed;
展开结果
查询返回的日志在表格格式中可能难以阅读。双击某一行可以将结果展开为更易读的JSON格式:
使用正则表达式过滤
日志系统使用BigQuery风格的正则表达式,通过regexp_contains函数实现。最基本的形式是检查指定列中是否存在某个字符串。
123456select cast(timestamp as datetime) as timestamp, event_message, metadatafrom postgres_logswhere regexp_contains(event_message, 'is present');
您应该考虑使用以下多种运算符:
查找以特定短语开头的消息
^
仅匹配字符串开头的值
12-- 仅查找以 connection 开头的消息regexp_contains(event_message, '^connection')
查找以特定短语结尾的消息:
$
仅匹配字符串末尾的值
12-- 仅查找以 port=12345 结尾的消息regexp_contains(event_message, '$port=12345')
忽略大小写:
(?i)
忽略后续所有字符的大小写
12-- 查找包含单词 "connection" 的所有 event_messages(不区分大小写)regexp_contains(event_message, '(?i)COnnecTion')
通配符:
.
可以代表任意字符序列
12-- 查找类似 "hello<任意内容>world" 的 event_messagesregexp_contains(event_message, 'hello.world')
字母数字范围:
[1-9a-zA-Z]
查找仅包含数字和字母的字符串
12-- 查找包含 1 到 5 之间数字(含)的 event_messagesregexp_contains(event_message, '[1-5]')
重复值:
x*
零个或多个 x
x+
一个或多个 x
x?
零个或一个 x
x{4,}
四个或更多 x
x{3}
正好 3 个 x
12-- 查找包含任意 3 位数字序列的 event_messagesregexp_contains(event_message, '[0-9]{3}')
转义保留字符:
\.
被解释为句点 .
而不是通配符
12-- 转义 .regexp_contains(event_message, 'hello world\.')
或
语句:
x|y
匹配包含 x
或 y
的任意字符串
12-- 查找包含单词 'started' 后接单词 "host" 或 "authenticated" 的 event_messagesregexp_contains(event_message, 'started host|authenticated')
SQL中的and
/or
/not
语句:
and
、or
和not
都是SQL原生关键字,可以与正则表达式结合使用来筛选结果
12345678select cast(timestamp as datetime) as timestamp, event_message, metadatafrom postgres_logswhere (regexp_contains(event_message, 'connection') and regexp_contains(event_message, 'host')) or not regexp_contains(event_message, 'received');
筛选与展开嵌套数据示例
Postgres日志筛选
123456789101112select cast(postgres_logs.timestamp as datetime) as timestamp, parsed.error_severity, parsed.user_name, event_messagefrom postgres_logs cross join unnest(metadata) as metadata cross join unnest(metadata.parsed) as parsedwhere regexp_contains(parsed.error_severity, 'ERROR|FATAL|PANIC')order by timestamp desclimit 100;
限制说明
日志表之间无法进行连接查询
每个产品表都是独立运行的,目前无法与其他日志表进行连接查询。这一限制未来可能会改变。
不支持with
关键字和子查询
解析器目前不支持with
语句和子查询。
不支持ilike
和similar to
关键字
虽然可以使用like
和其他比较运算符,但ilike
和similar to
与BigQuery的SQL变体不兼容。可以使用regexp_contains
作为替代方案。
不支持使用通配符*
选择列
日志解析器无法解析用于列选择的*
运算符。作为替代,您可以从metadata
列访问所有字段:
12345678select cast(postgres_logs.timestamp as datetime) as timestamp, event_message, metadatafrom <log_table_name>order by timestamp desclimit 100;