一个轻量级的 Python 服务指标采集库,支持动态 Hook 和 Prometheus 指标输出
Project description
ms_service_metric
一个轻量级的 Python 服务指标采集库,支持动态 Hook 和 Prometheus 指标输出。
特性
- 🔧 动态 Hook: 基于 YAML 配置动态 Hook 目标函数
- 📊 Prometheus 集成: 支持 Timer、Counter、Gauge、Histogram 等指标类型
- 🔄 动态开关: 通过共享内存和信号实现运行时开关控制
- 🏗️ 框架适配: 内置 vLLM、SGLang 等框架适配器
- 🔍 Locals 访问: 通过字节码注入访问函数局部变量
安装
pip install ms_service_metric
依赖
- Python >= 3.10
- pyyaml
- prometheus-client
- posix_ipc (Linux 平台)
快速开始
1. vLLM 集成
- 通过vllm的插件机制自动集成,无需额外修改代码
- 启动vllm 的多进程metric 采集环境变量
export PROMETHEUS_MULTIPROC_DIR=/dev/shm/vllm_metrics
mkdir -p $PROMETHEUS_MULTIPROC_DIR && rm -rf $PROMETHEUS_MULTIPROC_DIR/*
2. 控制指标采集
# 开启指标采集
ms-service-metric on
# 关闭指标采集
ms-service-metric off
# 重启(重新加载配置)
ms-service-metric restart
# 查看状态
ms-service-metric status
配置
配置文件格式
创建 YAML 配置文件:
# 使用默认 timer handler
- symbol: my_module:MyClass.my_method
metrics:
- name: my_method_duration
type: timer
label:
- name: status
expr: "ret.status if hasattr(ret, 'status') else 'unknown'"
# 使用自定义 handler
- symbol: my_module:process_request
handler: my_handlers:request_handler
need_locals: false
metrics:
- name: request_count
type: counter
expr: "1"
配置项说明
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| symbol | string | 是 | 目标符号路径,格式:module.path:ClassName.method_name |
| handler | string | 否 | 自定义 handler 路径,格式:module.path:function_name |
| min_version | string | 否 | 最小版本要求 |
| max_version | string | 否 | 最大版本要求 |
| need_locals | bool | 否 | 是否需要访问局部变量,默认 false |
| metrics | list | 否 | 指标配置列表 |
Metrics 配置
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 指标名称 |
| type | string | 是 | 指标类型:timer/counter/gauge/histogram |
| expr | string | 否 | 表达式(非 timer 类型必填) |
| label | list | 否 | 标签配置 |
| buckets | list | 否 | 直方图分桶(histogram 类型) |
环境变量
| 变量名 | 说明 | 默认值 |
|---|---|---|
| MS_SERVICE_METRIC_CONFIG_PATH | 配置文件路径 | 无 |
| MS_SERVICE_METRIC_SHM_PREFIX | 共享内存前缀 | /ms_service_metric |
| MS_SERVICE_METRIC_MAX_PROCS | 最大进程数 | 1000 |
| PROMETHEUS_MULTIPROC_DIR | 多进程指标目录 | 无 |
Handler 类型
Wrap Handler
包装函数类型,需要手动调用原函数:
def my_wrap_handler(ori_func, *args, **kwargs):
# 前置处理
start_time = time.time()
# 调用原函数
result = ori_func(*args, **kwargs)
# 后置处理
duration = time.time() - start_time
print(f"Duration: {duration}")
return result
Context Handler
上下文管理器类型,使用 yield 控制执行流程。根据参数签名自动判断是否需要访问局部变量:
不需要 locals(1个参数):
def simple_context_handler(ctx):
# ctx: FunctionContext 对象
# ctx.return_value: 返回值(yield 后可用)
# 前置处理
start_time = time.time()
yield # 原函数在这里执行
# 后置处理
duration = time.time() - start_time
print(f"Duration: {duration}")
print(f"Result: {ctx.return_value}")
需要 locals(2个参数):
def advanced_context_handler(ctx, local_values):
# ctx: FunctionContext 对象
# local_values: 函数的locals字典
# 前置处理
print(f"Locals before: {local_values}")
yield # 原函数在这里执行
# 后置处理
print(f"Result: {ctx.return_value}")
print(f"Locals after: {local_values}")
自动检测 need_locals
系统通过检查 handler 函数的参数签名自动判断是否需要 locals:
| 参数个数 | 含义 | 处理方式 |
|---|---|---|
| 1个参数 (ctx) | 不需要 locals | 封装成 wrap handler |
| 2个参数 (ctx, local_values) | 需要 locals | 走字节码注入 |
默认 Handler: 根据配置中是否存在 expr 字段自动决定:
- 有
expr:创建 2 参数 handler(需要 locals) - 无
expr:创建 1 参数 handler(不需要 locals)
配置示例:
# 不需要 locals(自动检测)
- symbol: my_module:simple_function
handler: my_handlers:simple_handler # 1个参数
# 需要 locals(自动检测)
- symbol: my_module:complex_function
handler: my_handlers:advanced_handler # 2个参数,第二个参数名包含"local"
metrics:
- name: processed_items
type: counter
expr: "len(items)" # items 是函数内的局部变量
# 默认 handler 自动检测(有 expr,需要 locals)
- symbol: my_module:another_function
metrics:
- name: item_count
type: counter
expr: "len(items)" # 存在 expr,自动创建 2 参数 handler
多 Handler 组合
同一个 symbol 可以配置多个 handler,按洋葱模型执行:
- symbol: my_module:process
handler: handlers:auth_check
- symbol: my_module:process
handler: handlers:timing
metrics:
- name: process_duration
type: timer
执行顺序:auth_check -> timing -> 原函数 -> timing -> auth_check
框架适配
vLLM
from ms_service_metric.adapters.vllm import initialize_vllm_metric
# 初始化
initialize_vllm_metric()
内置 V1 版本配置,自动 hook vLLM 关键函数。
SGLang
from ms_service_metric.adapters.sglang import initialize_sglang_metric
# 初始化
initialize_sglang_metric()
自定义适配器
from ms_service_metric.core import SymbolHandlerManager
class MyAdapter:
def __init__(self):
self._manager = SymbolHandlerManager()
def initialize(self, config_path: str):
self._manager.initialize(config_path)
def shutdown(self):
self._manager.shutdown()
API 参考
核心模块
SymbolHandlerManager
核心管理类,管理所有 Symbol 和 Handler。
from ms_service_metric.core import SymbolHandlerManager
manager = SymbolHandlerManager()
manager.initialize(config_path="path/to/config.yaml")
# 检查状态
if manager.is_enabled():
print("Metrics collection is enabled")
# 获取统计信息
stats = manager.get_stats()
print(f"Symbols: {stats['symbol_count']}")
print(f"Handlers: {stats['handler_count']}")
# 关闭
manager.shutdown()
Handler
Handler 包装类,表示一个 Hook 处理函数。
from ms_service_metric.core import MetricHandler
# 从配置创建MetricHandler
handler = MetricHandler.from_config({
'name': 'my_handler',
'handler': 'my_module:my_func',
'metrics': [{'name': 'duration', 'type': 'timer'}]
}, 'module.path:Class.method')
# 获取属性
print(handler.id) # 唯一标识符
print(handler.name) # 名称
# 获取hook函数
target = some_function # 目标函数
handler_type, hook_func = handler.get_hook_func(target)
print(handler_type) # 类型 (WRAP/CONTEXT)
MetricsManager
Prometheus 指标管理器。
from ms_service_metric.core import get_metrics_manager, MetricType
manager = get_metrics_manager()
# 设置前缀
manager.metric_prefix = "my_app"
# 注册指标
manager.register_metric(
name="request_duration",
metric_type=MetricType.TIMER,
description="Request duration in seconds",
label_names=["method", "status"]
)
# 记录指标
manager.record_metric(
name="request_duration",
value=0.5,
labels={"method": "GET", "status": "200"}
)
工具模块
ExprEval
表达式求值器,支持在运行时计算表达式。
from ms_service_metric.utils import ExprEval
evaluator = ExprEval("len(items) * 2")
result = evaluator({"items": [1, 2, 3]}) # 返回 6
支持的变量:
ret: 函数返回值duration: 执行耗时(秒)- 函数局部变量(通过
need_locals获取)
开发
安装开发依赖
pip install -e ".[dev]"
运行测试
pytest tests/
代码风格
black ms_service_metric/
flake8 ms_service_metric/
架构
┌─────────────────────────────────────────────────────────────┐
│ SymbolHandlerManager │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ SymbolConfig│ │SymbolWatcher│ │ MetricConfigWatch │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────┐ │
│ │ Symbol │ │
│ └───────────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Handler │ │Handler │ │Handler │ │
│ └────────┘ └────────┘ └────────┘ │
│ │ │ │ │
│ └───────────┼───────────┘ │
│ ▼ │
│ ┌───────────┐ │
│ HookHelper │ │
│ └───────────┘ │
│ │ │
│ ▼ │
│ ┌───────────┐ │
│ Target Func │ │
│ └───────────┘ │
└─────────────────────────────────────────────────────────────┘
详细设计请参考 DESIGN.md。
许可证
Apache License 2.0
贡献
欢迎提交 Issue 和 Pull Request。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ms_service_metric-0.0.1a1.tar.gz.
File metadata
- Download URL: ms_service_metric-0.0.1a1.tar.gz
- Upload date:
- Size: 75.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58a154585225967a4bc3f76e02d51c1f59c7bad4a9b1208492b10e0e9307447f
|
|
| MD5 |
3a7e2eec06e9fdadb21b46003f8d603c
|
|
| BLAKE2b-256 |
c014db854acd515abcb1581126d4430ef9bc9358c3eaa6aa7a163cfc7e0441b7
|
File details
Details for the file ms_service_metric-0.0.1a1-py3-none-any.whl.
File metadata
- Download URL: ms_service_metric-0.0.1a1-py3-none-any.whl
- Upload date:
- Size: 96.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3898ec05d4e800e551be6dae172649c1d89a273598d781163675f287bd5583ad
|
|
| MD5 |
565f14b0b5372a901e779e0fedeb453c
|
|
| BLAKE2b-256 |
c95c0795be277e0b8b7001af14756b552d1ec8cfd23e39e1cca7a26489d4f87e
|