VictoriaLogs 关键概念

官方文档:https://docs.victoriametrics.com/victorialogs/keyconcepts/

数据模型 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更快。

相关笔记