LogsQL
通过 LogsQL 可以做到:
- 在日志字段中进行全文搜索
- 通过过滤器组合实现任意复杂的逻辑过滤器
- 查询时从无结构日志中提取结构化字段
- 计算所选日志条目的各种统计信息
VictoriaLogs 日志条目数据结构介绍
数据模型 Data Model
VictoriaLogs 支持结构化和非结构化日志。 每个日志条目
entry必须包含至少一个日志消息字段_msg。 可以向日志条目添加任意数量的附加key=value字段。 单个日志条目可以表示为由字符串键、字符串值组成的单级JSON对象。如:{ "job": "my-app", "instance": "host123:4567", "level": "error", "client_ip": "1.2.3.4", "trace_id": "1234-56789-abcdef", "_msg": "failed to serve the client request" }空值和不存在的值处理相同,下例中的几个json对象等价,都是只有一个非空属性
_msg{ "_msg": "foo bar", "some_field": "", "another_field": "" }, { "_msg": "foo bar", "third_field": "", }, { "_msg": "foo bar", }VictoriaLogs 在进行 数据收集(
data ingestion) 时会自动将多级(嵌套)JSON转换为单级JSON,规则如下:
- 嵌套的字典使用
.连接key实现扁平化 示例如下{ "host": { "name": "foobar", "os": { "version": "1.2.3" } } }, { "host.name": "foobar", "host.os.version": "1.2.3" }
- 数组、数字、布尔值都被转换为字符串 示例如下
{ "tags": ["foo", "bar"], "offset": 12345, "is_error": false }, { "tags": "[\"foo\", \"bar\"]", "offset": "12345", "is_error": "false" }字段名和字段值中可以包含任意字符。 这些字符必须在数据收集时根据JSON字符串编码进行编码。 Unicode字符必须使用
UTF-8编码进行编码。{ "field with whitespace": "value\nwith\nnewlines", "Поле": "价值" }VictoriaLogs 会自动索引所有收集日志中的所有字段。 这使得可以在所有字段上进行全文搜索(通过
LogSQL查询)。VictoriaLogs 除了任意其他字段外,还支持以下特殊字段:
消息字段 _msg
每个收集的日志条目都必须包含
_msg字段,其中包含实际的日志消息。 换言之, VictoriaLogs 的最小日志条目如下:{ "_msg": "some log message" }可以通过HTTP查询请求,另外指定其他字段起到
_msg的作用 详见:https://docs.victoriametrics.com/victorialogs/data-ingestion/#http-parameters时间字段 _time
收集日志条目的时间戳。该字段必须符合以下格式之一:
- ISO8601或RFC3339
- 如
2023-06-20T15:32:10Z- 或
2023-06-20 15:32:10.123456789+02:00- 如果缺少时区信息(如
2023-06-20 15:32:10) 则时间将根据运行 VictoriaLogs 的主机本地时区进行解析- Unix 时间戳 秒、毫秒、微秒或纳秒级 如
1686026893(seconds),1686026893735(milliseconds 毫秒),1686026893735321(microseconds 微秒) or1686026893735321098(nanoseconds 纳秒)可以通过HTTP查询请求,另外指定其他字段起到
_time的作用 详见:https://docs.victoriametrics.com/victorialogs/data-ingestion/#http-parameters如果
_time字段缺失或等于0则自动使用数据收集时间作为日志条目的时间戳
_time字段将被用于时间过滤,以便快速将搜索范围缩小到选定的时间区间。流字段 _stream
一些结构化日志字段可以唯一标识生成日志的应用示例。 这可能是单个字段,如
instance="host123:456",也可能是多个字段, 如:{kubernetes.namespace="cloud-new", kubernetes.node.name="worker01" ,kubernetes.pod.name="business-dev-xxxxx-xxxxx", kubernetes.container.name="business-dev"}来自单个应用示例的日志条目形成 VictoriaLogs 中的日志流
log stream。 VictoriaLogs 优化了单个日志流的存储和查询。好处如下:
- 减少磁盘使用
- 查询性能提升
每个收集的日志条目都与一个日志流相关联。每个日志流包含以下两个特殊字段:
_stream_id日志流的唯一标识符 可以通过_stream_id:...过滤器选择该流中的所有日志。_stream该字段包含格式类似于 普罗米修斯指标标签 的流标签 格式如:{host="host-123", app="my-app"}例如,如果
host和app字段都与流相关,那么在相应的日志条目的_stream字段中也将具有{host="host-123", app="my-app"}值。 可以使用流过滤器搜索_stream字段VictoriaLogs 无法自动确定哪些字段可以唯一标识每条日志流 所以默认情况下,
_stream字段的值为{}。 这可能导致资源使用和查询性能不佳。 因此,在数据收集时,建议通过_stream_fields查询参数指定流级字段。 如k8s容器中的日志,推荐具有如下字段:{ "kubernetes.namespace": "some-namespace", "kubernetes.node.name": "some-node", "kubernetes.pod.name": "some-pod", "kubernetes.container.name": "some-container", "_msg": "some log message" }相应的,需要在数据收集时指定
_stream_fields=kubernetes.namespace,kubernetes.node.name,kubernetes.pod.name,kubernetes.container.name查询参数,以便正确的将每个容器的日志存储到不同的流中。请勿将易发生变化的字段添加到流中,如
ip,user_id,trace_id等。 因为这些可能会导致高基数问题 high cardinality issues其他自定义字段
每个收集的日志除了
Link to original_msg和_time外,还可能包含任意数量的字段,如trace_id等。 这些字段可以用于简化和优化搜索查询。如在专用的trace_id中进行搜索比在长日志消息中搜索trace_id更快。
LogsQL 使用
在LogsQL中,将查询条件称为过滤
日志消息过滤
直接输入一个单词或一段话,筛选出包含对应内容的日志消息;
当筛选词LogsQL关键词冲突时,可以使用英文双引号括起来要查询的单词(话),如下
error
或
"error"
或
"AND"
或
"get data from Nacos error"注意! 必须是一个完整的单词 比如 检索 nac 是无法查询出 包含有nacos单词的日志的
时间过滤 _time
AND运算符 与条件AND可省略 用空格替代 即两个用空格隔开的过滤条件默认就是与
_time按照_time字段筛选符合时间要求的日志条目参与查询
例如:
error AND _time:5m
等价于
error _time:5m排序 sort
因为对大量日志排序需要消耗大量的CPU和内存,因此,Logsql查询返回的日志默认是乱序的。
返回日志数量较少时(例如少于几百万条),可以使用sort管道进行排序处理
下例是一个按时间排序的示例
_time:5m error | sort by (_time)倒序排列(在维多利亚自带的查询页面中 倒序查询好像不生效 原因没深究):
_time:5m error | sort by (_time) desc返回条目限制 limit
通过limit管道符可以约束只返回最后的几条日志
_time:5m error | sort by (_time) desc | limit 10查询字段过滤 fields
默认返回所有日志字段 可以通过fields管道仅展示部分字段 如:
error _time:5m | fields _time, _stream, _msg逻辑运算 与或非
- 与:
AND或 空格 - 或:
OR - 非:
NOT或!或-
流上下文管道 - 关键词搜索日志及其上下几条日志
<q> | stream_context 管道筛选条件
<q>代表关键词查询语句stream_context流上下文管道
管道筛选条件包括:
after xx额外返回关键词日志之后的xx条日志before xx额外返回关键词日志之前的xx条日志time_window xx时间范围调整 还不会用
如 希望返回包含 nacos 关键词的日志及其上下各5条日志:
nacos | stream_context after 5 before 5