lua-resty-dymetrics
重新編譯 OpenResty
動態指標模組需要給 Nginx 核心打補丁,因此需要重新編譯 OpenResty。 這個補丁我們會透過郵件的方式進行交付。
下面的指令碼用於給 OpenResty 1.19.9.1 版本的 Nginx 核心打補丁。 打完補丁後,使用者可以根據原來的打包流程進行打包。
set -e
pkg=openresty-1.19.9.1
ngx=nginx-1.19.9
wget https://openresty.org/download/$pkg.tar.gz
tar -xf $pkg.tar.gz
cd $pkg/bundle/$ngx/
patch -p1 < ../../../nginx-1.19.9-proc_exit_handler.patch
cd ../../..
tar -czf $pkg.tar.gz $pkg
配置二進位制安裝包倉庫
首先我們需要配置二進位制安裝包的倉庫,按照以下命令進行配置。(命令中的 CLIENT_TOKEN
需要替換成訂閱郵件中的有效 Token)
curl -o get-xray-priv-lib-repo.sh https://pkg2.openresty.com.cn/scripts/get-xray-priv-lib-repo.sh
sudo bash get-xray-priv-lib-repo.sh -l lua-resty-dymetrics-(customer-name) -t CLIENT_TOKEN
sudo bash get-xray-priv-lib-repo.sh -l dymetrics-nginx-module -t CLIENT_TOKEN
sudo bash get-xray-priv-lib-repo.sh -l openresty-priv-comm -t CLIENT_TOKEN
安裝軟體包
動態指標需要安裝如下四個元件
- openresty-yajl
- openresty-yajl-devel
- dymetrics-nginx-module
- lua-resty-dymetrics-(customer-name)
其中,lua-resty-dymetrics-(customer-name) 這個元件可以根據客戶定製, 因此不同的客戶需要根據自己的名稱安裝響應的元件。下面命令中的 customer-name 需要根據實際情況進行替換。
使用 yum
包管理器的作業系統,執行以下命令進行私有庫的安裝。
sudo yum install -y dymetrics-nginx-module-1.19.9 openresty-yajl openresty-yajl-devel
sudo yum install -y lua-resty-dymetrics-(customer-name)
使用 dnf
包管理器的作業系統,執行以下命令進行私有庫的安裝。
sudo dnf install -y dymetrics-nginx-module-1.19.9 openresty-yajl openresty-yajl-devel
sudo dnf install -y lua-resty-dymetrics-(customer-name)
使用 apt
包管理器的作業系統,執行以下命令進行私有庫的安裝。
sudo apt-get install -y dymetrics-nginx-module-1.19.9 openresty-yajl openresty-yajl-dev
sudo apt-get install -y lua-resty-dymetrics-(customer-name)
使用
在使用前需要在配置檔案 nginx.conf
中需要新增以下這些配置項。
- load_module 指令用於載入
ngx_http_lua_dymetrics_module
這個動態模組。 - lua_package_path 和 lua_package_cpath 指令 指定 lua 檔案和 lua 載入的二進位制共享庫搜尋路徑。
- lua_shared_dymetrics 這個指令定義一個動態指標使用的共享記憶體區。
load_module /usr/local/openresty/nginx/lib/ngx_http_lua_dymetrics_module.so;
http {
lua_package_path "/usr/local/openresty/site/lualib/?.ljbc;;";
lua_package_cpath "/usr/local/openresty-yajl/lib/?.so;/usr/local/openresty/site/lualib/?.so;;";
lua_shared_dymetrics dymetrics 120M;
}
server {
listen 80;
server_name localhost;
set $app_uid "test.openresty.com";
log_by_lua_block {
if ngx.ctx.no_dymetrics_log then
return
end
local ts = ngx.time()
ts = ts - (ts % 60)
local request_log = require "resty.dymetrics_http_reqs".request_log
local conn_log= require "resty.dymetrics_http_conns".request_log
local lua_vars = {}
local app_id = 0
request_log(ts, app_id, lua_vars)
conn_log(ts, app_id, lua_vars)
}
location /metrics {
allow 127.0.0.1;
allow 18.140.243.108; # just an example
deny all;
content_by_lua_block {
ngx.ctx.no_dymetrics_log = true
local report_req_data = require "resty.dymetrics_http_reqs".report_data_prometheus
local report_conn_data = require "resty.dymetrics_http_conns".report_data_prometheus
local ts = ngx.time()
ts = ts - 60 - (ts % 60)
local data, err = report_req_data(ts, 0, "")
if err ~= nil then
ngx.log(ngx.ERR, "prometheus: failed to get http request data:", err)
else
ngx.say(data)
end
local data, err = report_conn_data(ts, 0, "")
if err ~= nil then
ngx.log(ngx.ERR, "prometheus: failed to get http connection data:", err)
else
ngx.say(data)
end
}
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
Lua APIs
dymetrics_http_reqs module
request_log
syntax: ok, err = reqs.request_log(time_key, app_id, lua_variables)
context: log_by_lua*
Calling this interface will add the current request to the statistics. If there is an error, it will return nil and the corresponding error message.
The value of time_key
is the starting value of the statistics cycle. For example, if 60s is a statistics cycle, then “time_key” can be obtained as follows: time_key = ngx.time() - ngx.time() % 60
. app_id
is a key for Prometheus output. If app_id is not distinguished, pass value 0
. lua_variables
is an extension variable that is currently not used and requires passing an empty Lua table.
Here is an example:
log_by_lua_block {
local ts = ngx.time()
ts = ts - (ts % 60)
local request_log = require "resty.dymetrics_http_reqs".request_log
local lua_vars = {}
local app_id = 0
request_log(ts, app_id, lua_vars)
}
report_data
syntax: ok, err = reqs. report_data(time_key, node_id, partition_id, gateway_id)
context: content_by_lua_block*,ngx.timer.*
Get the dynamic indicators for the statistics cycle that starts with time_key
. This time_key
is for the previous statistics cycle, not the current one, because the current statistics cycle has not yet ended, and new requests will still be added to it.
node_id
represents the current machine’s ID. If it does not exist, it should be passed as 0.
partition_id
is a string representing the current partition’s ID. If it does not exist, it can be passed as nil
. gateway_id
is the ID of the gateway that the current node belongs to. If it does not exist, it can be passed as nil
.
Here is an example:
content_by_lua_block {
local report_req_data = require "resty.dymetrics_http_reqs".report_data
local ts = ngx.time()
ts = ts - 60 - (ts % 60)
local data, err = report_req_data(ts, 0, "")
if err ~= nil then
ngx.log(ngx.ERR, "prometheus: failed to get http request data:", err)
else
ngx.say(data)
end
}
report_data_prometheus
syntax: ok, err = reqs.report_data_prometheus(time_key, node_id, partition_id, gateway_id)
context: content_by_lua_block*,ngx.timer.*
Get the dynamic indicators for the statistics cycle that starts with time_key
. This time_key
is for the previous statistics cycle, not the current one, because the current statistics cycle has not yet ended, and new requests will still be added to it.
node_id
represents the current machine’s ID. If it does not exist, it should be passed as 0.
partition_id
is a string representing the current partition’s ID. If it does not exist, it can be passed as nil
. gateway_id
is the ID of the gateway that the current node belongs to. If it does not exist, it can be passed as nil
.
Here is an example:
content_by_lua_block {
local report_req_data = require "resty.dymetrics_http_reqs".report_data_prometheus
local ts = ngx.time()
ts = ts - 60 - (ts % 60)
local data, err = report_req_data(ts, 0, "")
if err ~= nil then
ngx.log(ngx.ERR, "prometheus: failed to get http request data:", err)
else
ngx.say(data)
end
}
dymetrics_http_conns module
request_log
syntax: ok, err = conns.request_log(time_key, app_id, lua_variables)
context: log_by_lua*
Calling this interface will add the current request to the statistics. If there is an error, it will return nil and the corresponding error message.
The value of time_key
is the starting value of the statistics cycle. For example, if 60s is a statistics cycle, then “time_key” can be obtained as follows: time_key = ngx.time() - ngx.time() % 60
. app_id
is a key for Prometheus output. If app_id is not distinguished, pass value 0
. lua_variables
is an extension variable that is currently not used and requires passing an empty Lua table.
Here is an example:
log_by_lua_block {
local ts = ngx.time()
ts = ts - (ts % 60)
local conn_log = require "resty.dymetrics_http_conns".request_log
local lua_vars = {}
local app_id = 0
request_log(ts, app_id, lua_vars)
}
report_data
syntax: ok, err = conns.report_data(time_key, node_id, partition_id, gateway_id)
context: content_by_lua_block*,ngx.timer.*
Get the dynamic indicators for the statistics cycle that starts with time_key
. This time_key
is for the previous statistics cycle, not the current one, because the current statistics cycle has not yet ended, and new requests will still be added to it.
node_id
represents the current machine’s ID. If it does not exist, it should be passed as 0.
partition_id
is a string representing the current partition’s ID. If it does not exist, it can be passed as nil
. gateway_id
is the ID of the gateway that the current node belongs to. If it does not exist, it can be passed as nil
.
Here is an example:
content_by_lua_block {
local report_req_data = require "resty.dymetrics_http_conns".report_data
local ts = ngx.time()
ts = ts - 60 - (ts % 60)
local data, err = report_req_data(ts, 0, "")
if err ~= nil then
ngx.log(ngx.ERR, "prometheus: failed to get http request data:", err)
else
ngx.say(data)
end
}
report_data_prometheus
syntax: ok, err = conns.report_data_prometheus(time_key, node_id, partition_id, gateway_id)
context: content_by_lua_block*,ngx.timer.*
Get the dynamic indicators for the statistics cycle that starts with time_key
. This time_key
is for the previous statistics cycle, not the current one, because the current statistics cycle has not yet ended, and new requests will still be added to it.
node_id
represents the current machine’s ID. If it does not exist, it should be passed as 0.
partition_id
is a string representing the current partition’s ID. If it does not exist, it can be passed as nil
. gateway_id
is the ID of the gateway that the current node belongs to. If it does not exist, it can be passed as nil
.
Here is an example:
content_by_lua_block {
local report_req_data = require "resty.dymetrics_http_conns".report_data_prometheus
local ts = ngx.time()
ts = ts - 60 - (ts % 60)
local data, err = report_req_data(ts, 0, "")
if err ~= nil then
ngx.log(ngx.ERR, "prometheus: failed to get http request data:", err)
else
ngx.say(data)
end
}