遥测

高级日志过滤


查询日志

理解字段引用

日志表使用BigQuery SQL语法子集进行查询。所有日志表都包含三列:event_messagetimestampmetadata

列名描述
timestamp事件记录时间
event_message日志消息
metadata事件相关信息

metadata列是一个JSON对象数组,存储了每个记录事件的重要细节。例如在Postgres表中,metadata.parsed.error_severity字段表示事件的错误级别。要处理这些值,需要使用cross join进行unnest操作。

这种方法常用于JSON和数组列,如果您不熟悉这些数据类型,可能会觉得这种语法有些陌生。

1
2
3
4
5
6
7
8
9
10
select 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函数实现。最基本的形式是检查指定列中是否存在某个字符串。

1
2
3
4
5
6
select cast(timestamp as datetime) as timestamp, event_message, metadatafrom postgres_logswhere regexp_contains(event_message, 'is present');

您应该考虑使用以下多种运算符:

查找以特定短语开头的消息

^ 仅匹配字符串开头的值

1
2
-- 仅查找以 connection 开头的消息regexp_contains(event_message, '^connection')

查找以特定短语结尾的消息:

$ 仅匹配字符串末尾的值

1
2
-- 仅查找以 port=12345 结尾的消息regexp_contains(event_message, '$port=12345')

忽略大小写:

(?i) 忽略后续所有字符的大小写

1
2
-- 查找包含单词 "connection" 的所有 event_messages(不区分大小写)regexp_contains(event_message, '(?i)COnnecTion')

通配符:

. 可以代表任意字符序列

1
2
-- 查找类似 "hello<任意内容>world" 的 event_messagesregexp_contains(event_message, 'hello.world')

字母数字范围:

[1-9a-zA-Z] 查找仅包含数字和字母的字符串

1
2
-- 查找包含 1 到 5 之间数字(含)的 event_messagesregexp_contains(event_message, '[1-5]')

重复值:

x* 零个或多个 x
x+ 一个或多个 x
x? 零个或一个 x
x{4,} 四个或更多 x
x{3} 正好 3 个 x

1
2
-- 查找包含任意 3 位数字序列的 event_messagesregexp_contains(event_message, '[0-9]{3}')

转义保留字符:

\. 被解释为句点 . 而不是通配符

1
2
-- 转义 .regexp_contains(event_message, 'hello world\.')

语句:

x|y 匹配包含 xy 的任意字符串

1
2
-- 查找包含单词 'started' 后接单词 "host" 或 "authenticated" 的 event_messagesregexp_contains(event_message, 'started host|authenticated')

SQL中的and/or/not语句:

andornot都是SQL原生关键字,可以与正则表达式结合使用来筛选结果

1
2
3
4
5
6
7
8
select 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日志筛选

1
2
3
4
5
6
7
8
9
10
11
12
select 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语句和子查询。

不支持ilikesimilar to关键字

虽然可以使用like和其他比较运算符,但ilikesimilar to与BigQuery的SQL变体不兼容。可以使用regexp_contains作为替代方案。

不支持使用通配符*选择列

日志解析器无法解析用于列选择的*运算符。作为替代,您可以从metadata列访问所有字段:

1
2
3
4
5
6
7
8
select cast(postgres_logs.timestamp as datetime) as timestamp, event_message, metadatafrom <log_table_name>order by timestamp desclimit 100;