动态指标
以往我们做一些服务器上的指标数据统计,比如某个域名的访问量最高的 10 个客户端地址,某个域名的缓存命中率,则需要服务器将全量的指标数据上报到监控系统,再在监控系统中数据的聚合计算。
而动态指标功能支持以类似 SQL 语法的 Metric SQL 编写聚合规则,在服务器上高效地实时聚合计算得到统计数据,大大地减少了需要上报的数据量。Metric SQL 的语法可以参考这个文档:Metric SQL
。
动态指标的统计数据目前支持以 Lua API 和 Prometheus Exporter 的方式导出。
这里我们提供一个统计请求状态码分布的实际例子。
创建动态指标
选择新建动态指标,名称填写为 status-distribution,指标聚合上报间隔为 60 秒,SQL 内容如下:
select count(*) from reqs group by status;
导出动态指标
点击编译按钮,然后可以从下面的编译历史中下载编译后的 zip 压缩包。
压缩包中包含以下这些文件,解压后复制到 nginx.conf
中指定的 lua_package_path
目录下。
Archive: Tool-1-dymetrics-status-distribution.zip
Length Date Time Name
--------- ---------- ----- ----
2383 01-26-2022 17:12 dymetrics.ljbc
0 01-26-2022 17:12 metrics/
59638 01-26-2022 17:12 metrics/status-distribution.ljbc
此外,在列表页也可以通过多选的方式来导出多个动态指标。
修改 nginx.conf 配置
动态指标需要修改 nginx.conf 配置才能使用,在 http block
内添加动态指标配置,示例是推荐配置的大小,可以根据实际情况调整。同时动态指标还依赖 openresty-yajl
,还需要在 lua_package_cpath
加上 openresty-yajl
的路径。
lua_shared_dict dymetrics_keys 1m;
lua_shared_dymetrics dymetrics 100m;
lua_package_cpath "/usr/local/openresty-yajl/lib64/;./?.so;;";
添加动态指标初始化代码
在 init_worker
阶段进行初始化,需要提供一个回调函数。指标每个统计周期完成后会调用这个函数,在这里将统计数据回传。
init_worker_by_lua_block {
local report_func = function (data)
-- `data` is the result of the metric statistics
end
require "dymetrics" .init_worker(report_func)
}
添加动态指标采集入口
在 log_by_lua_block
阶段添加采集入口。
log_by_lua_block {
require "dymetrics" .collect()
}
添加 Prometheus Exporter 接口
Prometheus 的数据可以从这个接口导出。
location /prometheus {
content_by_lua_block {
require "dymetrics" .prometheus()
}
}
完整的 nginx.conf
worker_processes auto;
events {
worker_connections 1024;
}
http {
lua_package_path "$prefix/lua/?.lua;;";
lua_package_cpath "$prefix/lualib/?.so;/usr/local/openresty-yajl/lib64/?.so;;";
sendfile on;
keepalive_timeout 65;
lua_shared_dict dymetric_version 1m;
lua_shared_dymetrics dymetrics 100m;
init_worker_by_lua_block {
local report_func = function (data)
-- do nothing
end
require "dymetrics" .init_worker(report_func)
}
server {
listen 127.0.0.1:80;
server_name localhost;
location / {
root html;
index index.html index.htm;
log_by_lua_block {
require "dymetrics" .collect()
}
}
location /prometheus {
content_by_lua_block {
require "dymetrics" .prometheus()
}
}
}
}