mirror of
https://github.com/cmur2/nginx-metrics-graphite.git
synced 2024-11-14 16:56:16 +01:00
Add more metrics
This commit is contained in:
parent
6f893484c7
commit
8e6d157b13
22
README.md
22
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
This is a Lua plugin for the Nginx web server that automatically collects and submits several important Nginx metrics to [Graphite](https://graphiteapp.org/) suitable for visualisation with e.g. [Grafana](http://grafana.org/).
|
||||
|
||||
In constrast to commercial and proprietary solutions such as [Luameter](https://luameter.com/) or [NGINX Plus](https://www.nginx.com/products/) with it's [ngx_http_status_module](http://nginx.org/en/docs/http/ngx_http_status_module.html), this plugin is open source software while featuring more and additional metrics compared to those available via the open source [ngx_http_stub_status_module](http://nginx.org/en/docs/http/ngx_http_stub_status_module.html).
|
||||
In constrast to commercial and proprietary solutions such as [Luameter](https://luameter.com/) or [NGINX Plus](https://www.nginx.com/products/) with it's [ngx_http_status_module](http://nginx.org/en/docs/http/ngx_http_status_module.html), this plugin is open source software while featuring more and additional metrics compared to those available via the open source [ngx_http_stub_status_module](http://nginx.org/en/docs/http/ngx_http_stub_status_module.html). (Yea, [other web servers](https://redmine.lighttpd.net/projects/1/wiki/Docs_ModStatus) deliver more information by default...)
|
||||
|
||||
This plugin takes inspiration from other Nginx metric libraries like [nginx-lua-prometheus](https://github.com/knyar/nginx-lua-prometheus) but differs fundamentally in the metrics submission handling by. In certain intervals it automatically pushes metrics to the configured Graphite (i.e. Carbon) host using pure Lua code instead of exposing them via a separate web page for polling.
|
||||
|
||||
@ -10,36 +10,48 @@ The metrics collection happens on every request for which the user configures a
|
||||
|
||||
Collected metrics in this prototype implementation:
|
||||
|
||||
* number of requests
|
||||
* numbers of requests (total, to upstream, using ssl, using gzip)
|
||||
* average request duration
|
||||
* accumulated request sizes over all requests
|
||||
* accumulated response sizes over all requests
|
||||
* HTTP status code classes (1xx, 2xx, 3xx, 4xx, 5xx)
|
||||
* HTTP methods (GET, HEAD, PUT, POST, DELETE, OPTIONS, others)
|
||||
* HTTP versions (0.9, 1.0, 1.1, 2.0)
|
||||
|
||||
Successfully tested with Nginx 1.6.2 and ngx_lua 0.9.12 on Debian Jessie.
|
||||
|
||||
## Caveats
|
||||
|
||||
A short metric submission interval might cause blocking on the Nginx worker threads since the shared dictionary storing all counters has to be locked.
|
||||
|
||||
Intermittent network errors while communicating with Graphite might leed to permanent loss of metric information.
|
||||
Intermittent network errors while communicating with Graphite might leed to permanent loss of metric information. The communication happens in clear text and thus needs a secure separate network or other means.
|
||||
|
||||
## Install
|
||||
|
||||
* Install `nginx-extra` (includes Lua support) on Debian Jessie
|
||||
* Clone the nginx-metrics-graphite repository to */opt/nginx-metrics-graphite*
|
||||
* Add the following config to top-level `http` block:
|
||||
* Add the following config to top-level `http` block (300 second submission interval):
|
||||
|
||||
```nginx
|
||||
resolver x.y.z.w; # DNS resolver IP address needed
|
||||
|
||||
lua_shared_dict metrics_graphite 128k;
|
||||
lua_package_path ";;/opt/nginx-metrics-graphite/?.lua";
|
||||
init_by_lua 'metrics_graphite = require("metrics_graphite").init("graphite.example.net", 300, "my.node.nginx_metrics.prefix")';
|
||||
init_by_lua 'metrics_graphite = require("metrics_graphite").init("graphite.example.net", 300, "my.node.prefix")';
|
||||
init_worker_by_lua 'metrics_graphite:worker()';
|
||||
```
|
||||
|
||||
* Instrument the `http` block or any server or location beneath it using `log_by_lua 'metrics_graphite:log()';`
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
apt-get install luarocks # on Debian
|
||||
|
||||
luarocks --local install luacheck
|
||||
luacheck --globals ngx -- metrics_graphite.lua
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
nginx-metrics-graphite is licensed under the Apache License, Version 2.0. See LICENSE for more information.
|
||||
|
@ -26,11 +26,22 @@ function MetricsGraphite.init(carbon_host, interval, mbase)
|
||||
method_options = "OPTIONS",
|
||||
method_other = ""
|
||||
}
|
||||
self.query_http = {
|
||||
http_09 = 0.9,
|
||||
http_10 = 1.0,
|
||||
http_11 = 1.1,
|
||||
http_20 = 2.0
|
||||
}
|
||||
|
||||
-- initialize/reset counters
|
||||
self.stats = ngx.shared.metrics_graphite -- TODO: unclear whether ngx.shared.DICT is thread-safe?
|
||||
self.stats:set("main_loop_worker", 0)
|
||||
self.stats:set("requests", 0)
|
||||
|
||||
self.stats:set("requests", 0) -- total number
|
||||
self.stats:set("upstream_requests", 0) -- requests which used an upstream server
|
||||
self.stats:set("gzip_requests", 0) -- responses which used gzip
|
||||
self.stats:set("ssl_requests", 0) -- requests which used ssl
|
||||
|
||||
self.stats:set("request_length", 0)
|
||||
self.stats:set("bytes_sent", 0)
|
||||
|
||||
@ -45,6 +56,10 @@ function MetricsGraphite.init(carbon_host, interval, mbase)
|
||||
self.stats:set(k, 0)
|
||||
end
|
||||
|
||||
for k,v in pairs(self.query_http) do
|
||||
self.stats:set(k, 0)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -89,18 +104,21 @@ function MetricsGraphite:worker()
|
||||
self.stats:set("request_time_num", 0)
|
||||
|
||||
-- submit metrics
|
||||
sock:send(this.mbase .. ".nginx_test.test" .. ngx.worker.pid() .. " 1 " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_test.num_requests " .. this.stats:get("requests") .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_test.acc_request_length " .. this.stats:get("request_length") .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_test.acc_bytes_sent " .. this.stats:get("bytes_sent") .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_test.avg_request_time " .. avg_request_time .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_metrics.num_requests " .. this.stats:get("requests") .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_metrics.acc_request_length " .. this.stats:get("request_length") .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_metrics.acc_bytes_sent " .. this.stats:get("bytes_sent") .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_metrics.avg_request_time " .. avg_request_time .. " " .. ngx.time() .. "\n")
|
||||
|
||||
for k,v in pairs(self.query_status) do
|
||||
sock:send(this.mbase .. ".nginx_test.num_" .. k .. " " .. this.stats:get(k) .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_metrics.num_" .. k .. " " .. this.stats:get(k) .. " " .. ngx.time() .. "\n")
|
||||
end
|
||||
|
||||
for k,v in pairs(self.query_method) do
|
||||
sock:send(this.mbase .. ".nginx_test.num_" .. k .. " " .. this.stats:get(k) .. " " .. ngx.time() .. "\n")
|
||||
sock:send(this.mbase .. ".nginx_metrics.num_" .. k .. " " .. this.stats:get(k) .. " " .. ngx.time() .. "\n")
|
||||
end
|
||||
|
||||
for k,v in pairs(self.query_http) do
|
||||
sock:send(this.mbase .. ".nginx_metrics.num_" .. k .. " " .. this.stats:get(k) .. " " .. ngx.time() .. "\n")
|
||||
end
|
||||
|
||||
sock:close()
|
||||
@ -118,6 +136,15 @@ function MetricsGraphite:log()
|
||||
-- function by default called on every request,
|
||||
-- should be fast and only do important calculations here
|
||||
self.stats:incr("requests", 1)
|
||||
if ngx.var.upstream_response_time ~= nil then
|
||||
self.stats:incr("upstream_requests", 1)
|
||||
end
|
||||
if ngx.var.gzip_ratio ~= nil then
|
||||
self.stats:incr("gzip_requests", 1)
|
||||
end
|
||||
if ngx.var.ssl_protocol ~= nil then
|
||||
self.stats:incr("ssl_requests", 1)
|
||||
end
|
||||
|
||||
for k,v in pairs(self.query_status) do
|
||||
if ngx.status >= v and ngx.status < v+100 then
|
||||
@ -138,6 +165,14 @@ function MetricsGraphite:log()
|
||||
self.stats:incr("method_other", 1)
|
||||
end
|
||||
|
||||
for k,v in pairs(self.query_http) do
|
||||
-- float equaliy
|
||||
if math.abs(v - ngx.req.http_version()) < 0.01 then
|
||||
self.stats:incr(k, 1)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local request_length = ngx.var.request_length -- in bytes
|
||||
self.stats:incr("request_length", request_length)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user