tRPC-Python 在生态系统中提供 Prometheus,并且提供了抽象基类 BaseMetrics(注册类型为 PluginType.METRICS)供业务或第三方插件扩展。
需要注意以下两点机制:
- 不自动解析 YAML 配置:框架不会读取
trpc_python.yaml中的plugins.metrics段。仅在配置文件里编写metrics配置不会自动实例化插件,也不会将其设为默认监控实现。 - 门面转发与激活:监控上报的入口位于
trpc_sdk.telemetry(推荐直接从包顶层导入:from trpc_sdk.telemetry import get_metrics, report_attr, set_default_metrics)。在显式调用set_default_metrics绑定默认实例之前,所有report_*函数都会直接返回False。
trpc_sdk.telemetry 提供了四个上报函数。当已设置默认监控实例时,它们会将调用转发给该实例;否则直接返回 False:
report_active(active_data, call_result):主调侧(客户端)调用监控上报。report_passive(passive_data, call_result):被调侧(服务端)调用监控上报。report_attr(key, value, policy=StatPolicy.SUM):属性指标上报。report_custom(data):自定义多维监控数据上报。
框架内部调用情况:
- 目前框架内部(如 codec 收到非法魔数、transport 发生连接错误、runtime 检测到子进程退出等场景)已经接入了
report_attr。一旦业务调用了set_default_metrics,这些内部指标就会自动进入你的插件。 report_active、report_passive和report_custom在框架内部暂无默认调用点,业务代码或自定义拦截器可以根据需要主动调用门面函数进行上报。
监控相关的数据结构定义在 trpc_sdk/abc/_metrics.py 中:
ActiveData:主调侧维度信息,包含active_service、passive_service、passive_ip、ret_code等字段。PassiveData:被调侧维度信息,包含active_service、passive_service、passive_interface、ret_code等字段。CallResult:调用结果,其中status为ReportStatus枚举(SUCCESS = 0、EXCEPTION = 1、TIMEOUT = 2),time为耗时(单位:毫秒)。StatPolicy:统计策略字符串枚举,支持SUM、AVG、MAX、MIN、SET、HISTOGRAM。调用report_attr不传policy时默认为StatPolicy.SUM。CustomData:自定义监控数据,包含name、dimensions、stat_values、tags。其中stat_values的元素为StatValue(包含value、count、policy)。
四个 report_* 抽象方法的返回值类型均为 bool,成功接收样本时返回 True。
下面实现一个最小化的内存监控插件,将上报的样本保存在内存列表中,不依赖外部监控系统。注意 BaseMetrics 的四个抽象方法必须全部实现,否则无法实例化:
from trpc_sdk.abc import ActiveData
from trpc_sdk.abc import BaseMetrics
from trpc_sdk.abc import CallResult
from trpc_sdk.abc import CustomData
from trpc_sdk.abc import PassiveData
from trpc_sdk.abc import PluginType
from trpc_sdk.abc import StatPolicy
from trpc_sdk.plugin import register_plugin
from trpc_sdk.telemetry import get_metrics
from trpc_sdk.telemetry import set_default_metrics
@register_plugin(PluginType.METRICS, "memory")
class MemoryMetrics(BaseMetrics):
def __init__(self):
super().__init__()
self.active = []
self.passive = []
self.attrs = []
self.custom = []
def report_active(self, active_data: ActiveData, call_result: CallResult) -> bool:
self.active.append((active_data, call_result))
return True
def report_passive(self, passive_data: PassiveData, call_result: CallResult) -> bool:
self.passive.append((passive_data, call_result))
return True
def report_attr(self, key: str, value: float, policy: StatPolicy) -> bool:
self.attrs.append((key, value, policy))
return True
def report_custom(self, data: CustomData) -> bool:
self.custom.append(data)
return True
def install() -> MemoryMetrics:
metrics = get_metrics("memory")
set_default_metrics(metrics)
return metrics- 通过
get_metrics获取单例:@register_plugin仅将类注册到插件表中。首次调用get_metrics("memory")(等价于get_plugin(PluginType.METRICS, "memory"))时,插件管理器才会构造实例并依次调用其init()和start()。请直接将该返回值传给set_default_metrics(metrics);如果自己额外执行MemoryMetrics()传入,会导致门面持有的对象与插件表中的单例不一致。 - 生效时机与多进程说明:在调用
install()前,需确保定义插件的模块已被import。由于每个 Worker 子进程各自维护独立的默认监控实例,需要在实际产生上报的进程中(通常在开始处理请求前)执行install()。无需在 YAML 中编写plugins.metrics。 - 验证上报:执行
install()后,调用report_attr("demo", 1)即可在metrics.attrs中看到记录;业务侧也可以构造ActiveData和CallResult并调用report_active完成主调上报。