ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Litestar Prometheus 插件实战:基于 ASGI 中间件的指标采集与配置指南

2026/9/16 17:51:58 拓冰建站 浏览量
Litestar Prometheus 插件实战:基于 ASGI 中间件的指标采集与配置指南 Litestar Prometheus 插件实战基于 ASGI 中间件的指标采集与配置指南【免费下载链接】litestarLight, flexible and extensible ASGI framework | Built to scale项目地址: https://gitcode.com/GitHub_Trending/li/litestar导读本文围绕 Litestar 内置的可选 Prometheus 导出器位于litestar.plugins.prometheus展开讲解如何通过中间件对 HTTP/WebSocket 请求进行全自动埋点并在/metrics端点暴露 Prometheus 格式或 OpenMetrics 格式的指标数据。读完本文你将掌握从安装依赖、快速接入、参数化配置到多进程部署gunicorn/uwsgi 等的完整方案并能理解请求计数、耗时直方图、并发量与错误计数四大类指标的底层采集原理。说明本文对应的 API 参考文档为 docs/reference/plugins/prometheus.rst其内容经 Sphinxautomodule从源码自动生成因此本文以该模块的源码litestar/plugins/prometheus、官方使用指南 docs/usage/metrics/prometheus.rst 与单元测试 tests/unit/test_plugins/test_prometheus.py 为依据对其 API 与行为进行系统性解读。一、安装依赖该插件是对prometheus-client的封装使用时必须先安装依赖两种方式任选其一# 方式一单独安装 prometheus-client pip install prometheus-client # 方式二作为 Litestar 的 extra 一起安装 pip install litestar[prometheus]从源码看三个模块文件config.py、middleware.py、controller.py顶部都通过try: import prometheus_client检测依赖若未安装会抛出MissingDependencyException(prometheus_client, prometheus-client, prometheus)提示你需要补装依赖。因此缺少依赖时应用会在导入阶段直接失败而不是运行时报错。二、快速开始三步接入litestar.plugins.prometheus对外暴露三个公开 API见init.pyPrometheusConfig中间件配置类负责生成DefineMiddleware实例PrometheusMiddlewareASGI 中间件实现负责采集请求指标PrometheusController内置的指标导出控制器默认挂载在/metrics路径。最小可用示例对应官方示例 using_prometheus_exporter.pyfrom litestar import Litestar from litestar.plugins.prometheus import PrometheusConfig, PrometheusController def create_app(group_path: bool True) - Litestar: # 默认 app_name 和 prefix 均为 litestar prometheus_config PrometheusConfig(group_pathgroup_path) # 默认情况下指标以 Prometheus 文本格式暴露在 /metrics 路径 # 如需修改路径或切换 OpenMetrics 格式可子类化 PrometheusController return Litestar( route_handlers[PrometheusController], middleware[prometheus_config.middleware], )核心流程只有两步创建PrometheusConfig实例通过prometheus_config.middleware属性返回DefineMiddleware包装的中间件见 config.py注册到Litestar(..., middleware[...])并把PrometheusController注册为路由处理器。启动应用后访问http://localhost:8000/metrics即可看到采集到的指标文本。三、PrometheusConfig 配置项全解PrometheusConfig是一个dataclass定义于 config.py所有参数均有默认值直接PrometheusConfig()即可使用默认配置。下表汇总了全部配置项及其语义配置项类型默认值说明app_namestrlitestar指标中使用的应用名作为默认标签app_name的值prefixstrlitestar指标名称前缀例如litestar_requests_totallabelsMapping[str, str \| Callable] \| NoneNone附加到指标的自定义标签值可以是常量字符串也可以是接收Request并返回字符串的可调用对象exemplarsCallable[[Request], dict] \| NoneNone返回示例exemplar字典的可调用对象仅 OpenMetrics 文本格式支持bucketsSequence[str \| float] \| NoneNone耗时直方图Histogram的自定义桶边界不传时使用 prometheus-client 默认桶excluded_http_methodsMethod \| Sequence[Method] \| NoneNone需要从指标中排除的 HTTP 方法如[POST]exclude_unhandled_pathsboolFalse是否忽略未处理路径上的请求指标excludestr \| list[str] \| NoneNone要从指标中排除的路由模式单个或列表exclude_opt_keystr \| NoneNone路由处理器opt中的键名处理器设置该键后可以退出opt-out中间件scopesScopes \| NoneNone中间件处理的 ASGI scope为None时同时处理http与websocketmiddleware_classtype[PrometheusMiddleware]PrometheusMiddleware使用的中间件类允许子类替换group_pathboolTrue是否将路径分组以规避标签基数cardinality爆炸其中值得展开说明的几个参数prefix与app_nameprefix直接决定指标名的前缀。从 middleware.py 可见四个指标名分别拼接为{prefix}_requests_total、{prefix}_request_duration_seconds、{prefix}_requests_in_progress、{prefix}_requests_error_totalapp_name则作为默认标签app_name的值出现在每条序列中。group_path默认开启。开启后路径标签不再取真实 URL 路径而是取request.scope[path_template]即路由模板如/users/{user_id}从而把同一路由的所有请求聚合到一条时间序列上。单元测试 test_prometheus.py 验证了这一点连续请求/users/1、/users/2、/users/3后指标中只有path/users/{user_id}这一条序列且计数为 3而不会出现path/users/1等。若关闭该选项参数化路由的每个不同实参都会产生独立时间序列容易造成基数爆炸建议保持默认开启。excluded_http_methods被排除的方法会直接透传见 middleware.py不做任何指标记录。scopes中间件基于AbstractMiddleware实现scopes、exclude、exclude_opt_key均透传给父类见 middleware.py行为与 Litestar 其他中间件一致。四、高级配置示例官方示例 using_prometheus_exporter_with_extra_configs.py 演示了如何组合使用上述配置项from collections.abc import Callable from typing import Any from litestar import Litestar, Request from litestar.plugins.prometheus import PrometheusConfig, PrometheusController # 通过子类化修改指标路径并切换为 OpenMetrics 格式 class CustomPrometheusController(PrometheusController): path /custom-path openmetrics_format True # 自定义标签值可以是字符串也可以是可调用对象接收 Request 返回字符串 def custom_label_callable(request: Request[Any, Any, Any]) - str: return v2.0 extra_labels: dict[str, str | Callable[[Request[Any, Any, Any]], str]] { version_no: custom_label_callable, location: earth, } # 自定义直方图桶边界单位秒 buckets [0.1, 0.2, 0.3, 0.4, 0.5] # 附加 exemplar仅 OpenMetrics 格式支持 def custom_exemplar(request: Request[Any, Any, Any]) - dict[str, str]: return {trace_id: 1234} prometheus_config PrometheusConfig( app_namelitestar-example, prefixlitestar, labelsextra_labels, bucketsbuckets, exemplarscustom_exemplar, excluded_http_methods[POST], ) app Litestar( route_handlers[CustomPrometheusController], middleware[prometheus_config.middleware], )示例中的关键点自定义标签labels的值可以是常量如location: earth也可以是可调用对象如custom_label_callable。源码中_get_extra_labelsmiddleware.py对每个值做str(v(request) if callable(v) else v)处理即在每次请求时动态求值。自定义直方图桶buckets会以关键字参数buckets...传给Histogram构造器middleware.py。exemplar仅在使用 OpenMetrics 文本格式openmetrics_format True时生效Prometheus 文本格式下会被忽略其值以exemplar关键字传入inc()/observe()middleware.py。单元测试 test_prometheus.py 验证了输出形如litestar_requests_total{...} 1.0 # {trace_id1234} 1.0。自定义路径与格式PrometheusController的两个类属性path默认/metrics与openmetrics_format默认False可在子类中覆盖。切换 OpenMetrics 格式后控制器会使用prometheus_client.openmetrics.exposition.generate_latest生成指标并设置对应的Content-Type见 controller.py。五、默认指标一览中间件在 middleware.py 中定义了四类指标名称均以prefix开头默认litestar指标名类型说明{prefix}_requests_totalCounter累计请求总数{prefix}_request_duration_secondsHistogram请求耗时秒直方图支持自定义桶{prefix}_requests_in_progressGauge当前正在处理的请求数{prefix}_requests_error_totalCounter请求错误累计数仅状态码 ≥ 500 时递增每条序列默认携带四个标签见_get_default_labelsmiddleware.pymethodHTTP 方法对 WebSocket 连接则为websocketpathgroup_pathTrue时为路由模板如/users/{user_id}否则为真实路径status_code响应状态码app_name配置的app_name。六、源码级原理中间件如何工作PrometheusMiddleware继承自AbstractMiddleware其核心逻辑在__call__方法middleware.py执行流程如下方法过滤若请求方法命中excluded_http_methods直接透传不记录任何指标构造标签合并默认标签与自定义标签自定义标签优先并发量递增requests_in_progress.inc()代理 send用_get_wrapped_send包装 ASGIsend函数在http.response.start消息中捕获真实状态码在http.response.body消息中记录结束时间并计算耗时middleware.py异常兜底捕获HTTPException以记录其真实状态码如 401/403/404捕获其他异常统一记为 500然后重新抛出见 middleware.py。单元测试 test_prometheus.py 专门验证了 401、403、500 以及通用异常如ValueError的状态码记录行为收尾上报在finally中递减requests_in_progress写入最终status_code并分别递增requests_error_total仅 ≥500 时、requests_total以及向直方图observe耗时。注意一个细节指标对象本身缓存在类级字典PrometheusMiddleware._metrics中middleware.py因此即使配置实例多次创建同一名称的指标也只会注册一次避免重复注册冲突在测试环境中如需重置需手动清空该字典并注销 prometheus_client 默认 REGISTRY 中的收集器见测试辅助函数create_configtest_prometheus.py。七、多进程部署与 OpenMetrics 支持多进程gunicorn/uwsgi 等场景PrometheusController.get在响应时检测环境变量prometheus_multiproc_dir或PROMETHEUS_MULTIPROC_DIRcontroller.py。若已设置则改用CollectorRegistry()multiprocess.MultiProcessCollector(registry)聚合各 worker 的指标这正是官方推荐的多进程部署方式。单元测试 test_prometheus.py 验证了该分支会以MultiProcessCollector(registry)的方式被调用。同时requests_in_progress仪表在定义时设置了multiprocess_modelivesummiddleware.py确保多进程下并发量能正确求和。OpenMetrics 文本格式子类化PrometheusController并设置openmetrics_format True即可切换。该格式由 prometheus-client 的openmetrics.exposition模块生成除文本结构不同外还支持输出 exemplar示例适合与分布式追踪如 trace_id关联的场景。八、接入 Prometheus 与 Grafana应用接入后在 Prometheus 配置文件的scrape_configs中加入抓取目标即可开始采集scrape_configs: - job_name: litestar metrics_path: /metrics static_configs: - targets: [localhost:8000]建议在 Grafana 中基于以下 PromQL 建立常用面板请求 QPSsum(rate(litestar_requests_total[5m])) by (method, path)请求耗时 P95histogram_quantile(0.95, sum(rate(litestar_request_duration_seconds_bucket[5m])) by (le, path))错误率sum(rate(litestar_requests_error_total[5m])) by (path) / sum(rate(litestar_requests_total[5m])) by (path)当前并发sum(litestar_requests_in_progress)九、实战建议与注意事项保持group_pathTrue除非路由数量极少且不包含参数化路径否则建议开启路径分组避免标签基数爆炸拖垮 Prometheus 存储。合理设置直方图桶默认桶覆盖 5ms10s 的常见范围若接口延迟集中在特定区间可通过buckets自定义以获得更精细的分位估算。/metrics自身的监控从测试可见requests_in_progress在抓取/metrics的瞬间可能显示为 1.0test_prometheus.py属正常现象。生产环境建议将/metrics端点与业务端口分离或用exclude排除内部监控路径。排除无关流量用excluded_http_methods排除OPTIONS等预检请求用exclude/exclude_opt_key排除健康检查等路径可显著降低指标基数与写入量。多进程部署必须设置prometheus_multiproc_dir并确保该目录对所有 worker 可见、可写否则多 worker 进程各自的计数器无法正确聚合。exemplar 仅在 OpenMetrics 格式下生效若使用默认的 Prometheus 文本格式exemplars配置不会产生任何输出。至此你已经掌握了 Litestar Prometheus 插件从安装、接入、参数配置到原理剖析与生产部署的完整链路。如需查阅更底层的实现细节可继续阅读 litestar/plugins/prometheus/middleware.py、litestar/plugins/prometheus/controller.py 以及 tests/unit/test_plugins/test_prometheus.py。【免费下载链接】litestarLight, flexible and extensible ASGI framework | Built to scale项目地址: https://gitcode.com/GitHub_Trending/li/litestar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考