跳到主要内容

2 篇博文 含有标签「指标采集」

查看所有标签

APO使用场景之:统一的指标采集展示

· 阅读需 11 分钟
Autopilot Observability
APO 向导式可观测性平台

Cover 图

可观测性领域中的指标一直都占有非常重要的地位。Prometheus生态目前已经是事实上的标准,但是实际用户在落地Prometheus的时候可能存在以下的问题:

  • 虽然生态中有各种成熟的Exporter,但是各种Exporter的安装配置相对而言比较繁琐,管理比较麻烦
  • 跨集群的指标数据汇聚相对而言比较麻烦,很多时候需要二次开发,没有简单配置即可工作的工具
  • Prometheus 原生数据存储在大数据量时不稳定,业界有着很好的类似VictorioMetrics方案,但是很多人还未尝试使用
  • 业界也存在过万好评的大屏,能够更好体现指标价值,对于很多用户而言可能并不了解

在APO中能够很好的解决以上的问题,已经将指标生态的各种产品进行很好的整合。

Grafana Alloy介绍

Alloy是Grafana 发布替代之前Grafana Agent的开源产品。

简单的官方介绍:

“Grafana Alloy 是一个开源的 OpenTelemetry Collector 发行版,内置 Prometheus 管道,并支持度量、日志、追踪和性能剖析。”

更为详细的官方介绍:

“Alloy 为 OTel、Prometheus、Pyroscope、Loki 以及许多其他指标、日志、追踪和分析工具提供了原生管道。此外,您可以使用 Alloy 管道执行各种任务,例如在 Loki 和 Mimir 中配置警报规则。Alloy 完全兼容 OTel Collector、Prometheus Agent 和 Promtail。您可以将 Alloy 作为这些解决方案的替代方案,或将其与多个收集器和代理结合成混合系统。您可以在 IT 基础设施的任何地方部署 Alloy,并将其与 Grafana LGTM 堆栈、Grafana Cloud 的遥测后端或任何其他供应商的兼容后端配对。Alloy 灵活多变,您可以轻松配置以满足本地部署、仅云部署或两者结合的需求。”

APO是如何使用Grafana Alloy

从Grafana Alloy的官方介绍中可以看出Alloy很强大,但APO并未使用Alloy所有的功能,主要使用以下两个功能:

  • 集成管理各种Prometheus的exporter的功能,有兴趣的朋友可以翻之前文章介绍了如何使用Alloy一键配置完成exporter的指标采集
  • 管道功能:跨云,跨集群,跨网段的指标采集之后要传输到统一可观测性后台展示

集成管理Prometheus各种exporter功能

通过简单配置即可完成exporter的配置、安装部署:比如通过以下的配置,即可实现ElasticSearch 的exporter的部署和采集

# 采集 elasticsearch指标
prometheus.exporter.elasticsearch "example" {
address = "http://<elasticsearch-url>:9200"
basic_auth {
username = USERNAME
password = PASSWORD
}
}

prometheus.scrape "mysql" {
targets = prometheus.exporter.elasticsearch.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

数据的管道功能

管道功能,数据可以通过OpenTelemetry的collector完成数据的跨集群、跨网络、跨云的传输。

数据流向:

Alloy(采集指标)-> Otel Collector (网络边界)->(网络边界) Otel Collector -> VictoriaMetric

管道功能核心的逻辑在于通过简单配置OTEL collector

  • recievier
  • exporter

配置示例:

边缘侧 Collector 配置(负责接收指标并发送到中心 Collector):

边缘侧 Collector 将通过 OTLP 接收指标数据,并通过 OTLP 发送到中心侧 Collector。

配置示例(边缘侧 Collector):

receivers:
otlp:
protocols:
grpc: # 支持 gRPC 和 HTTP 协议
http:

exporters:
otlp:
endpoint: "http://center-collector:4317" # 中心 Collector 的接收地址
metrics:
resource_to_telemetry_conversion:
enabled: true # 将资源级信息转换为 Telemetry 数据

service:
pipelines:
metrics:
receivers: [otlp] # 从应用接收 OTLP 格式的指标数据
exporters: [otlp] # 导出到中心 Collector

中心侧 Collector 配置(负责从边缘侧 Collector 接收指标并写入存储系统):

中心侧 Collector 将通过 OTLP 接收边缘侧 Collector 发来的指标数据,并将其导出到最终的存储后端。

配置示例(中心侧 Collector):

yaml


Copy code
receivers:
otlp:
protocols:
grpc:
http:

exporters:
prometheus:
endpoint: "http://prometheus:9090/metrics" # Prometheus 的接收地址
namespace: "otel_metrics"

service:
pipelines:
metrics:
receivers: [otlp] # 从边缘侧 Collector 接收 OTLP 格式的指标数据
exporters: [prometheus] # 导出到 Prometheus

配置说明:

1.边缘侧 Collector:

  • receivers: 使用 otlp 接收应用程序发送的指标数据,支持 gRPC 和 HTTP 协议。
  • exporters: 使用 otlp 导出数据,endpoint 是中心侧 Collector 的接收地址。

2.中心侧 Collector:

  • receivers: 使用 otlp 从边缘侧 Collector 接收指标数据。
  • xporters: 使用 prometheus 将数据导出到VictorioMetrics。

APO如何看待Alloy其它功能

  • Alloy集成Loki而来的日志能力,在实际使用日志场景中可能不够用,实际日志都要完成非结构化转化成结构化这一步骤,但是Loki在此方向并不擅长
  • Pyroscope等Continues Profiling的数据目前在OpenTelemetry生态并未完全成熟,即便能够使用Alloy完成数据的采集,但是如何传输,存储,展示都成为问题,还有很多问题等着解决

Alloy的exporter集成能力是经过grafana agent项目能力沉淀而来,坑相对而言比较少。APO在实际使用Alloy也踩了些坑,通过不断调整配置,相信未来也会越来越稳定。

VictorioMetrics的使用

VM已经成为很多公司存储指标的首选,主要是相比prometheus其它生态产品而言

架构简洁性:

  • VictoriaMetrics: VictoriaMetrics 集群版的架构较为简单,支持单一二进制文件启动,减少了复杂的集群管理工作。它既可以用作单机部署,也可以扩展为分布式集群,支持水平扩展,且维护相对简单。

  • Thanos/Cortex: 这两者的架构相对复杂,通常需要多个组件(如 Querier、Store Gateway、Compactor 等)协同工作,且往往涉及到对象存储(如 S3、GCS 等)来进行长期存储。因此,它们的配置、部署和维护难度较高,适合需要长时间数据保留的大规模集群。

高效存储和压缩:

  • VictoriaMetrics: 其高效的数据压缩和存储引擎使其在处理大量数据时更加节省存储空间。它采用自定义的存储格式和时间序列压缩算法,特别擅长处理大规模高频率的时间序列数据。

  • Thanos/Cortex: 这两者依赖于 Prometheus 的存储块和外部对象存储来处理长时间的数据保留,并通过外部系统进行压缩。虽然通过对象存储解决了长期存储问题,但这种方式带来的延迟和复杂性较高,尤其是在查询大量历史数据时,可能会受到网络和存储系统性能的影响。

性能和查询速度:

  • VictoriaMetrics: 由于其优化的存储引擎和索引机制,VictoriaMetrics 在长时间范围的查询场景中通常表现更好。它可以处理大规模数据的高性能写入和快速查询,即使在单节点场景下也能保持良好的表现。

  • Thanos/Cortex: 这两者的查询性能取决于集群的规模和外部存储的读写性能,尤其在跨多个 Prometheus 实例进行查询时,由于依赖对象存储,查询速度相对较慢。此外,Cortex 使用分区和多租户设计,虽然增强了灵活性,但在某些场景下也会引入查询延迟。

完全兼容 Prometheus API:

VictoriaMetrics 完全兼容 Prometheus 的查询语言(PromQL)和数据采集接口,能够无缝替代 Prometheus,且支持从 Prometheus、Thanos、InfluxDB 等系统中直接导入数据,迁移成本低。

指标的统一展示

当各种prometheus exporter的数据存储在VictorioMetrics之中,可以利用生态已有的Grafana大屏直接展示,感谢StarsLiao的贡献,在其贡献的大屏中,有很多已经成为众多公司的选择,很多大屏有着上万的好评。APO中很多大屏都引入了大佬的作品。

1 图

2 图


总结

APO利用Prometheus和OpenTelemetry的成熟生态成果,快速完成指标的采集、传输和统一展示。虽然这些能力并不是APO的核心价值,但也是可观测性平台的核心支柱能力,也欢迎用户先将APO当成指标的采集、传输和统一展示的工具,当系统越来越复杂,需要集成Trace、日志等能力之时,用户可以不用迁移平台。

APO介绍:

国内开源首个 OpenTelemetry 结合 eBPF 的向导式可观测性产品

apo.kindlingx.com

https://github.com/CloudDetail/apo

APO 集成生态exporter一键完成指标采集

· 阅读需 8 分钟
Kindling-OriginX
故障根因推理引擎

Cover 图

Metrics 作为可观测性领域的三大支柱之一,Metrics数据采集显得尤为重要。传统的prometheus工具采集指标,需要指定路径抓取,当指标越来越多配置会显得复杂。同时prometheus只能采集指定的指标,当用户需要节点系统相关、中间件等指标还需要引进额外组件。久而久之采集指标配置难以维护。

APO 为了用户更好地一键采集各类指标,选择 Grafana-Alloy 作为APO的指标采集器,兼容OpenTelemtry生态,集成到 APO OneAgent之中,APO OneAgent负责采集所有指标,发送至APO-Server,存储至Victoria-Metrics, APO-front负责展示所有指标。当需要额外采集数据,只需配置OneAgent中Alloy数据采集源,无需更改其他组件,配置灵活,简单易懂。

图 1


APO 指标采集配置步骤

安装APO-Agent之时,已经安装自带安装了grafana-Alloy。APO启动之后 APO Server并对外提供服务,OneAgent抓取指标,然后发送到 Server,可以在APO Front中的Grafana查看数据。

当用户想要修改指标采集配置,修改 apo-grafana-alloy-config ConfigMap即可(虚机环境下修改apo配置文件config/grafana-alloy/config.alloy)

采集的配置步骤如下:

  1. 配置APO-server地址
  2. 配置apo-grafana-alloy-config文件
  3. grafana查询指标

APO server地址配置

首先需要配置APO Server地址,OneAgent采集指标后将数据发送到APO Server

    otelcol.receiver.prometheus "default" {
output {
metrics = [otelcol.exporter.otlp.default.input]
}
}

otelcol.exporter.otlp "default" {
client {
endpoint = "<host-ip>:<port>"
tls {
insecure = true
insecure_skip_verify = true
}
}
}

配置说明:其中 receiver 接收 prometheus 指标,转换成 otel 格式,然后exporter导出发送至APO-Server

APO缺采集配置

以kubernetes环境为例,通常一个集群可能存在如下指标需要采集

  • node metrics 节点机器系统相关指标 (磁盘,cpu等信息)
  • kubelet metrics 提供 node 和 Pod 的基本运行状态和资源使用情况
  • cadvisor metrics container相关的详细资源使用和性能指标数据

机器相关指标采集

    jsprometheus.exporter.unix "local_system" {
}

prometheus.scrape "scrape_metrics" {
targets = prometheus.exporter.unix.local_system.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
scrape_interval = "10s"
}

该组件会采集机器上的各种资源指标

kubernetes 指标采集

其中 discovery.kubernetes 组件负责获取kubernetes信息, APO 这里选择获取node相关的信息

之后采集 kubelet和 cadvisor相关的指标,由于是k8s集群,还需要配置 scheme, bearer_token_file等权限相关信息

discovery.kubernetes "nodes" {
role = "node"
}

prometheus.scrape "kubelet" {
targets = discovery.kubernetes.nodes.targets
scheme = "https"
scrape_interval = "60s"
bearer_token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"
tls_config {
insecure_skip_verify = true
}
clustering {
enabled = true
}
forward_to = [otelcol.receiver.prometheus.default.receiver]
job_name = "integrations/kubernetes/kubelet"
}

prometheus.scrape "cadvisor" {
targets = discovery.kubernetes.nodes.targets
scheme = "https"
scrape_interval = "60s"
bearer_token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"
tls_config {
insecure_skip_verify = true
}
clustering {
enabled = true
}
forward_to = [otelcol.receiver.prometheus.default.receiver]
job_name = "integrations/kubernetes/cadvisor"
metrics_path = "/metrics/cadvisor"
}

scrape指标采集

通常用户还会部署一些自定义的探针程序,用于自定义一些监控指标

只需指定 targets 下的 addres 用于指定采集URL, __metrics__path__自定义采集路径,默认为/metircs

prometheus.scrape "agent_metrics" {
targets = [
{
__address__ = "<scrape-path-1>:<port>",
},
{
__address__ = "<scrape-path-2>:<port>",
__metrics__path__ = "/metrics/agent"
},
{
__address__ = "<scrape-path-3>:<port>",
},
]
forward_to = [otelcol.receiver.prometheus.default.receiver]
scrape_interval = "10s"
}

如采集APO node-agent 指标

APO node-agent 用于采集上下游网络指标和进程启动时间指标,路径为 localhost:9500/metrics

prometheus.scrape "agent_metrics" {
targets = [
{
__address__ = "localhost:9408",
}
]
forward_to = [otelcol.receiver.prometheus.default.receiver]
scrape_interval = "10s"
}

一键采集中间件指标

除了采集基本指标外,用户使用APO还可以根据自己的需求额外配置其他指标采集。

如采集各类 中间件指标 (kafka, redis, mysql, elasticsearch等)

图 2

监控 MySQL

1.OneAgent 的 alloy 配置文件添加如下内容,然后重启 OneAgent

# 采集 mysql指标
prometheus.exporter.mysql "example" {
data_source_name = "username:password@(<mysql-url>:3306)/"
enable_collectors = ["heartbeat", "mysql.user"]
}

prometheus.scrape "mysql" {
targets = prometheus.exporter.mysql.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

2.APO Front 的 Grafana 中导入 MySQL 模版

图 3

3.验证是否有MySQL指标数据

图 4

监控 ElasticSearch

1.OneAgent 的 alloy 配置文件添加如下内容,然后重启 OneAgent

# 采集 elasticsearch指标
prometheus.exporter.elasticsearch "example" {
address = "http://<elasticsearch-url>:9200"
basic_auth {
username = USERNAME
password = PASSWORD
}
}

prometheus.scrape "elasticsearch" {
targets = prometheus.exporter.elasticsearch.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

2.APO Front 的 Grafana 中导入 ElasticSearch 模版

3.验证是否有ElasticSearch指标数据

图 5

监控 Redis

1.OneAgent 的 alloy 配置文件添加如下内容,重启OneAgent

# 采集 redis 指标
prometheus.exporter.redis "example" {
address = "<redis-url>:6379"
}

prometheus.scrape "redis" {
targets = prometheus.exporter.redis.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

2.APO Front 的 Grafana 导入 Redis 模版

3.验证是否有 Redis 指标数据

图 6

监控 Kafka

1.OneAgent 的 alloy 配置文件添加如下内容,重启OneAgent

# 采集 kafka 指标
prometheus.exporter.kafka "example" {
address = "<kafka-url>:9092"
}

prometheus.scrape "kafka" {
targets = prometheus.exporter.kafka.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

2.APO Front 的 Grafana 导入 Kafka 模版

3.验证是否有Kafka 指标数据

图 7


更多指标的采集可以参考Grafana-Alloy的官方文档或者咨询我们

Alloy已经支持如下中间件指标采集:

图8


参考资料

otel-collector

otlp-configgrpc

victora-metrics

Sending data via OpenTelemetry

alloy

discovery.kubernetes

otel.receiver.prometheus

prometheus

样例配置文件

logging {
level = "info"
format = "logfmt"
}


otelcol.receiver.prometheus "default" {
output {
metrics = [otelcol.processor.transform.default.input]
}
}

otelcol.processor.transform "default" {
error_mode = "ignore"
trace_statements {
context = "resource"
statements = [
`replace_all_patterns(attributes, "key", "service\\.instance\\.id", "service_instance_id")`,
`replace_all_patterns(attributes, "key", "service\\.name", "service_name")`,
`replace_all_patterns(attributes, "key", "net\\.host\\.name", "net_host_name")`,
]
}
output {
metrics = [otelcol.exporter.otlp.default.input]
}
}

otelcol.exporter.otlp "default" {
client {
endpoint = "<host-ip>:<port>"
tls {
insecure = true
insecure_skip_verify = true
}
}
}

prometheus.exporter.unix "local_system" {
}

prometheus.scrape "scrape_metrics" {
targets = prometheus.exporter.unix.local_system.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
scrape_interval = "10s"
}

prometheus.scrape "agent_metrics" {
targets = [
{
__address__ = "<scrape-path-1>",
},
{
__address__ = "<scrape-path-2>",
},
{
__address__ = "<scrape-path-3>",
},
]
forward_to = [otelcol.receiver.prometheus.default.receiver]
scrape_interval = "10s"
}

discovery.kubernetes "nodes" {
role = "node"
}

prometheus.scrape "kubelet" {
targets = discovery.kubernetes.nodes.targets
scheme = "https"
scrape_interval = "60s"
bearer_token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"
tls_config {
insecure_skip_verify = true
}
clustering {
enabled = true
}
forward_to = [otelcol.receiver.prometheus.default.receiver]
job_name = "integrations/kubernetes/kubelet"
}

prometheus.scrape "cadvisor" {
targets = discovery.kubernetes.nodes.targets
scheme = "https"
scrape_interval = "60s"
bearer_token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"
tls_config {
insecure_skip_verify = true
}
clustering {
enabled = true
}
forward_to = [otelcol.receiver.prometheus.default.receiver]
job_name = "integrations/kubernetes/cadvisor"
metrics_path = "/metrics/cadvisor"
}


# 采集 mysql指标
prometheus.exporter.mysql "example" {
data_source_name = "username:password@(<mysql-url>:3306)/"
enable_collectors = ["heartbeat", "mysql.user"]
}

// Configure a prometheus.scrape component to send metrics to.
prometheus.scrape "mysql_metrics" {
targets = prometheus.exporter.mysql.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}

# 采集 elasticsearch指标
prometheus.exporter.elasticsearch "example" {
address = "http://<elasticsearch-url>:9200"
basic_auth {
username = USERNAME
password = PASSWORD
}
}

prometheus.scrape "demo" {
targets = prometheus.exporter.elasticsearch.example.targets
forward_to = [otelcol.receiver.prometheus.default.receiver]
}