推荐使用OpenResty + lua-resty-prometheus方案:在access_by_lua_block中读取ngx.var.args长度并用Histogram暴露,需启用lua_need_request_body且限制采样阈值;次选日志解析方案,用$request_length近似或扩展exporter提取args长度。

直接采集请求参数大小(如 query string 长度、body 大小)及分布直方图,Nginx 原生不支持,需结合 nginx-module-vts(已停更)、nginx-prometheus-exporter(外部解析日志)或自定义 Lua 模块(推荐)。核心思路是:在 Nginx 请求处理阶段提取参数长度,用 Prometheus Histogram 类型暴露分位数统计。
✅ 方案一:OpenResty + lua-resty-prometheus(最灵活)
适用于 OpenResty 环境,可精确控制采集逻辑:
- 在
access_by_lua_block或log_by_lua_block中读取ngx.var.args(query string)和ngx.var.request_body(需开启lua_need_request_body on;) - 计算长度(单位:byte),避免大 body 导致性能问题,建议只对 GET/POST 小请求采样或加长度阈值限制(如 ≤ 10KB)
- 使用
lua-resty-prometheus创建 Histogram,例如:local hist = metric:histogram("nginx_request_args_bytes", "Query string length in bytes", {0.1, 100, 1000, 5000, 10000})
然后调用hist:observe(#ngx.var.args) - 注意:request_body 默认为空,需配置
client_max_body_size和启用lua_need_request_body on;生产环境慎用 full-body,可用ngx.req.get_body_data()获取原始体,或仅统计Content-Length头
✅ 方案二:Nginx 日志 + prometheus-logstash-exporter(免改 Nginx 配置)
适合标准 Nginx,通过日志字段间接采集:
- 自定义 log_format,加入参数长度变量:
log_format with_args_length '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $args_length';
其中$args_length需用map指令生成:map $args $args_length { default ${#args}; }(⚠️ 注意:Nginx 官方不支持字符串长度内置变量,此写法无效;实际需用lua_map或放弃该字段) - 更可行做法:用
$request_length(整个请求行+头+body 总长)近似代替,或用 Logstash 解析$request提取?key=value后截取 query 部分再算长度 - 配合 prometheus-logstash-exporter 或自研日志 parser,将日志中提取的长度字段转为 Histogram 指标上报
✅ 方案三:nginx-prometheus-exporter + 自定义日志解析(轻量级)
官方推荐 exporter,但默认不解析参数长度,需扩展:
- 启用 Nginx 的
log_format输出 query string 长度(需 OpenResty 或 patch Nginx 支持$args_length) - 或修改
nginx-prometheus-exporter源码,在日志解析器中添加正则提取args=.*?并计算长度,映射到 histogram metric - 启动 exporter 时指定自定义日志格式和指标名:
--web.listen-address=:9113 --nginx.scrape-uri=http://localhost:8080/stub_status --nginx.exported-metrics-file=/etc/nginx/exporter-metrics.yaml
? 关键提醒
直方图 bucket 设置要合理:
- query string 通常较短(0–2KB),建议 buckets:
[10, 50, 100, 500, 1000, 2000] - request body 差异大,按业务定(如 API:0.1K, 1K, 10K, 100K;上传服务:100K, 1M, 10M)
- 避免 bucket 过密或过疏,否则
histogram_quantile()查询结果失真 - Prometheus 默认每 15s 抓一次,高频小请求下 histogram 样本量充足;低频请求建议延长 scrape interval 或用 Summary 类型替代
不复杂但容易忽略:参数长度统计必须区分 GET(args 在 URL)和 POST(args 可能在 body 或 URL),且空参数、编码字符(如 %20)计入原始字节长度。真实场景优先监控 $request_length + 单独采样 query/body 分布,比强求“精确 args 长度”更稳定实用。











