webman暴露/metrics端点需单例collectorregistry、标准openmetrics文本格式(#help开头,name{label} value timestamp)、响应头content-type: text/plain; version=0.0.4,且禁止多worker重复初始化或传入非法标签。

Webman 本身不直接提供指标采集和可视化能力,要集成 Grafana 展示业务监控大屏,本质是让 Webman 暴露可观测指标(如请求量、响应时间、错误率),再由 Prometheus 抓取,最后在 Grafana 中建模展示。这不是“Webman 插件式接入”,而是标准的云原生监控链路。
Webman 如何暴露 Prometheus 兼容的 metrics 端点
Webman 没有内置 metrics 中间件,需手动实现或借助 workerman/metrics 扩展。核心是注册一个 HTTP 路由,返回符合 Prometheus 文本格式的指标数据(Content-Type: text/plain; version=0.0.4)。
- 推荐使用
workerman/metrics:安装后在启动文件中调用Metric::init(),并注册路由如/metrics,它会自动聚合连接数、请求计数、响应延迟直方图等基础指标 - 自定义业务指标必须手动注册:例如用
Metric::counter('api_login_total', 'login success count')记录登录次数,并在登录逻辑中调用Metric::inc('api_login_total') - 注意:所有指标名、标签值必须符合 Prometheus 命名规范(只含字母、数字、下划线,不能以数字开头),否则
prometheus抓取时会报invalid metric name - 不要在控制器里实时计算耗时指标——应在中间件或全局事件钩子(如
onWorkerStart)中初始化计数器/直方图,否则高并发下会严重拖慢响应
Grafana 中配置 Webman 指标数据源与查询
确保 Prometheus 已将 Webman 的 /metrics 端点加入 scrape_configs,并在 Grafana 中添加该 Prometheus 为数据源后,才能开始写查询。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 面板查询语言必须用 PromQL,不是 SQL 或 JS:例如查每秒登录请求数,写
rate(api_login_total[1m]),不是SELECT COUNT(*) FROM logs - 标签过滤要带引号:想看特定环境的指标,写
api_login_total{env="prod"},漏掉引号会导致语法错误 - 避免直接展示原始计数器:
api_login_total是单调递增的,应始终配合rate()、increase()或sum by()使用,否则图表会是一条垂直上升的直线 - Webman 的 HTTP 延迟指标默认是直方图类型(
http_request_duration_seconds_bucket),要用histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[1m])) by (le))计算 P95 延迟
Webman 日志如何进 Grafana(非 metrics 场景)
如果想把 Webman 的 access log 或 error log 推送到 Grafana,不能走 Prometheus(它不处理日志),得用 Loki + Promtail 链路。
- Webman 日志需输出到文件(如
runtime/log/app.log),且格式尽量结构化(JSON 最佳),避免纯文本解析困难 - Promtail 配置中,
scrape_configs的static_config必须指向 Webman 日志路径,并用pipeline_stages提取字段(如status_code、uri) - Grafana 查询 Loki 时,用 LogQL:例如查 5xx 错误,写
{job="webman"} | json | status_code >= 500;若没启用json解析器,只能用正则|~ "5\d\d",但不可靠 - Loki 不支持复杂聚合(如按 URI 分组统计 404 次数),这类需求得回退到 ELK 或用 Grafana + Prometheus + 自定义 exporter 折中实现
真正卡住人的地方不在 Webman 侧,而在于 Prometheus 抓取间隔(scrape_interval)和 Grafana 刷新频率的错配——比如设了 15s 抓取,却在 Grafana 里用 1s 刷新面板,结果看到的是重复旧数据或空白。这个细节没有文档会强调,但实际调试时八成问题出在这儿。









