暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用 OpenTelemetry 简化日志管理 - 如何获取、解析和存储日志

GreptimeDB 2025-01-15
435

OpenTelemetry (OTel) 是一个专为监控应用程序运行状况而设计的开源标准。通过收集指标、日志、追踪数据,它提供了系统运行情况的全面视图,帮助运维团队快速识别和解决问题。

在我们之前的文章:《云原生运维入门必看!OpenTelemetry 三大数据类型及核心组件解析》中,我们介绍了 OTel 的不同组件及其协同方式。

在本文中,我们将重点关注日志数据,这是系统监测最重要的指标之一。日志对于理解系统内的事件至关重要,它提供了操作的详细时间戳记录。然而,日志的非结构化特点增加了分析日志数据的难度。针对这点, OpenTelemetry 的标准化 Log Data Model 提供了一个结构化框架,使得获取、查询和分析日志更简单。

在 OpenTelemetry 中获取日志

日志是开发人员了解系统内发生事件最常用的数据,其本质上是非结构化的数据流,可以让开发人员灵活地发送应用程序状态数据。但是由于缺乏结构化,开发一款用于捕获、解析和保存日志的标准化工具变得相当困难。

而这些问题恰恰可以被 OpenTelemetry Log Data Model 很好地解决。其标准化结构能帮助用户对每个日志的上下文进行更深入的理解,解答关于日志是何时、何地、为何以及如何发出的问题。

Log Data Model 类型及示例问题

Field NameDescription
TimestampTime when the event occurred.
ObservedTimestampTime when the event was observed.
TraceIdRequest trace id.
SpanIdRequest span id.
TraceFlagsW3C trace flag.
SeverityTextThe severity text (also known as log level).
SeverityNumberNumerical value of the severity.
BodyThe body of the log record.
ResourceDescribes the source of the log.
InstrumentationScopeDescribes the scope that emitted the log.
AttributesAdditional information about the event.
  1. Tracing 上下文

TraceId
SpanId
字段将日志与分布式跟踪关联起来,使开发人员能够跟踪请求在多个服务中的路径。

◦ 示例问题:在某个特定用户交易时还发生了哪些事件?

  1. 时间信息

Timestamp
ObservedTimestamp
字段回答了事件何时发生以及处理时间多久的问题。

◦ 示例问题:事件发生和在系统中被观察到之间是否有延迟?

  1. 严重性和重要性

SeverityText
SeverityNumber
字段能够按严重性过滤日志,并指定处理日志的优先级。

◦ 示例问题:在过去一小时内发生了多少严重错误?

  1. 上下文属性

Attributes
字段允许添加自定义键值对,提供额外的上下文。

◦ 示例问题:与此错误相关的用户 ID 是什么?

  1. 源标识

Resource
字段有助于识别日志的来源(例如,哪个服务、主机或容器)

◦ 示例问题:哪个特定微服务生成的错误最多?

  1. Instrumentation 详情

InstrumentationScope
字段提供有关生成日志的库或模块的信息。

◦ 示例问题:是否有来自特定第三方库的错误模式?

  1. 灵活的消息内容

Body
字段包括了结构化或非结构化的日志消息,支持传统的日志记录和更现代的结构化日志记录方法。

◦ 示例问题:我们在小部件服务中看到的最常见错误是什么?

通过遵循这一模型,日志不仅仅是简单的文本记录,它们变成了丰富的、可查询的数据点。通过与其他遥测数据(如追踪和指标)轻松关联,日志能够提供对系统行为和性能的全面视图。

将日志转换为 Log Data Model

(图 1:OpenTelemetry 数据流程)

日志 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 是一个强大的组件,可用于从各种来源收集、处理和导出日志。它在更复杂的环境或需要更灵活地处理日志时特别有用,缺点是设置过程复杂,并且还涉及之后组件的维护。

以下是使用采集器处理日志的一些关键点:

  1. 多功能日志收集

采集器可以从多个来源摄取日志,包括:

  • 通过 OTLP 直接发送的应用程序日志
  • 磁盘上的日志文件
  • 系统日志(例如,syslog)
  • 容器日志(例如,来自 Docker 或 Kubernetes)
  1. 处理能力

采集器可以在转发日志之前执行各种操作:

  • 过滤:删除不必要的日志
  • 转换:修改日志结构或内容
  • 添加:向日志添加元数据或属性
  1. 多种导出选项

日志可以发送到各种后端,包括:

  • OpenTelemetry 原生后端
  • 流行的日志系统(例如,Elasticsearch、Splunk)
  • 云服务(例如,AWS CloudWatch、Google Cloud Logging)
  1. 可扩展性和性能

采集器可以处理高容量的日志,并提供批处理和重试机制等功能,以确保可靠送达。

  1. 配置灵活性

可以通过 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!

文章转载自GreptimeDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论