lua-resty-dymetrics
Recompile OpenResty
The Dynamic Metrics module requires a patch to the Nginx core, so OpenResty needs to be recompiled. This patch will be delivered via email.
The following script is used to patch the Nginx core for OpenResty version 1.19.9.1. After patching, users can follow the original packaging process.
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
Configure the binary installer repository
First we need to configure the repository for the binary installer, follow the command below. (The CLIENT_TOKEN
in the command needs to be replaced with a valid Token from the subscription email)
curl -o get-xray-priv-lib-repo.sh https://pkg2.openresty.com/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
Installing packages
Dynamic metrics requires the following four components to be installed
- openresty-yajl
- openresty-yajl-devel
- dymetrics-nginx-module
- lua-resty-dymetrics-(customer-name)
The lua-resty-dymetrics-(customer-name) component is customizable by the customer. So different customers need to install the component according to their names. The customer-name in the following command needs to be replaced as appropriate.
For operating systems using the yum
package manager, run the following command to install the private library.
``bash sudo yum install -y dymetrics-nginx-module-1.19.9 openresty-yajl openresty-yajl-devel sudo yum install -y lua-resty-dymetrics-(customer-name)
For operating systems using the ``dnf`` package manager, execute the following command to install the private libraries.
```bash
sudo dnf install -y dymetrics-nginx-module-1.19.9 openresty-yajl openresty-yajl-devel
sudo dnf install -y lua-resty-dymetrics-(customer-name)
For operating systems using the apt
package manager, execute the following command to install the private libraries.
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)
Usage
You need to add the following configuration items to the configuration file nginx.conf
before using it.
load_module
directive to load the dynamic modulengx_http_lua_dymetrics_module
.- The
lua_package_path
andlua_package_cpath
directives specify the path to search for lua files and lua-loaded binary shared libraries. lua_shared_dymetrics
directive defines a shared memory area to be used by dynamic metrics.
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.
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
}