CnOps 智能运维与可观测社区
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题

CnOps 智能运维与可观测社区

愿景

CnOps 智能运维与可观测社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页/开源项目/OpenTelemetry/日志
文档目录
文档开始手动插桩使用插桩库导出器资源采样什么是 OpenTelemetry?
可观测性入门上下文传播
链路(Trace)Metrics日志Baggage(行李)
组件语义约定Resources(资源)插桩范围采样Distributions(发行版)术语表
API 参考文档示例
支持库列表

OpenTelemetry

日志

日志是带有时间戳的文本记录,可以是结构化的(推荐)或非结构化的,且可附带元数据。 在所有遥测信号中,日志具有最悠久的历史。大多数编程语言都内置了日志记录功能,或有知名且广泛使用的日志库。 OpenTelemetry 并未定义专用的 API 或 SDK 来创建日志。相反,OpenTelemetry 日志指的是你已有的日志, 这些日志来自现有的日志框架或基础设施组件。OpenTelemetry...

日志是带有时间戳的文本记录,可以是结构化的(推荐)或非结构化的,且可附带元数据。
在所有遥测信号中,日志具有最悠久的历史。大多数编程语言都内置了日志记录功能,或有知名且广泛使用的日志库。

OpenTelemetry 日志 {#opentelemetry-logs}

OpenTelemetry 并未定义专用的 API 或 SDK 来创建日志。相反,OpenTelemetry 日志指的是你已有的日志,
这些日志来自现有的日志框架或基础设施组件。OpenTelemetry SDK 和自动注入功能利用多个组件,
自动将日志与链路关联。

OpenTelemetry 的日志支持旨在与你已有的日志完全兼容,提供了能力来为这些日志添加上下文,
并提供统一的工具包,将来自不同来源的日志解析并转换为统一格式。

OpenTelemetry Collector 中的 OpenTelemetry 日志 {#opentelemetry-logs-in-the-opentelemetry-collector}

OpenTelemetry Collector 提供了多个处理日志的工具:

  • 多种接收器,可从特定的、已知的数据源解析日志。
  • filelogreceiver,可从任意文件读取日志,并支持多种日志格式解析或使用正则表达式。
  • 类似 transformprocessor 的处理器,可解析嵌套数据、扁平化结构、添加/移除/更新值等。
  • 多种导出器(exporters),可将日志数据导出为非 OpenTelemetry 格式。

采纳 OpenTelemetry 的第一步通常是部署 Collector 作为通用日志代理。

应用中的 OpenTelemetry 日志 {#opentelemetry-logs-for-applications}

在应用中,可以通过任意日志库或语言内置日志功能创建 OpenTelemetry 日志。
当你启用自动注入或激活 SDK 后,OpenTelemetry 会自动将现有日志与活动的链路与 Span 关联起来,
并将这些 ID 包裹到日志正文中。换句话说,OpenTelemetry 会自动关联你的日志与链路信息。

语言支持情况 {#language-support}

日志信号在 OpenTelemetry 规范中是稳定的。
各语言对 Logs API 和 SDK 的支持情况如下:

结构化、非结构化与半结构化日志 {#structured-unstructured-and-semistructured-logs}

OpenTelemetry 在技术上并不区分结构化与非结构化日志。你可以使用任何已有的日志配合 OpenTelemetry。不过,
并非所有日志格式都同样有用!尤其是在生产环境中,推荐使用结构化日志,因为它们易于解析和大规模分析。
以下部分将解释三种类型日志的差异。

结构化日志 {#structured-logs}

结构化日志是指其文本格式具有一致性、可被机器读取的日志。在应用中,最常见的结构化格式是 JSON:

{
  "timestamp": "2024-08-04T12:34:56.789Z",
  "level": "INFO",
  "service": "user-authentication",
  "environment": "production",
  "message": "User login successful",
  "context": {
    "userId": "12345",
    "username": "johndoe",
    "ipAddress": "192.168.1.1",
    "userAgent": "Mozilla/5.0 ..."
  },
  "transactionId": "abcd-efgh-ijkl-mnop",
  "duration": 200,
  "request": {
    "method": "POST",
    "url": "/api/v1/login",
    "headers": {
      "Content-Type": "application/json",
      "Accept": "application/json"
    },
    "body": {
      "username": "johndoe",
      "password": "******"
    }
  },
  "response": {
    "statusCode": 200,
    "body": {
      "success": true,
      "token": "jwt-token-here"
    }
  }
}

对于基础设施组件,通常使用通用日志格式(CLF):

127.0.0.1 - johndoe [04/Aug/2024:12:34:56 -0400] "POST /api/v1/login HTTP/1.1" 200 1234

也可以混用不同结构化格式。例如扩展日志格式(ELF)可以将 JSON 与空格分隔的 CLF 数据混合:

192.168.1.1 - johndoe [04/Aug/2024:12:34:56 -0400] "POST /api/v1/login HTTP/1.1" 200 1234 "http://example.com" "Mozilla/5.0 ..." {"transactionId": "abcd-efgh...", ...}

为了充分利用这类日志,需要将 JSON 和 ELF 部分都解析为统一格式,便于在可观测性后端分析。
OpenTelemetry Collector 中的 filelogreceiver 提供了解析这类日志的标准方法。

结构化日志是最推荐的日志使用方式。由于格式一致,它们更易于解析,从而便于在 Collector
中预处理、与其他数据关联,并在后端平台分析。

非结构化日志 {#unstructured-logs}

非结构化日志指没有一致结构的日志。它们可能更易读,因此在开发中常用。
但在生产可观测性中不推荐使用,因为很难大规模解析和分析。

非结构化日志示例:

[ERROR] 2024-08-04 12:45:23 - Failed to connect to database. Exception: java.sql.SQLException: Timeout expired. ...

System reboot initiated at 2024-08-04 03:00:00 by user: admin. Reason: Scheduled maintenance. ...

DEBUG - 2024-08-04 09:30:15 - User johndoe performed action: file_upload. Filename: report_Q3_2024.pdf, Size: 2.3 MB ...

在生产环境中也可以存储和分析非结构化日志,尽管你可能需要进行大量解析或预处理工作,使其具备机器可读性。
例如,前面提到的三条日志就需要使用正则表达式解析时间戳,并编写自定义解析器来稳定地提取日志消息的正文。
这通常是日志后端根据时间戳对日志进行排序和组织所必需的。虽然解析非结构化日志以便分析是可行的,
但所需工作量往往比直接采用结构化日志要大,比如通过在应用中使用标准的日志记录框架来实现结构化日志。

半结构化日志 {#semistructured-logs}

半结构化日志具有某种自一致的模式以便被机器读取,但不同系统之间的数据格式和分隔符可能不一致。

半结构化日志示例:

2024-08-04T12:45:23Z level=ERROR service=user-authentication userId=12345 action=login message="Failed login attempt" error="Invalid password" ...

尽管机器可读,但为了实现大规模分析,仍可能需要多个解析器。

OpenTelemetry 日志组件 {#opentelemetry-logging-components}

以下是构成 OpenTelemetry 日志支持的核心概念和组件。

日志附加器/桥接器 {#log-appender--bridge}

作为应用开发者,你无需直接调用 Logs Bridge API,该 API 是为日志库作者构建日志附加器或桥接器而设。
你只需使用喜欢的日志库,并配置其使用能将日志传递给 OpenTelemetry LogRecordExporter 的附加器。

OpenTelemetry 各语言 SDK 提供了此功能。

Logger Provider

属于 Logs Bridge API,仅供日志库作者使用。

Logger Provider(有时叫 LoggerProvider)是 Logger 的工厂。
一般在应用启动时初始化一次,其生命周期与应用相同。初始化时也包括 Resource 和 Exporter 的初始化。

Logger

属于 Logs Bridge API,仅供日志库作者使用。

Logger 用于创建日志记录,Logger 实例由 Logger Provider 生成。

日志记录导出器 {#log-record-exporter}

Log Record Exporter 将日志记录发送到某个消费者。
消费者可以是标准输出(用于调试或开发),也可以是 OpenTelemetry Collector,或你选择的任何开源或商业后端。

日志记录 {#log-record}

日志记录代表对事件的记录。在 OpenTelemetry 中,日志记录包含两类字段:

  • 具备特定含义的命名顶级字段;
  • 可任意定义的 Resource 和 Attributes 字段。

顶级字段如下:

字段名 描述
Timestamp 事件发生的时间
ObservedTimestamp 观察到事件的时间
TraceId 请求的链路 ID
SpanId 请求的 Span ID
TraceFlags W3C 链路标志
SeverityText 严重性文本(也称日志级别)
SeverityNumber 严重性的数值表示
Body 日志正文
Resource 日志来源
InstrumentationScope 产生该日志的范围
Attributes 事件的附加信息

更多有关日志记录与字段的细节,请参阅日志数据模型。

规范 {#specification}

如需进一步了解 OpenTelemetry 中的日志,请参阅日志规范。

文章大纲