nginx-lua-prometheus
Nginx 的 Prometheus 指标库
$ opm get knyar/nginx-lua-prometheus
[!覆盖率状态](https://coveralls.io/github/knyar/nginx-lua-prometheus?branch=master)
Nginx 的 Prometheus 指标库
这是一个 Lua 库,可与 Nginx 一起使用,用于跟踪指标并在单独的网页上公开它们,以便 Prometheus 获取。
安装
要使用此库,您需要 [ngx_lua]( https://github.com/openresty/lua-nginx-module) nginx 模块。您可以使用支持 Lua 的基于 Nginx 的服务器,如 OpenResty,或使用启用该模块的常规 Nginx 服务器:例如,在 Debian 10 上,您可以简单地安装 libnginx-mod-http-lua
(但如果您使用的是更高版本的 Debian,请阅读 [已知问题]( #known-issues))。
库文件 - prometheus.lua
- 需要在 LUA_PATH
中可用。如果这是您唯一使用的 Lua 库,您只需将 lua_package_path
指向检出此 git 存储库的目录(请参阅下面的示例)。
OpenResty 用户将在 opm 中找到此库。它也可以通过 luarocks 获得。
快速入门指南
要跟踪按服务器名称细分的请求延迟以及按服务器名称和状态细分的请求计数,请将以下内容添加到 nginx.conf
的 http
部分
lua_shared_dict prometheus_metrics 10M;
lua_package_path "/path/to/nginx-lua-prometheus/?.lua;;";
init_worker_by_lua_block {
prometheus = require("prometheus").init("prometheus_metrics")
metric_requests = prometheus:counter(
"nginx_http_requests_total", "Number of HTTP requests", {"host", "status"})
metric_latency = prometheus:histogram(
"nginx_http_request_duration_seconds", "HTTP request latency", {"host"})
metric_connections = prometheus:gauge(
"nginx_http_connections", "Number of HTTP connections", {"state"})
}
log_by_lua_block {
metric_requests:inc(1, {ngx.var.server_name, ngx.var.status})
metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.server_name})
}
这
为您的指标配置一个名为
prometheus_metrics
的共享字典,大小限制为 10MB;注册一个名为
nginx_http_requests_total
的计数器,它有两个标签:host
和status
;注册一个名为
nginx_http_request_duration_seconds
的直方图,它有一个标签host
;注册一个名为
nginx_http_connections
的仪表盘,它有一个标签state
;在每个 HTTP 请求上测量其延迟,将其记录在直方图中并递增计数器,将当前服务器名称设置为
host
标签,将 HTTP 状态码设置为status
标签。
最后一步是配置一个单独的服务器,它将公开这些指标。请确保它只能从您的 Prometheus 服务器访问
server {
listen 9145;
allow 192.168.0.0/16;
deny all;
location /metrics {
content_by_lua_block {
metric_connections:set(ngx.var.connections_reading, {"reading"})
metric_connections:set(ngx.var.connections_waiting, {"waiting"})
metric_connections:set(ngx.var.connections_writing, {"writing"})
prometheus:collect()
}
}
}
指标将在 http://your.nginx:9145/metrics
上可用。请注意,此示例中的仪表盘指标包含从 nginx 全局状态获得的值,因此它们在指标返回给客户端之前立即设置。
API 参考
init()
语法: require("prometheus").init(dict_name, [options]])
初始化模块。这应该从 nginx 配置的 init_worker_by_lua_block 部分调用一次。
dict_name
是用于存储所有指标的 nginx 共享字典的名称。如果未指定,默认为prometheus_metrics
。options
是可以提供的配置选项表。接受的选项是prefix
(字符串):指标名称前缀。此字符串将在输出时添加到指标名称之前。error_metric_name
(字符串):可用于更改错误指标的默认名称(有关详细信息,请参阅 "内置指标")。sync_interval
(数字):设置每个工作线程的计数器和键索引的同步间隔(以秒为单位)。这将为计数器指标递增以及指标重置/删除设置最终一致性的边界。默认为 1。
返回一个 prometheus
对象,该对象应该用于注册指标。
示例
init_worker_by_lua_block {
prometheus = require("prometheus").init("prometheus_metrics", {sync_interval=3})
}
prometheus:counter()
语法: prometheus:counter(name, description, label_names)
注册一个计数器。应该从 [init_worker_by_lua_block]( https://github.com/openresty/lua-nginx-module#init_worker_by_lua_block) 部分为每个计数器调用一次。
name
是指标的名称。description
是将与指标一起呈现给 Prometheus 的文本描述。可选(如果您仍然需要定义标签名称,则传递nil
)。label_names
是指标的标签名称数组。可选。
Prometheus 文档的命名部分 提供了有关选择指标和标签名称的良好指南。
返回一个 counter
对象,该对象以后可以递增。
示例
init_worker_by_lua_block {
prometheus = require("prometheus").init("prometheus_metrics")
metric_bytes = prometheus:counter(
"nginx_http_request_size_bytes", "Total size of incoming requests")
metric_requests = prometheus:counter(
"nginx_http_requests_total", "Number of HTTP requests", {"host", "status"})
}
prometheus:gauge()
语法: prometheus:gauge(name, description, label_names)
注册一个仪表盘。应该从 [init_worker_by_lua_block]( https://github.com/openresty/lua-nginx-module#init_worker_by_lua_block) 部分为每个仪表盘调用一次。
name
是指标的名称。description
是将与指标一起呈现给 Prometheus 的文本描述。可选(如果您仍然需要定义标签名称,则传递nil
)。label_names
是指标的标签名称数组。可选。
返回一个 gauge
对象,该对象以后可以设置。
示例
init_worker_by_lua_block {
prometheus = require("prometheus").init("prometheus_metrics")
metric_connections = prometheus:gauge(
"nginx_http_connections", "Number of HTTP connections", {"state"})
}
prometheus:histogram()
语法: prometheus:histogram(name, description, label_names, buckets)
注册一个直方图。应该从 [init_worker_by_lua_block]( https://github.com/openresty/lua-nginx-module#init_worker_by_lua_block) 部分为每个直方图调用一次。
name
是指标的名称。description
是文本描述。可选。label_names
是指标的标签名称数组。可选。buckets
是一个数字数组,用于定义桶边界。可选,默认为 20 个延迟桶,涵盖从 5 毫秒到 10 秒(以秒为单位)的范围。
返回一个 histogram
对象,该对象以后可用于记录样本。
示例
init_worker_by_lua_block {
prometheus = require("prometheus").init("prometheus_metrics")
metric_latency = prometheus:histogram(
"nginx_http_request_duration_seconds", "HTTP request latency", {"host"})
metric_response_sizes = prometheus:histogram(
"nginx_http_response_size_bytes", "Size of HTTP responses", nil,
{10,100,1000,10000,100000,1000000})
}
prometheus:collect()
语法: prometheus:collect()
以与 Prometheus 兼容的文本格式呈现所有指标。这应该在 content_by_lua_block 中调用,以在单独的 HTTP 页面上公开指标。
示例
location /metrics {
content_by_lua_block { prometheus:collect() }
allow 192.168.0.0/16;
deny all;
}
prometheus:metric_data()
语法: prometheus:metric_data()
将指标数据返回为字符串数组。
counter:inc()
语法: counter:inc(value, label_values)
递增先前注册的计数器。这通常从 log_by_lua_block 全局调用或按服务器/位置调用。
value
是应该添加到计数器的值。默认为 1。label_values
是标签值的数组。
标签值的数量应与使用 prometheus:counter()
注册计数器时定义的标签名称的数量相匹配。对于没有标签的计数器,不应该提供任何标签值。不可打印的字符将从标签值中删除。
示例
log_by_lua_block {
metric_bytes:inc(tonumber(ngx.var.request_length))
metric_requests:inc(1, {ngx.var.server_name, ngx.var.status})
}
counter:del()
语法: counter:del(label_values)
删除先前注册的计数器。这通常在您不再需要观察此计数器(或此计数器中具有特定标签值的指标)时调用。如果此计数器具有标签,您必须传递 label_values
以删除此计数器的特定指标。如果您想删除具有标签的计数器的所有指标,则应调用 Counter:reset()
。
label_values
是标签值的数组。
标签值的数量应与使用 prometheus:counter()
注册计数器时定义的标签名称的数量相匹配。对于没有标签的计数器,不应该提供任何标签值。不可打印的字符将从标签值中删除。
此函数将在删除指标之前等待 sync_interval
,以允许所有工作线程同步其计数器。
counter:reset()
语法: counter:reset()
删除先前注册的计数器的所有指标。如果此计数器没有标签,它与 Counter:del()
函数完全相同。如果此计数器有标签,它将删除具有不同标签值的 所有指标。
此函数将在删除指标之前等待 sync_interval
,以允许所有工作线程同步其计数器。
gauge:set()
语法: gauge:set(value, label_values)
设置先前注册的仪表盘的当前值。这可以从 log_by_lua_block 全局调用或按服务器/位置调用,以在每个请求上修改仪表盘,或从 content_by_lua_block 在 prometheus::collect()
之前调用,以返回实时值。
value
是仪表盘应该设置的值。必需的。label_values
是标签值的数组。
gauge:inc()
语法: gauge:inc(value, label_values)
递增或递减先前注册的仪表盘。当您想要观察可以同时增加和减少的指标的实时值时,这通常被调用。
value
是应该添加到仪表盘的值。当您需要减少仪表盘的值时,它可以是负值。默认为 1。label_values
是标签值的数组。
标签值的数量应与使用 prometheus:gauge()
注册仪表盘时定义的标签名称的数量相匹配。对于没有标签的仪表盘,不应该提供任何标签值。不可打印的字符将从标签值中删除。
gauge:del()
语法: gauge:del(label_values)
删除先前注册的仪表盘。这通常在您不再需要观察此仪表盘(或此仪表盘中具有特定标签值的指标)时调用。如果此仪表盘具有标签,您必须传递 label_values
以删除此仪表盘的特定指标。如果您想删除具有标签的仪表盘的所有指标,则应调用 Gauge:reset()
。
label_values
是标签值的数组。
标签值的数量应与使用 prometheus:gauge()
注册仪表盘时定义的标签名称的数量相匹配。对于没有标签的仪表盘,不应该提供任何标签值。不可打印的字符将从标签值中删除。
gauge:reset()
语法: gauge:reset()
删除先前注册的仪表盘的所有指标。如果此仪表盘没有标签,它与 Gauge:del()
函数完全相同。如果此仪表盘有标签,它将删除具有不同标签值的 所有指标。
histogram:observe()
语法: histogram:observe(value, label_values)
在先前注册的直方图中记录一个值。通常从 log_by_lua_block 全局调用或按服务器/位置调用。
请注意,记录观察需要递增几个直方图,这不会原子地发生,并且可能会与指标收集发生冲突(请参阅 #161)。
value
是应该记录的值。必需的。label_values
是标签值的数组。
示例
log_by_lua_block {
metric_latency:observe(tonumber(ngx.var.request_time), {ngx.var.server_name})
metric_response_sizes:observe(tonumber(ngx.var.bytes_sent))
}
histogram:reset()
语法: histogram:reset()
删除先前注册的直方图的所有指标。
此函数将在删除指标之前等待 sync_interval
,以允许所有工作线程同步其计数器。
内置指标
如果模块遇到错误(例如,当 lua_shared_dict
变得满时),它将递增一个名为 nginx_metric_errors_total
的错误指标(除非在 init() 中配置了另一个名称)。您可能希望为此指标配置警报。
注意事项
在 stream 模块中的使用
目前,在 Nginx 中无法在 HTTP 和 Stream 模块之间共享字典。如果您使用此库从 stream 模块收集指标,则需要配置一个单独的端点来返回它们。以下是一个示例。
server {
listen 9145;
content_by_lua_block {
local sock = assert(ngx.req.socket(true))
local data = sock:receive()
local location = "GET /metrics"
if string.sub(data, 1, string.len(location)) == location then
ngx.say("HTTP/1.1 200 OK")
ngx.say("Content-Type: text/plain")
ngx.say("")
ngx.say(table.concat(prometheus:metric_data(), ""))
else
ngx.say("HTTP/1.1 404 Not Found")
end
}
}
已知问题
libnginx-mod-http-lua 在某些 Debian 和 Ubuntu 版本中已损坏
请注意,最近的稳定版 Debian 和 Ubuntu 已知会打包与相同发行版中提供的 nginx
版本不兼容的 ngx_lua
版本。这会导致 nginx 进程在使用 lua 模块时发生段错误,使其完全无法使用。在这种情况下,nginx 错误日志将清楚地表明进程崩溃,例如
[alert] 123#123: worker process 45678 exited on signal 11
已知以下版本的 Debian 和 Ubuntu 存在此问题
故障排除
确保已启用 nginx lua 模块
如果您遇到表明 nginx 不知道如何解释 lua 脚本的问题,请确保已启用 [lua 模块](https://github.com/openresty/lua-nginx-module)。您可能需要在 nginx.conf
中添加类似以下内容
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;
保持启用 lua 代码缓存
此模块期望 lua_code_cache 选项为 on
(这是默认值)。
尝试使用旧版本的库
如果您看到库初始化错误,随后是每个指标更改请求的错误(例如,尝试索引全局 '...'(一个 nil 值)),则您可能正在使用旧版本的 lua-nginx-module。例如,如果您尝试将此库的最新版本与 Ubuntu 16.04 附带的 nginx-extras
包一起使用,就会发生这种情况。
如果您无法升级 nginx 和 lua-nginx-module,可以尝试使用该库的旧版本;它将没有最新的性能优化,但仍然可以使用。推荐使用的旧版本是 0.20181120。
开发
安装测试依赖项
luarocks install luacheck
luarocks install luaunit
运行测试
luacheck --globals ngx -- prometheus.lua
lua prometheus_test.lua
cd integration && ./test.sh
(需要 Docker 和 Go)
发布新版本
更新 CHANGELOG.md
更新
dist.ini
中的版本重命名
.rockspec
文件并在其中更新版本提交更改
创建一个新的 Git 标签:
git tag 0.XXXXXXXX && git push origin 0.XXXXXXXX
推送到 luarocks:
luarocks upload nginx-lua-prometheus-0.20181120-1.rockspec
上传到 OPM:
opm build && opm upload
贡献者
创建和维护者:Anton Tolchanov (@knyar)
Metrix 前缀支持由 david birdsong ([@davidbirdsong]( https://github.com/davidbirdsong)) 贡献
Gauge 支持由 Cosmo Petrich ([@cosmopetrich]( https://github.com/cosmopetrich)) 贡献
性能改进和每个工作线程的计数器由 Wangchong Zhou (@fffonion) / [@Kong]( https://github.com/Kong) 贡献。
指标名称跟踪改进由 Jan Dolinár ([@dolik-rce]( https://github.com/dolik-rce)) 贡献
许可证
根据 MIT 许可证授权。
第三方许可证
以下第三方模块在此库中使用
此模块根据 Apache 2.0 许可证授权。
版权所有 (C) 2019, Kong Inc.
保留所有权利。
作者
Anton Tolchanov
许可证
mit
版本
-
knyar/nginx-lua-prometheus 0.20240525Prometheus 指标库,适用于 Nginx 2024-05-25 09:28:11
-
knyar/nginx-lua-prometheus 0.20230607Prometheus 指标库,适用于 Nginx 2023-06-07 08:36:09
-
knyar/nginx-lua-prometheus 0.20221218Prometheus 指标库,适用于 Nginx 2022-12-18 15:36:45
-
knyar/nginx-lua-prometheus 0.20220527Prometheus 指标库,适用于 Nginx 2022-05-27 09:27:03
-
knyar/nginx-lua-prometheus 0.20220127Prometheus 指标库,适用于 Nginx 2022-01-27 22:20:51
-
knyar/nginx-lua-prometheus 0.20210206Prometheus 指标库,适用于 Nginx 2021-02-06 14:16:45
-
knyar/nginx-lua-prometheus 0.20201218Prometheus 指标库,适用于 Nginx 2020-12-18 08:56:27
-
knyar/nginx-lua-prometheus 0.20201118Prometheus 指标库,适用于 Nginx 2020-11-18 09:18:46
-
knyar/nginx-lua-prometheus 0.20200523Prometheus 指标库,适用于 Nginx 2020-05-23 18:06:31
-
knyar/nginx-lua-prometheus 0.20200420Prometheus 指标库,适用于 Nginx 2020-04-20 08:59:10
-
knyar/nginx-lua-prometheus 0.20181120Prometheus 指标库,适用于 Nginx 2018-11-20 17:29:44
-
knyar/nginx-lua-prometheus 0.20171117Prometheus 指标库,适用于 Nginx 2017-11-17 13:01:48