菜单
文档breadcrumb arrow Grafana Lokibreadcrumb arrow 发送数据breadcrumb arrow OpenTelemetrybreadcrumb arrow 原生 OTLP 端点 vs Loki Exporter
开源

原生 OTLP 端点与 Loki Exporter 有何不同

引言

OpenTelemetry (OTel) 正在迅速成为行业标准,采用率不断提高。在 Loki 3.0 版本之前,Loki 没有原生支持摄取 OTel 日志,这促使创建了 LokiExporter。虽然 LokiExporter 完成了将 OTel 日志摄取到 Loki 的任务,但它没有提供原生的用户体验,并且查询体验也不理想。作为我们改善 OTel 用户体验工作的一部分,我们在 3.0 版本中为 Loki 添加了原生 OTel 日志摄取支持。

有哪些变化?

日志格式化

LokiExporter 的 README 详细解释了通过 LokiExporter 摄取的 OTel 日志的格式化方式,而 Loki 的原生 OTel 日志摄取端点在其文档中也详细描述了。以下是两种格式化方式的摘要对比

LokiExporter

  • 索引标签
    • 它支持通过 OTel 客户端/采集器设置的提示来控制标签。
    • 默认标签
      • job=service.namespace/service.name
      • instance=service.instance.id
      • exporter=OTLP
      • level=severity
  • 日志正文:将日志记录和属性编码为 json(默认)或 logfmt 格式。

Loki 的原生 OTel 日志摄取端点

  • 索引标签
    • 它支持通过 Loki 中的每租户 OTLP 配置来控制标签。
    • 默认情况下,它选择一些预配置的资源属性作为索引标签,如此处所述。
  • LogLine:LogRecord.Body 的字符串化形式。
  • 结构化元数据:未存储在索引标签和 LogLine 中的任何内容都存储为结构化元数据

示例日志

让我们来看以下示例 OTel 日志,并了解在默认配置下,它在这两种格式下摄取后会是什么样子

  • 资源属性
    • service.name: “auth”
    • service.namespace: “dev”
    • service.kind: “app”
  • 日志记录
    • Timestamp: 1715247552000000000
    • Body: “user logged in”
    • Severity Text: “INFO”
    • 属性

通过 LokiExporter 摄取

  • 索引标签
    • job=“dev/auth”
    • exporter=“OTLP”
  • 日志正文:{"body":"user logged in","severity":"INFO","attributes":{"email":"foo@bar.com"}, "resources":{"service.kind":"app","service.name":"auth","service.namespace":"dev"}}

通过 Loki 的原生 OTel 端点摄取

  • 索引标签
    • service_name=“auth”
    • service_namespace=“dev”
  • 日志正文:“user logged in”
  • 结构化元数据
    • service_kind: “app”
    • severity_text: “INFO”
    • email: “ foo@bar.com

查询体验

如前所述,LokiExporter 将数据编码为 json 或 logfmt blob,这需要在查询时解码才能与 OTel 属性进行交互。然而,原生 OTel 端点在存储数据之前不做任何编码。它利用结构化元数据,这使得在查询时无需使用任何解析器即可更轻松地与 OTel 属性进行交互。以上述摄取的日志行为例,让我们看看在不同场景下,两者的查询体验有何不同

查询所有日志,不带任何过滤器

  • 通过 LokiExporter 摄取:{job="dev/auth"}
  • 通过 Loki 的原生 OTel 端点摄取:{service_name="auth", service_namespace="dev"}

查询严重级别为 INFO 的日志

  • 通过 LokiExporter 摄取:{job="dev/auth"} | json | severity="INFO"
  • 通过 Loki 的原生 OTel 端点摄取:{service_name="auth", service_namespace="dev"} | severity_text="INFO"

在日志查询结果中将日志消息显示为日志行

  • 通过 LokiExporter 摄取:{job="dev/auth"} | json | line_format "{{.body}}"
  • 通过 Loki 的原生 OTel 端点摄取:{service_name="auth", service_namespace="dev"}

按电子邮件统计过去一小时内的登录事件

  • 通过 LokiExporter 摄取:sum(count_over_time({job="dev/auth"} |= "user logged in" | json[1h])) by (email)
  • 通过 Loki 的原生 OTel 端点摄取:sum(count_over_time({service_name="auth", service_namespace="dev"} |= "user logged in"[1h])) by (email)

从 LokiExporter 切换到原生 OTel 端点的好处

  • 未来改进:目前正在讨论弃用 LokiExporter,这将导致其不再获得未来的增强功能。Loki 的原生 OTel 端点代表着我们产品的未来,所有未来的开发和增强功能都将集中于此。升级到原生端点将确保您受益于最新的增强功能和最佳用户体验。
  • 简化的客户端配置: LokiExporter 需要设置提示来管理流标签,这违背了首先选择 OTel 的初衷,因为如果您不重新配置客户端就无法从一个 OTel 兼容的存储切换到另一个。使用 Loki 的原生 OTel 端点,无需为客户端设置提示来管理标签,没有额外的复杂性。
  • 简化的查询: Loki 的原生 OTel 端点利用结构化元数据,这使得在查询时无需使用 json 或 logfmt 解析器解码数据,即可更轻松地引用 OTel LogRecord 中的属性和其他字段。
  • 更现代、高上下文的数据模型: 与较旧的基于 json 的模型相比,更符合现代可观测性实践。

从 LokiExporter 切换到原生 OTel 摄取格式需要做什么?

  • 将您的 OpenTelemetry Collector 指向 Loki 原生 OTel 摄取端点,如此处所述。
  • 重写您在仪表盘、告警、Grafana Explore 中的星标查询等各种地方的 LogQL 查询,以按照新格式查询 OTel 日志。