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

收集日志条目的时间戳。该字段必须符合以下格式之一:

  • ISO8601RFC3339
    • 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 微秒) or 1686026893735321098 (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"}

例如,如果hostapp字段都与流相关,那么在相应的日志条目的_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查询参数,以便正确的将每个容器的日志存储到不同的流中。

请勿将易发生变化的字段添加到流中,如ipuser_idtrace_id等。 因为这些可能会导致高基数问题 high cardinality issues

其他自定义字段

每个收集的日志除了_msg_time外,还可能包含任意数量的字段,如trace_id等。 这些字段可以用于简化和优化搜索查询。如在专用的trace_id中进行搜索比在长日志消息中搜索trace_id更快。

Link to original

LogsQL 使用

LogsQL中,将查询条件称为过滤

日志消息过滤

直接输入一个单词或一段话,筛选出包含对应内容的日志消息;

当筛选词LogsQL关键词冲突时,可以使用英文双引号括起来要查询的单词(话),如下

error

"error"

"AND"

"get data from Nacos error"

注意! 必须是一个完整的单词 比如 检索 nac 是无法查询出 包含有nacos单词的日志的

时间过滤 _time

  1. AND 运算符 与条件
    1. AND 可省略 用空格替代 即两个用空格隔开的过滤条件默认就是
  2. _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

相关笔记