English | 中文
tRPC-Python provides Prometheus in the ecosystem, and the abstract base class BaseMetrics (registration type PluginType.METRICS) for business code or third-party plugins to extend.
Two mechanisms to keep in mind:
- YAML is not parsed automatically. The framework does not read the
plugins.metricssection oftrpc_python.yaml. Writing ametricssection does not instantiate the plugin, and it does not set it as the default implementation. - Facade forwarding and activation. The reporting entry is
trpc_sdk.telemetry. Import from the package:from trpc_sdk.telemetry import get_metrics, report_attr, set_default_metrics. Untilset_default_metricsbinds a default instance, everyreport_*function returnsFalse.
trpc_sdk.telemetry provides four report functions. When a default metrics instance is set, they forward the call to that instance. Otherwise they return False:
report_active(active_data, call_result): caller-side (client) metrics.report_passive(passive_data, call_result): callee-side (server) metrics.report_attr(key, value, policy=StatPolicy.SUM): attribute metrics.report_custom(data): custom multi-dimensional metrics.
What the framework calls:
- The framework already calls
report_attr, for example an illegal magic number in the codec, a connection error in transport, and a child process exit in the runtime. After business code callsset_default_metrics, those internal metrics enter the plugin. report_active,report_passive, andreport_customhave no default call sites inside the framework. Business code or a custom filter can call the facade when it needs to report.
The definitions are in trpc_sdk/abc/_metrics.py.
ActiveData: caller-side dimensions, includingactive_service,passive_service,passive_ip, andret_code.PassiveData: callee-side dimensions, includingactive_service,passive_service,passive_interface, andret_code.CallResult: the call result.statusisReportStatus:SUCCESS = 0,EXCEPTION = 1,TIMEOUT = 2.timeis milliseconds.StatPolicy: a string enum:SUM,AVG,MAX,MIN,SET,HISTOGRAM. Whenreport_attromitspolicy, the policy isStatPolicy.SUM.CustomData: custom metrics data, withname,dimensions,stat_values, andtags. An element ofstat_valuesis aStatValue(value,count,policy).
All four report_* methods return bool. Accepting the sample returns True.
The plugin below keeps reported samples in memory and does not depend on an external metrics system. All four abstract methods of BaseMetrics must be implemented, or the class cannot be instantiated:
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- Take the singleton from
get_metrics.@register_pluginonly puts the class into the plugin table. The first call toget_metrics("memory")(the same asget_plugin(PluginType.METRICS, "memory")) constructs the instance and runsinit()andstart(). Pass that return value toset_default_metrics(metrics). Constructing anotherMemoryMetrics()and passing it in gives the facade an object that is not the singleton in the plugin table. - When it takes effect, and multiple processes. Import the module that defines the plugin before calling
install(). Each worker process keeps its own default metrics instance, so callinstall()in the process that actually reports, usually before it starts handling requests. Do not write aplugins.metricssection in YAML. - Check that reports land. After
install(),report_attr("demo", 1)shows up inmetrics.attrs. Business code can also buildActiveDataandCallResultand callreport_active.