OpenTelemetry 指标
gRPC 中可用的 OpenTelemetry 指标
OpenTelemetry 指标
概述
gRPC 为 OpenTelemetry 插件提供了支持,该插件提供的指标可以帮助您 -
- 排查系统故障
- 迭代改进系统性能
- 设置持续监控和警报。
背景
OpenTelemetry 是一个可观测性框架,用于创建和管理遥测数据。gRPC 以前通过 OpenCensus 提供可观测性支持,但 OpenCensus 已退役,取而代之的是 OpenTelemetry。
仪表
gRPC OpenTelemetry 插件接受一个 MeterProvider,并依赖于 OpenTelemetry API 来创建 Meter,该 Meter 标识正在使用的 gRPC 库,例如版本为 1.57.1
的 grpc-c++
。以下列出的仪表是使用此 Meter 创建的。用户应使用 OpenTelemetry SDK 来自定义 OpenTelemetry 导出的视图。
越来越多的 gRPC 组件正在进行可观测性仪表化。目前,我们已仪表化以下组件 -
- 每次调用:观察 RPC 本身(例如,延迟)。
- 客户端每次调用(稳定,默认开启):观察客户端调用
- 客户端每次尝试(稳定,默认开启):观察客户端调用的尝试,因为一个调用可能因重试或对冲而有多次尝试。
- 客户端每次调用重试(实验性):观察重试、透明重试和对冲,
- 服务器:观察服务器收到的调用。
- LB 策略:观察各种负载均衡策略
- 加权轮询(实验性)
- Pick-First(实验性)
- XdsClient(实验性)
注意 某些仪表默认关闭,需要通过 gRPC OpenTelemetry 插件 API 明确启用。实验性指标始终默认关闭。(参考 C++ API)
每次调用指标
客户端每次调用仪表
名称 | 类型 | 单位 | 标签(必填) | 描述 |
---|---|---|---|---|
grpc.client.call.duration | 直方图 | 秒 | grpc.method, grpc.target, grpc.status | 此指标旨在衡量 gRPC 库从应用程序角度完成 RPC 所花费的端到端时间。 |
详情请参阅 A66: OpenTelemetry 指标。
客户端每次尝试仪表
名称 | 类型 | 单位 | 标签(处置) | 描述 |
---|---|---|---|---|
grpc.client.attempt. started | 计数器 | {attempt} | grpc.method(必填),grpc.target(必填) | 已启动的 RPC 尝试总数,包括尚未完成的尝试。 |
grpc.client.attempt. duration | 直方图 | 秒 | grpc.method(必填),grpc.target(必填),grpc.status(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 完成 RPC 尝试所花费的端到端时间,包括选择子通道的时间。 |
grpc.client.attempt. sent_total_compressed_message_size | 直方图 | 字节 | grpc.method(必填),grpc.target(必填),grpc.status(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 每次 RPC 尝试发送的所有请求消息(不包括元数据)的总字节数(已压缩但未加密);不包括 gRPC 或传输帧字节。 |
grpc.client.attempt. rcvd_total_compressed_message_size | 直方图 | 字节 | grpc.method(必填),grpc.target(必填),grpc.status(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 每次 RPC 尝试接收的所有响应消息(不包括元数据)的总字节数(已压缩但未加密);不包括 gRPC 或传输帧字节。 |
详情请参阅 A66: OpenTelemetry 指标。
客户端每次调用重试仪表
名称 | 类型 | 单位 | 标签(必填) | 描述 |
---|---|---|---|---|
grpc.client.call.retries | 直方图 | {retry} | grpc.method, grpc.target | 客户端调用期间的重试次数。如果没有重试,则不报告 0。 |
grpc.client.call.transparent_retries | 直方图 | {transparent_retry} | grpc.method, grpc.target | 客户端调用期间的透明重试次数。如果没有透明重试,则不报告 0。 |
grpc.client.call.hedges | 直方图 | {hedge} | grpc.method, grpc.target | 客户端调用期间的对冲次数。如果没有对冲,则不报告 0。 |
grpc.client.call.retry_delay | 直方图 | 秒 | grpc.method, grpc.target | 在客户端调用期间没有活动尝试时的总延迟时间。 |
详情请参阅 A96: OTel 重试指标。
服务器仪表
名称 | 类型 | 单位 | 标签(必填) | 描述 |
---|---|---|---|---|
grpc.server.call. started | 计数器 | {call} | grpc.method | 已启动的 RPC 总数,包括尚未完成的 RPC。 |
grpc.server.call. sent_total_compressed_message_size | 直方图 | 字节 | grpc.method, grpc.status | 每次 RPC 发送的所有响应消息(不包括元数据)的总字节数(已压缩但未加密);不包括 gRPC 或传输帧字节。 |
grpc.server.call. rcvd_total_compressed_message_size | 直方图 | 字节 | grpc.method, grpc.status | 每次 RPC 接收的所有请求消息(不包括元数据)的总字节数(已压缩但未加密);不包括 gRPC 或传输帧字节。 |
grpc.server.call. duration | 直方图 | 秒 | grpc.method, grpc.status | 此指标旨在衡量 RPC 从服务器传输(HTTP2/inproc)角度所花费的端到端时间。 |
详情请参阅 A66: OpenTelemetry 指标。
LB 策略仪表
加权轮询 LB 策略仪表
名称 | 类型 | 单位 | 标签(处置) | 描述 |
---|---|---|---|---|
grpc.lb.wrr. rr_fallback | 计数器 | {update} | grpc.target(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 实验性:调度程序更新中没有足够具有有效权重的端点,导致 WRR 策略回退到 RR 行为的次数。 |
grpc.lb.wrr. endpoint_weight_not_yet_usable | 计数器 | {endpoint} | grpc.target(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 实验性:每个调度程序更新中尚未具有可用权重信息(即,尚未收到负载报告,或在停用期内)的端点数量。 |
grpc.lb.wrr. endpoint_weight_stale | 计数器 | {endpoint} | grpc.target(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 实验性:每个调度程序更新中最新权重比过期时间更早的端点数量。 |
grpc.lb.wrr. endpoint_weights | 直方图 | {weight} | grpc.target(必填),grpc.lb.locality(可选),grpc.lb.backend_service(可选) | 实验性:每个调度程序更新记录的端点权重。 |
详情请参阅 A78: WRR、Pick First 和 XdsClient 的 gRPC OTel 指标。
Pick First LB 策略仪表
名称 | 类型 | 单位 | 标签(必填) | 描述 |
---|---|---|---|---|
grpc.lb.pick_first. disconnections | 计数器 | {disconnection} | grpc.target | 实验性:选定子通道断开连接的次数。 |
grpc.lb.pick_first. connection_attempts_succeeded | 计数器 | {attempt} | grpc.target | 实验性:成功连接尝试的次数。 |
grpc.lb.pick_first. connection_attempts_failed | 计数器 | {attempt} | grpc.target | 实验性:失败连接尝试的次数。 |
详情请参阅 A78: WRR、Pick First 和 XdsClient 的 gRPC OTel 指标。
XdsClient 仪表
名称 | 类型 | 单位 | 标签(必填) | 描述 |
---|---|---|---|---|
grpc.xds_client. connected | 测量仪 | {bool} | grpc.target, grpc.xds.server | 实验性:xDS 客户端当前是否与 xDS 服务器有正常工作的 ADS 流。 |
grpc.xds_client. server_failure | 计数器 | {failure} | grpc.target, grpc.xds.server | 实验性:xDS 服务器从健康变为不健康的计数器。 |
grpc.xds_client. resource_updates_valid | 计数器 | {resource} | grpc.target, grpc.xds.server, grpc.xds.resource_type | 实验性:接收到的被视为有效的资源计数器,即使未更改。 |
grpc.xds_client. resource_updates_invalid | 计数器 | {resource} | grpc.target, grpc.xds.server, grpc.xds.resource_type | 实验性:接收到的被视为无效的资源计数器。 |
grpc.xds_client. resources | 测量仪 | {resource} | grpc.target, grpc.xds.authority, grpc.xds.cache_state, grpc.xds.resource_type | 实验性:xDS 资源的数量。 |
详情请参阅 A78: WRR、Pick First 和 XdsClient 的 gRPC OTel 指标。
标签/属性
对于仪表的记录测量值,gRPC 可能会提供一些附加信息作为属性或标签。例如,grpc.client.attempt.started
具有标签 grpc.method
和 grpc.target
,以及每个测量值,它们告诉我们与被观察的 RPC 尝试相关联的方法和目标。
注意 某些属性在仪表上标记为可选。这些需要从 gRPC OpenTelemetry 插件 API 明确启用。(参考 C++ API)
名称 | 描述 |
---|---|
grpc.method | 完整的 gRPC 方法名称,包括包、服务和方法,例如“google.bigtable.v2.Bigtable/CheckAndMutateRow”。 |
grpc.status | 收到的 gRPC 服务器状态码,例如“OK”、“CANCELLED”、“DEADLINE_EXCEEDED”。 |
grpc.target | 创建 gRPC 通道时使用的规范化目标 URI,例如“dns:///pubsub.googleapis.com:443”、“xds:///helloworld-gke:8000”。 |
grpc.lb.backend_service | 流量发送到的后端服务。当单个通道目标可以发送到不同的服务器集合时,这很重要。使用 xDS 时,这将是集群名称。不相关时,该值将为空字符串。 |
grpc.lb.locality | 流量发送到的区域。 |
grpc.xds.server | 对于客户端,表示 XdsClient 所在的 gRPC 通道的目标。对于服务器,将是字符串“#server”。 |
grpc.xds.authority | xDS 权威。对于旧式非 xdstp 资源名称,该值为“#old”。 |
grpc.xds.cache_state | 指示 xDS 资源的缓存状态(“requested”、“does_not_exist”、“acked”、“nacked”、“nacked_but_cached”)。 |
grpc.xds.resource_type | xDS 资源类型,例如“envoy.config.listener.v3.Listener”。 |
常见问题
Q. 如何获取吞吐量或 QPS(每秒查询数)?
在延迟直方图指标上使用计数聚合 - grpc.client.attempt.duration
/ grpc.client.call.duration
(对于客户端)或 grpc.server.call.duration
(对于服务器)。
Q. 如何获取 RPC 的错误率?
错误计数可以通过在延迟直方图指标 grpc.client.attempt.duration
/ grpc.client.call.duration
(对于客户端)或 grpc.server.call.duration
(对于服务器)上使用过滤器 grpc.status != OK
值来计算。
语言示例
语言 | 示例 |
---|---|
C++ | C++ 示例 |
Go | Go 示例 |
Java | Java 示例 |
Python | Python 示例 |