17、OpenTelemetry Collector 深入解析

OpenTelemetry Collector 深入解析

1. OpenTelemetry Collector 概述

OpenTelemetry Collector 本质上是一个接收各种格式遥测数据、处理数据并将其导出到一个或多个目标的进程。它在遥测数据的来源(如应用程序或节点)和最终存储数据以进行分析的后端之间充当代理。

部署 OpenTelemetry Collector 并非毫无成本,因为它需要额外的资源来运行、操作和监控。不过,部署它有以下好处:
- 解耦遥测数据的来源和目标:开发者可以在应用代码中为遥测数据配置单一目标,而收集器的操作者可以根据需要确定数据的去向,无需修改现有代码。
- 为多种数据类型提供单一目标:收集器可以配置为接收多种不同格式的跟踪、指标和日志,如 OTLP、Jaeger、Zipkin、Prometheus、StatsD 等。
- 减少数据发送到后端的延迟:减轻因事件导致后端无响应时的意外副作用。收集器部署还可以根据需要进行水平扩展以增加容量。
- 修改遥测数据以解决合规性和安全问题:收集器可以通过处理器根据配置中定义的标准过滤数据,从而阻止数据泄露并防止不应包含在遥测数据中的信息被存储在后端。

2. OpenTelemetry Collector 组件理解

收集器允许用户通过组合任意数量的接收器、处理器和导出器为每个信号单独配置管道,这为收集器的使用方式和位置提供了很大的灵活性。

收集器的初始实现是从 OpenCensus Service 派生而来,它支持许多开箱即用的开放协议用于输入和输出。收集器中的每个组件都实现了 Component 接口,该接口非常简洁:

type Component interface {
    Start(ctx context.Context, host Host) error
    Shutdown(ctx context.Context) error
}

这个接口使得实现者可以轻松地向收集器添加额外的组件,使其具有很强的可扩展性。

3. 接收器(Receivers)

管道中的第一个组件是接收器,它接收各种支持格式的数据,并将这些数据转换为收集器内部的数据格式。通常,接收器会注册一个监听器,为其支持的协议在收集器中暴露一个端口。例如,Jaeger 接收器支持以下协议:
| 协议 | 端口 |
| — | — |
| Thrift Binary | 6832 |
| Thrift Compact | 6831 |
| Thrift HTTP | 14268 |
| gRPC | 14250 |

需要注意的是,默认端口值可以通过配置进行覆盖。同一个接收器可以启用多个协议,每个协议默认会监听不同的端口。

接收器可以在多个管道中重复使用,也可以为同一个管道配置多个接收器。以下是一个配置示例,启用了 OTLP gRPC 接收器和 Jaeger Thrift Binary 接收器,并配置了三个单独的管道:

receivers:
  otlp:
    protocols:
      grpc:
  jaeger:
    protocols:
      thrift_binary:
service:
  pipelines:
    traces/otlp:
      receivers: [otlp]
    traces/jaeger:
      receivers: [jaeger]
    traces/both:
      receivers: [otlp, jaeger]

为不同的接收器创建单独的管道在需要对一个管道中的数据进行额外处理而另一个管道不需要时会很有用。接收器的接口也很简洁:

type Receiver interface {
    Component
}
type TracesReceiver interface {
    Receiver
}

这种简单性使得根据需要实现额外的接收器变得容易。

4. 主机指标接收器(Host metrics receiver)

主机指标接收器可以配置为收集运行收集器的主机的指标。它可以配置为抓取 CPU、磁盘、内存和各种其他系统级详细信息的指标。以下示例展示了如何配置主机指标接收器每 10 秒抓取主机的负载、内存和网络信息:

receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      load:
      memory:
      network:
service:
  pipelines:
    metrics:
      receivers: [hostmetrics]

该接收器支持额外的配置,以便你可以包含或排除特定的设备或指标。配置此接收器可以帮助你在不运行额外进程的情况下监控主机的性能。

5. 处理器(Processors)

在将数据传递给导出器之前,对数据执行一些额外的任务(如过滤不需要的遥测数据或注入额外的属性)是有益的,这就是处理器的工作。与接收器和导出器不同,处理器的功能因处理器而异。此外,配置中组件的顺序对处理器很重要,因为数据是从一个处理器串行传递到另一个处理器的。

处理器接口除了嵌入 Component 接口外,还嵌入了一个与正在处理的信号匹配的消费者接口,例如:

type Capabilities struct {
    MutatesData bool
}
type baseConsumer interface {
    Capabilities() Capabilities
}
type Metrics interface {
    baseConsumer
    ConsumeMetrics(ctx context.Context, md pdata.Metrics) error
}
type MetricsProcessor interface {
    Processor
    consumer.Metrics
}

以下是一个配置示例,配置了一个名为 attributes/add-key 的属性处理器来插入一个键为 example-key 的属性并将其值设置为 first,第二个属性处理器 attributes/update-key 将 example-key 属性的值更新为 second:

processors:
  attributes/add-key:
    actions:
      - key: example-key
        action: insert
        value: first
  attributes/update-key:
    actions:
      - key: example-key
        action: update
        value: second
service:
  pipelines:
    traces:
      processors: [attributes/add-key, attributes/update-key]

此配置的预期输出是所有发出的跨度都将 example-key 属性设置为 second。由于处理器的顺序很重要,颠倒上述示例中的处理器将把值设置为 first。

以下是另一个更现实的示例,将一个属性的值从 old-key 复制到 new-key,然后删除 old-key 属性:

processors:
  attributes/copy-and-delete:
    actions:
      - key: new-key
        action: upsert
        from_attribute: old-key
      - key: old-key
        action: delete
service:
  pipelines:
    traces:
      processors: [attributes/copy-and-delete]

这种配置可用于迁移值或合并来自多个系统的数据,其中不同的名称用于表示相同的数据。

处理器涵盖了一系列功能,以下是当前的处理器及其处理的信号列表:
| 处理器 | 处理信号 |
| — | — |
| Attributes processor | 跟踪、指标、日志 |
| Filter processor | 指标 |
| Probabilistic sampling processor | 跟踪 |
| Resource processor | 跟踪、指标、日志 |
| Span processor | 跟踪 |
| Batch processor | 跟踪、指标、日志 |
| Memory limiter processor | 跟踪、指标、日志 |

下面详细介绍几种常见的处理器:
- 属性处理器(Attributes processor) :可用于修改遥测数据属性,支持 delete、extract、hash、insert、update、upsert 等操作。还可以根据 match_type(严格匹配或正则表达式匹配)包含或排除跨度。例如:

processors:
  attributes/include-secret:
    include:
      match_type: strict
      services: ["super-secret", "secret"]
    actions:
      - key: secret-attr
        action: delete

属性处理器在清理个人身份信息(PII)或其他敏感信息时非常有用。
- 过滤处理器(Filter processor) :允许根据配置的标准包含或排除遥测数据。可以配置为使用严格或正则表达式匹配名称,也可以使用匹配属性和名称的表达式。目前,过滤处理器仅支持过滤指标,但社区已请求支持更多信号。
- 概率采样处理器(Probabilistic sampling processor) :可用于减少从收集器导出的跟踪数量,通过指定采样百分比来确定应保留的跟踪百分比。hash_seed 参数用于确定收集器如何对跟踪 ID 进行哈希处理以确定要处理的跟踪:

processors:
  probabilistic_sampler:
    sampling_percentage: 20
    hash_seed: 12345

当多个收集器连接时,hash_seed 配置参数尤为重要。
- 资源处理器(Resource processor) :允许用户修改与遥测数据关联的资源的属性,配置选项与属性处理器相同。例如:

processors:
  resource:
    attributes:
    - key: deployment.environment
      value: staging
      action: upsert
    - key: container.runtime
      from_attribute: runtime
      action: insert
    - key: runtime
      action: delete
  • 跨度处理器(Span processor) :可根据跨度的名称操作跨度的名称或属性。它可以从跨度中提取属性并根据这些属性更新其名称,或者将跨度的名称扩展为与跨度关联的单个属性。例如:
processors:
  span/rename:
    name:
      from_attributes: ["messaging.system", "messaging.operation"]
      separator: ":"
  span/create-attributes:
    name:
      to_attributes:
        rules:
          - ^\/stores\/(?P<storeId>.*)\/.*$
          - ^.*\/orders/(?P<orderId>.*)\/.*$

跨度处理器还支持 include 和 exclude 配置以帮助过滤跨度。
- 批量处理器(Batch processor) :帮助批量处理数据以提高数据传输效率。可以配置为根据批量大小和时间表发送批量数据。例如:

processors:
  batch:
    timeout: 10s # default 200ms
    send_batch_size: 10000 # default 8192
    send_batch_max_size: 11000 # default 0 – no limit

建议为所有管道配置批量处理器以优化收集器的吞吐量。
- 内存限制处理器(Memory limiter processor) :允许用户控制收集器消耗的内存量,确保收集器尽可能避免内存不足。可以通过固定的兆字节值或基于总可用内存计算的百分比来指定限制。如果同时指定了两者,固定值优先。内存限制器强制执行软限制和硬限制,两者的差异由峰值限制配置定义。建议与 ballast 扩展一起使用内存限制器,ballast 扩展允许收集器预先分配内存以提高堆的稳定性。例如:

processors:
  memory_limiter:
    check_interval: 5s
    limit_mib: 250
    spike_limit_mib: 50
extensions:
  memory_ballast:
    size_mib: 125

当处理器超过软限制时,它会返回错误并开始丢弃数据;如果超过硬限制,它还会强制进行垃圾回收以释放内存。内存限制处理器应配置为管道中的第一个处理器,以确保当内存阈值超过时,返回的错误会传播到接收器,从而允许接收器向客户端发送适当的错误代码,客户端可以相应地限制其发送的请求。

6. 导出器(Exporters)

管道的最后一个组件是导出器。导出器在收集器管道中的角色与在 SDK 中的角色非常相似,它将收集器内部格式的数据进行编组,转换为输出格式,并将其发送到一个或多个配置的目标。导出器的接口与处理器接口非常相似,也是一个消费者,按信号进行分离。例如:

type LogsExporter interface {
    Exporter
    consumer.Logs
}

可以根据需要为不同的目标配置同一类型的多个导出器,也可以为同一个管道配置多个导出器以将数据输出到多个位置。以下是一个配置示例,配置了一个 Jaeger 导出器用于导出跟踪,以及一个 OTLP 导出器用于导出跟踪和指标:

exporters:
  jaeger:
    endpoint: jaeger:14250
  otlp:
    endpoint: otelcol:4317
service:
  pipelines:
    traces:
      exporters: [jaeger, otlp]
    metrics:
      exporters: [otlp]

通过合理配置接收器、处理器和导出器,OpenTelemetry Collector 可以高效地处理和导出各种遥测数据,满足不同场景下的监控和分析需求。

OpenTelemetry Collector 深入解析

7. 配置示例与流程总结

为了更好地理解 OpenTelemetry Collector 的使用,下面给出一个完整的配置示例,包含接收器、处理器和导出器的配置,并总结其工作流程。

receivers:
  otlp:
    protocols:
      grpc:
  jaeger:
    protocols:
      thrift_binary:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      load:
      memory:
      network:

processors:
  attributes/add-key:
    actions:
      - key: example-key
        action: insert
        value: first
  attributes/update-key:
    actions:
      - key: example-key
        action: update
        value: second
  attributes/copy-and-delete:
    actions:
      - key: new-key
        action: upsert
        from_attribute: old-key
      - key: old-key
        action: delete
  batch:
    timeout: 10s
    send_batch_size: 10000
    send_batch_max_size: 11000
  memory_limiter:
    check_interval: 5s
    limit_mib: 250
    spike_limit_mib: 50

exporters:
  jaeger:
    endpoint: jaeger:14250
  otlp:
    endpoint: otelcol:4317

service:
  pipelines:
    traces/otlp:
      receivers: [otlp]
      processors: [attributes/add-key, attributes/update-key, batch, memory_limiter]
      exporters: [jaeger, otlp]
    traces/jaeger:
      receivers: [jaeger]
      processors: [attributes/add-key, attributes/update-key, batch, memory_limiter]
      exporters: [jaeger, otlp]
    metrics:
      receivers: [hostmetrics]
      processors: [batch, memory_limiter]
      exporters: [otlp]

其工作流程如下:
1. 数据接收 :接收器(如 OTLP、Jaeger、主机指标接收器)接收各种格式的遥测数据,并将其转换为收集器内部的数据格式。
2. 数据处理 :处理器按照配置的顺序对数据进行处理,如插入或更新属性、批量处理、内存限制等。
3. 数据导出 :导出器将处理后的数据编组为输出格式,并发送到配置的目标(如 Jaeger、OTLP 后端)。

8. 性能优化建议

为了确保 OpenTelemetry Collector 能够高效稳定地运行,以下是一些性能优化建议:
- 使用批量处理器 :为所有管道配置批量处理器,如前面示例所示,通过合理设置超时时间、批量大小和最大批量大小,优化数据传输效率,提高收集器的吞吐量。
- 配置内存限制处理器 :使用内存限制处理器控制收集器的内存消耗,避免因内存不足导致的性能问题。同时,结合 ballast 扩展,预先分配内存以提高堆的稳定性。
- 合理配置接收器和导出器 :根据实际需求选择合适的接收器和导出器,并合理配置其参数。例如,对于高并发场景,可以考虑水平扩展收集器实例。
- 优化处理器顺序 :处理器的顺序会影响数据处理的结果和性能,确保按照逻辑顺序配置处理器,避免不必要的重复处理。

9. 总结

OpenTelemetry Collector 是一个强大的工具,它提供了灵活的配置选项,允许用户根据不同的需求组合接收器、处理器和导出器,实现对各种遥测数据的高效处理和导出。

通过本文的介绍,我们了解了 OpenTelemetry Collector 的基本概念、组件功能、配置方法以及性能优化建议。以下是对各组件的总结表格:
| 组件 | 功能 | 示例配置 |
| — | — | — |
| 接收器 | 接收各种格式的遥测数据并转换为内部格式 | otlp jaeger hostmetrics 接收器配置 |
| 处理器 | 对数据进行过滤、修改、批量处理等操作 | attributes filter batch memory_limiter 等处理器配置 |
| 导出器 | 将处理后的数据编组并发送到目标 | jaeger otlp 导出器配置 |

在实际应用中,我们可以根据具体的监控和分析需求,灵活配置 OpenTelemetry Collector,确保能够准确、高效地收集和处理遥测数据,为系统的性能优化和故障排查提供有力支持。

以下是 OpenTelemetry Collector 工作流程的 mermaid 流程图:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B(数据接收):::process
    B --> C(数据处理):::process
    C --> D(数据导出):::process
    D --> E([结束]):::startend

希望本文能够帮助你更好地理解和使用 OpenTelemetry Collector,在实际项目中发挥其强大的功能。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值