菜单
开源 RSS

使用 OpenTelemetry Collector 摄取日志到 Loki

Loki 原生支持通过 HTTP 摄取 OpenTelemetry 日志。要使用 OpenTelemetry Collector 摄取日志到 Loki,您必须使用 otlphttp exporter

Loki 配置

当 Loki 使用 OpenTelemetry 协议 (OTLP) 摄取端点摄取日志时,部分数据会存储为结构化元数据

您必须在 Loki 配置文件中将 allow_structured_metadata 设置为 true。否则,Loki 将拒绝日志载荷,认为其格式错误。请注意,结构化元数据在 Loki 3.0 及更高版本中默认启用。

yaml
limits_config:
  allow_structured_metadata: true

配置 OpenTelemetry Collector 将日志写入 Loki

您需要对 OpenTelemetry Collector 配置进行以下更改,以便将日志写入 Loki 的 OTLP 摄取端点。

yaml
exporters:
  otlphttp:
    endpoint: http://<loki-addr>:3100/otlp

并在 service.pipelines 中启用它

yaml
service:
  pipelines:
    logs:
      receivers: [...]
      processors: [...]
      exporters: [..., otlphttp]

如果您想使用基本认证进行身份验证,我们推荐使用 basicauth 扩展

yaml
extensions:
  basicauth/otlp:
    client_auth:
      username: username
      password: password

exporters:
  otlphttp:
    auth:
      authenticator: basicauth/otlp
    endpoint: http://<loki-addr>:3100/otlp

service:
  extensions: [basicauth/otlp]
  pipelines:
    logs:
      receivers: [...]
      processors: [...]
      exporters: [..., otlphttp]

格式注意事项

由于 OpenTelemetry 协议与 Loki 存储模型不同,以下是 OpenTelemetry 格式数据在摄取期间默认映射到 Loki 数据模型的方式,这可以按稍后说明进行更改

  • 索引标签:资源属性与 Loki 中的索引标签很好地对应,因为两者通常都标识日志的来源。要存储为索引标签的资源属性默认列表可以在分发器的 otlp_config 下使用 default_resource_attributes_as_index_labels 进行配置。默认情况下,以下资源属性将存储为索引标签,而其余属性则作为结构化元数据与每个日志条目一起存储

    • cloud.availability_zone

    • cloud.region

    • container.name

    • deployment.environment.name

    • k8s.cluster.name

    • k8s.container.name

    • k8s.cronjob.name

    • k8s.daemonset.name

    • k8s.deployment.name

    • k8s.job.name

    • k8s.namespace.name

    • k8s.pod.name

    • k8s.replicaset.name

    • k8s.statefulset.name

    • service.instance.id

    • service.name

    • service.namespace

      注意

      由于 Loki 的默认索引标签限制为 15 个,我们建议仅选择部分资源属性作为索引标签。尽管默认配置选择了超过 15 个资源属性,但这应该没问题,因为其中一些是互斥的。

  • 时间戳:根据设置情况,使用 LogRecord.TimeUnixNanoLogRecord.ObservedTimestamp 之一。如果两者都未设置,将使用摄取时间戳。

  • 日志行:LogRecord.Body 包含日志主体。但是,由于 Loki 仅支持字符串格式的日志主体,我们将使用 OTel collector lib 中的 AsString 方法将非字符串值转换为字符串。

  • 结构化元数据:无法存储在索引标签和日志行中的任何内容都将存储为结构化元数据。以下是结构化元数据中将存储内容的非详尽列表,以让您了解它会包含哪些内容

    • 未存储为索引标签的资源属性会被复制并与每个日志条目一起存储。
    • InstrumentationScope 下的所有内容都会被复制并与每个日志条目一起存储。
    • LogRecord 下的所有内容,除了 LogRecord.BodyLogRecord.TimeUnixNano 和有时是 LogRecord.ObservedTimestamp

在将 OpenTelemetry 日志摄取到 Loki 之前需要注意的事项

  • 点号(.)转换为下划线(_)。

    Loki 在标签名称中不支持 . 或除 _ 以外的任何其他特殊字符。在将属性转换为索引标签或结构化元数据时,不支持的字符将被替换为 _。另外请注意,在编写查询时,您必须使用规范化格式,即在使用 OTel Attributes 查询数据时,使用 _ 代替特殊字符。

    例如,OTLP 中的 service.name 在 Loki 中将变为 service_name

  • 嵌套属性的展平

    在将 OTLP 中的属性转换为索引标签或结构化元数据时,任何嵌套的属性值都将使用 _ 作为分隔符进行展平。其方式类似于 LogQL JSON 解析器中的处理方式。

  • 非字符串属性值的字符串化

    在将 OTLP 中的属性值转换为索引标签值或结构化元数据时,任何非字符串值都将使用 OTel collector lib 中的 AsString 方法转换为字符串。

更改 OTLP 到 Loki 格式的默认映射

Loki 支持 按租户配置 OTLP 设置,允许您更改每个租户的 OTLP 到 Loki 格式的默认映射。目前仅支持更改属性的存储方式。配置如下所示

yaml
# OTLP log ingestion configurations
limits_config:
  otlp_config:
    # Configuration for Resource Attributes to store them as index labels or
    # Structured Metadata or drop them altogether
    resource_attributes:
      # Configure whether to ignore the default list of resource attributes set in
      # 'distributor.otlp.default_resource_attributes_as_index_labels' to be
      # stored as index labels and only use the given resource attributes config
      [ignore_defaults: <boolean>]
  
      [attributes_config: <list of attributes_configs>]
  
    # Configuration for Scope Attributes to store them as Structured Metadata or
    # drop them altogether
    [scope_attributes: <list of attributes_configs>]
  
    # Configuration for Log Attributes to store them as Structured Metadata or
    # drop them altogether
    [log_attributes: <list of attributes_configs>]
  
  attributes_config:
    # Configures action to take on matching Attributes. It allows one of
    # [structured_metadata, drop] for all Attribute types. It additionally allows
    # index_label action for Resource Attributes
    [action: <string> | default = ""]
  
    # List of attributes to configure how to store them or drop them altogether
    [attributes: <list of strings>]
  
    # Regex to choose attributes to configure how to store them or drop them
    # altogether
    [regex: <Regexp>]

以下是一些更改 OTLP 到 Loki 格式默认映射的配置示例

示例 1

yaml
limits_config:
  otlp_config:
    resource_attributes:
      attributes_config:
        - action: index_label
          attributes:
            - service.group

使用示例配置,各种类型的属性将按以下方式存储

  • 将前面提到的所有 17 个资源属性和 service.group 资源属性存储为索引标签。
  • 将剩余的资源属性存储为结构化元数据。
  • 将所有的 Scope 和 Log 属性存储为结构化元数据。

示例 2

yaml
limits_config:
  otlp_config:
    resource_attributes:
      ignore_defaults: true
      attributes_config:
        - action: index_label
          regex: service.group

使用示例配置,各种类型的属性将按以下方式存储

  • service.group 资源属性存储为索引标签。
  • 将剩余的资源属性存储为结构化元数据。
  • 将所有的 Scope 和 Log 属性存储为结构化元数据。

示例 3

yaml
limits_config:
  otlp_config:
    resource_attributes:
      attributes_config:
        - action: index_label
          regex: service.group
    scope_attributes:
      - action: drop
        attributes:
          - method.name
    log_attributes:
      - action: structured_metadata
        attributes:
          - user.id
      - action: drop
        regex: .*

使用示例配置,各种类型的属性将按以下方式存储

  • 将前面提到的所有 17 个资源属性和 service.group 资源属性存储为索引标签。
  • 将剩余的资源属性存储为结构化元数据。
  • 删除名为 method.name 的 Scope 属性,并将所有其他 Scope 属性存储为结构化元数据。
  • 将名为 user.id 的 Log 属性存储为结构化元数据,并删除所有其他 Log 属性。