OpenTelemetry (OTel) 是一个专为监控应用程序运行状况而设计的开源标准。通过收集指标、日志、追踪数据,它提供了系统运行情况的全面视图,帮助运维团队快速识别和解决问题。
在我们之前的文章:《云原生运维入门必看!OpenTelemetry 三大数据类型及核心组件解析》中,我们介绍了 OTel 的不同组件及其协同方式。
在本文中,我们将重点关注日志数据,这是系统监测最重要的指标之一。日志对于理解系统内的事件至关重要,它提供了操作的详细时间戳记录。然而,日志的非结构化特点增加了分析日志数据的难度。针对这点, OpenTelemetry 的标准化 Log Data Model 提供了一个结构化框架,使得获取、查询和分析日志更简单。
在 OpenTelemetry 中获取日志
日志是开发人员了解系统内发生事件最常用的数据,其本质上是非结构化的数据流,可以让开发人员灵活地发送应用程序状态数据。但是由于缺乏结构化,开发一款用于捕获、解析和保存日志的标准化工具变得相当困难。
而这些问题恰恰可以被 OpenTelemetry Log Data Model 很好地解决。其标准化结构能帮助用户对每个日志的上下文进行更深入的理解,解答关于日志是何时、何地、为何以及如何发出的问题。
Log Data Model 类型及示例问题
| Field Name | Description |
|---|---|
| Timestamp | Time when the event occurred. |
| ObservedTimestamp | Time when the event was observed. |
| TraceId | Request trace id. |
| SpanId | Request span id. |
| TraceFlags | W3C trace flag. |
| SeverityText | The severity text (also known as log level). |
| SeverityNumber | Numerical value of the severity. |
| Body | The body of the log record. |
| Resource | Describes the source of the log. |
| InstrumentationScope | Describes the scope that emitted the log. |
| Attributes | Additional information about the event. |
Tracing 上下文
◦ TraceId
和 SpanId
字段将日志与分布式跟踪关联起来,使开发人员能够跟踪请求在多个服务中的路径。
◦ 示例问题:在某个特定用户交易时还发生了哪些事件?
时间信息
◦ Timestamp
和 ObservedTimestamp
字段回答了事件何时发生以及处理时间多久的问题。
◦ 示例问题:事件发生和在系统中被观察到之间是否有延迟?
严重性和重要性
◦ SeverityText
和 SeverityNumber
字段能够按严重性过滤日志,并指定处理日志的优先级。
◦ 示例问题:在过去一小时内发生了多少严重错误?
上下文属性
◦ Attributes
字段允许添加自定义键值对,提供额外的上下文。
◦ 示例问题:与此错误相关的用户 ID 是什么?
源标识
◦ Resource
字段有助于识别日志的来源(例如,哪个服务、主机或容器)
◦ 示例问题:哪个特定微服务生成的错误最多?
Instrumentation 详情
◦ InstrumentationScope
字段提供有关生成日志的库或模块的信息。
◦ 示例问题:是否有来自特定第三方库的错误模式?
灵活的消息内容
◦ Body
字段包括了结构化或非结构化的日志消息,支持传统的日志记录和更现代的结构化日志记录方法。
◦ 示例问题:我们在小部件服务中看到的最常见错误是什么?
通过遵循这一模型,日志不仅仅是简单的文本记录,它们变成了丰富的、可查询的数据点。通过与其他遥测数据(如追踪和指标)轻松关联,日志能够提供对系统行为和性能的全面视图。
将日志转换为 Log Data Model

日志 SDK
日志 SDK 由 OpenTelemetry 提供的库组成,它将现有日志库关联到其他 OpenTelemetry 下游系统可读的 OTLP 格式。开发人员要想把日志保存到数据库里,就可以直接使用 Log SDK ,减少安装和维护其他组件的工作量。
安装 Log SDK 需要配置现有语言日志框架,如 Python 的 logging
、Go 的 log
或 Java 的 Log4j
与 OpenTelemetry LogHandler
的框架。在配置标准日志库时,您需要设置一些重要细节,例如日志的名称、想要捕获的日志类型(stdout、stderr、debug)以及日志的目标位置(任何兼容 OTLP 的后端)。之后,在应用程序中调用这些 logger 时,日志将带着已配置的属性发送到指定的目标位置。
以下是使用 OpenTelemetry Logging SDK 对 Python 应用程序进行检测的示例。
import logging
from opentelemetry.sdk._logs import LogEmitterProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogProcessor, ConsoleLogExporter, OTLPLogExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
from opentelemetry.sdk._logs import set_log_emitter_provider
log_emitter_provider = LogEmitterProvider(resource=Resource.create({"service.name": "my-python-app"}))
# Set the global log emitter provider (this will bridge the Python logging with OpenTelemetry)
set_log_emitter_provider(log_emitter_provider)
# Configure the OTLP exporter (sending to OpenTelemetry-compatible backend)
otlp_exporter = OTLPLogExporter(endpoint="http://greptimedb:4000", insecure=True)
# Add a batch log processor for sending logs asynchronously
log_processor = BatchLogProcessor(otlp_exporter)
log_emitter_provider.add_log_processor(log_processor)
# Optionally, add a ConsoleLogExporter for debugging
# console_exporter = ConsoleLogExporter()
# log_emitter_provider.add_log_processor(BatchLogProcessor(console_exporter))
# Set up logging integration
handler = LoggingHandler(level=logging.INFO, log_emitter_provider=log_emitter_provider)
logging.getLogger().addHandler(handler)
# Example usage of logging with OpenTelemetry bridge
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# Example log message
logger.info("This is an OpenTelemetry log message!")
日志采集器
OpenTelemetry Collector 是一个强大的组件,可用于从各种来源收集、处理和导出日志。它在更复杂的环境或需要更灵活地处理日志时特别有用,缺点是设置过程复杂,并且还涉及之后组件的维护。
以下是使用采集器处理日志的一些关键点:
多功能日志收集
采集器可以从多个来源摄取日志,包括:
通过 OTLP 直接发送的应用程序日志 磁盘上的日志文件 系统日志(例如,syslog) 容器日志(例如,来自 Docker 或 Kubernetes)
处理能力
采集器可以在转发日志之前执行各种操作:
过滤:删除不必要的日志 转换:修改日志结构或内容 添加:向日志添加元数据或属性
多种导出选项
日志可以发送到各种后端,包括:
OpenTelemetry 原生后端 流行的日志系统(例如,Elasticsearch、Splunk) 云服务(例如,AWS CloudWatch、Google Cloud Logging)
可扩展性和性能
采集器可以处理高容量的日志,并提供批处理和重试机制等功能,以确保可靠送达。
配置灵活性
可以通过 YAML 配置文件调整采集器的参数设置,无需修改应用程序代码。
以下是日志配置的基本示例:
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
exporters:
logging:
loglevel: debug
otlp:
endpoint: 'otel-collector:4317'
tls:
insecure: true
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [logging, otlp]
上述配置设置了 Log Collector 通过 OTLP 接收日志,再通过批处理提高效率,最后将其导出到日志导出器(用于调试)和另一个 OTLP 端点。
使用 Log Collector 提供了一种集中化的方式来管理整个基础设施中的日志,与直接使用 Log SDK 的方法相比,它在日志处理和路由方面提供了更大的灵活性和控制力。
GreptimeDB 作为 OpenTelemetry 日志采集器
GreptimeDB 是一个云原生时间序列数据库,专为实时、高效的数据存储和分析而设计,尤其适用于可观测性场景。通过对 OpenTelemetry 的原生支持,GreptimeDB 可以作为一个采集器,使用户能够轻松获取、存储和分析可观测数据。这简化了日志管道,同时提供了一个可扩展且强大的监控后端。
有关更多详细信息,请查看 GreptimeDB OpenTelemetry 文档:
https://docs.greptime.com/zh/user-guide/ingest-data/for-observerbility/opentelemetry/
如何选择 Log Collector 和 Log SDK
这两种方式帮助开发人员获取需要的日志,选择哪一种主要取决于环境的复杂性。不妨问问自己:
需要从许多不同的来源收集日志吗? 是否需要额外的步骤转化日志? 是否愿意投入精力来管理额外的组件?
如果需要从多个来源收集日志并需要执行许多复杂操作,建议使用日志收集代理,如 Fluent bit 或 Grafana alloy。否则,如果只想简单地从少数来源收集日志,且开销和复杂性较低,可以尝试日志 SDK。
如果需要帮助设置 OpenTelemetry 的日志管道,请扫描下方二维码添加小助手联系我们的团队,开始收集日志并构建更具弹性的部署。
❝关于 Greptime
Greptime 格睿科技专注于为可观测、物联网及车联网等领域提供实时、高效的数据存储和分析服务,帮助客户挖掘数据的深层价值。目前基于云原生的时序数据库 GreptimeDB 已经衍生出多款适合不同用户的解决方案,更多信息或 demo 展示请联系下方小助手(微信号:greptime)。
欢迎对开源感兴趣的朋友们参与贡献和讨论,从带有 good first issue 标签的 issue 开始你的开源之旅吧~期待在开源社群里遇见你!添加小助手微信即可加入“技术交流群”与志同道合的朋友们面对面交流哦~
Star us on GitHub Now: https://github.com/GreptimeTeam/greptimedb
官网:https://greptime.cn/
文档:https://docs.greptime.cn/Twitter: https://twitter.com/Greptime
Slack: https://greptime.com/slack
LinkedIn: https://www.linkedin.com/company/greptime/
往期精彩文章:
点击「阅读原文」,立即体验 GreptimeDB!








