├── .gitignore ├── README.md ├── reqstat.lua ├── stat_util.lua └── status_api.lua /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx_lua_request_monitor 2 | nginx请求各项指标的监控与统计 3 | 4 | ## 主要功能 5 | 6 | 监控请求数、流量、请求时间、4xx、5xx等。 7 | 8 | ## 配置 9 | 10 | http { 11 | include mime.types; 12 | default_type application/octet-stream; 13 | 14 | lua_shared_dict statistics_dict 50M; 15 | lua_package_path "your_path/nginx_lua_request_monitor/?.lua"; 16 | 17 | sendfile on; 18 | keepalive_timeout 65; 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | set $domain_monitor "site.test.xxx.com"; 25 | log_by_lua_file "your_path/nginx_lua_request_monitor/reqstat.lua"; 26 | 27 | location / { 28 | root html; 29 | index index.html index.htm; 30 | } 31 | 32 | } 33 | 34 | # 监控服务 35 | server { 36 | listen 6080; 37 | server_name localhost; 38 | location /nginx_status { 39 | content_by_lua_file "your_path/nginx_lua_request_monitor/status_api.lua"; 40 | } 41 | } 42 | 43 | } 44 | 45 | ## 提供的接口 46 | 47 | - curl -v "http://localhost:6080/nginx_status" 48 | 49 | ``` 50 | Server Name key:test.xxx.com 51 | Request Count:12 52 | Request Time Sum:0 53 | Flow Sum:5446 54 | 4xx Code Count:3 55 | 5xx Code Count:0 56 | ``` 57 | 58 | - curl -v "http://localhost:6080/nginx_status?domain=test.xxx.com" 59 | - curl -v "http://localhost:6080/nginx_status?domain=test.xxx.com&type=reqc" 60 | - curl -v "http://localhost:6080/nginx_status?domain=test.xxx.com&type=reqt" 61 | - curl -v "http://localhost:6080/nginx_status?domain=test.xxx.com&type=flow" 62 | - curl -v "http://localhost:6080/nginx_status?domain=test.xxx.com&type=4xx" 63 | - curl -v "http://localhost:6080/nginx_status?domain=test.xxx.com&type=5xx" 64 | 65 | 66 | ## 扩展 67 | 68 | 如果有其他需求,比如监控location、upstream的监控,只需在相应配置的作用域块中加入变量即可,扩展很方便。 -------------------------------------------------------------------------------- /reqstat.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- yapu.wang@dianping.com 3 | -- Created by wangyapu on 2016/07/05 15:29. 4 | -- 5 | 6 | -- 共享内存statistics_dict记录所有监控数据 7 | statistics_dict = ngx.shared.statistics_dict 8 | local stat_util = require("stat_util") 9 | 10 | -- query conut 11 | function query_count(identifier) 12 | local query_count_key = identifier .. "__query_count" 13 | local new_value, err = statistics_dict:incr(query_count_key, 1) 14 | if not new_value and err == "not found" then 15 | statistics_dict:add(query_count_key, 0, 86400) 16 | stat_util.incr(statistics_dict, query_count_key, 1) 17 | end 18 | end 19 | 20 | -- request time count 21 | function request_time_count(identifier) 22 | local request_time_count_key = identifier .. "__request_time_count" 23 | local current_request_time = tonumber(ngx.var.request_time) or 0 24 | local pre_sum = statistics_dict:get(request_time_count_key) or 0 25 | local sum = pre_sum + current_request_time 26 | statistics_dict:set(request_time_count_key, sum, 86400) 27 | end 28 | 29 | -- flow count 30 | function flow_count(identifier) 31 | local flow_sum_key = identifier .. "__bytes_sent_count" 32 | local current_bytes_sent = tonumber(ngx.var.bytes_sent) or 0 33 | local pre_sum = statistics_dict:get(flow_sum_key) or 0 34 | local sum = pre_sum + current_bytes_sent 35 | statistics_dict:set(flow_sum_key, sum, 86400) 36 | end 37 | 38 | -- request 4xx code count 39 | function request_4xx_code_count(identifier) 40 | local status_code = tonumber(ngx.var.status) 41 | local request_4xx_count_key = identifier .. "__4xx_code_count" 42 | 43 | if status_code >= 400 and status_code < 500 then 44 | local new_value, err = statistics_dict:incr(request_4xx_count_key, 1) 45 | if not new_value and err == "not found" then 46 | statistics_dict:add(request_4xx_count_key, 0, 86400) 47 | stat_util.incr(statistics_dict, request_4xx_count_key, 1) 48 | end 49 | end 50 | end 51 | 52 | -- request 5xx code count 53 | function request_5xx_code_count(identifier) 54 | local status_code = tonumber(ngx.var.status) 55 | local request_5xx_count_key = identifier .. "__5xx_code_count" 56 | 57 | if status_code >= 500 then 58 | local new_value, err = statistics_dict:incr(request_5xx_count_key, 1) 59 | if not new_value and err == "not found" then 60 | statistics_dict:add(request_5xx_count_key, 0, 86400) 61 | stat_util.incr(statistics_dict, request_5xx_count_key, 1) 62 | end 63 | end 64 | end 65 | 66 | if ngx.var.domain_monitor and string.len(ngx.var.domain_monitor) > 0 then 67 | local var_prefix = ngx.var.domain_monitor 68 | query_count(var_prefix) 69 | request_time_count(var_prefix) 70 | flow_count(var_prefix) 71 | request_4xx_code_count(var_prefix) 72 | request_5xx_code_count(var_prefix) 73 | end 74 | 75 | -------------------------------------------------------------------------------- /stat_util.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- yapu.wang@dianping.com 3 | -- Created by wangyapu on 2016/07/05 15:29. 4 | -- 5 | 6 | local stat_util = {} 7 | 8 | function stat_util.incr(dict, key, increment) 9 | increment = increment or 1 10 | local new_value, err = dict:incr(key, increment) 11 | if err then 12 | dict:set(key, increment) 13 | new_value = increment 14 | end 15 | return new_value 16 | end 17 | 18 | function stat_util.empty(dict) 19 | dict:flush_all() 20 | dict:flush_expired() 21 | end 22 | 23 | function stat_util.show(dict) 24 | for index, key in pairs(dict:get_keys(10240)) do 25 | ngx.say(key, " | ", dict:get(key)) 26 | end 27 | end 28 | 29 | function stat_util.showByDomainAndType(dict, type, domain) 30 | ngx.say("Server Name key:", domain) 31 | local identifier = "site." .. domain 32 | if type == "all" or not type then 33 | ngx.say("Request Count:", dict:get(identifier .. "__query_count") or 0) 34 | ngx.say("Request Time Sum:", dict:get(identifier .. "__request_time_count") or 0) 35 | ngx.say("Flow Sum:", dict:get(identifier .. "__bytes_sent_count") or 0) 36 | ngx.say("4xx Code Count:", dict:get(identifier .. "__4xx_code_count") or 0) 37 | ngx.say("5xx Count Count:", dict:get(identifier .. "__5xx_code_count") or 0) 38 | ngx.exit(ngx.HTTP_OK) 39 | elseif type == "reqc" then 40 | ngx.say("Request Count:", dict:get(identifier .. "__query_count") or 0) 41 | ngx.exit(ngx.HTTP_OK) 42 | elseif type == "reqt" then 43 | ngx.say("Request Time Sum:", dict:get(identifier .. "__request_time_count") or 0) 44 | ngx.exit(ngx.HTTP_OK) 45 | elseif type == "flow" then 46 | ngx.say("Flow Sum:", dict:get(identifier .. "__bytes_sent_count") or 0) 47 | ngx.exit(ngx.HTTP_OK) 48 | elseif type == "4xx" then 49 | ngx.say("4xx Code Count:", dict:get(identifier .. "__4xx_code_count") or 0) 50 | ngx.exit(ngx.HTTP_OK) 51 | elseif type == "5xx" then 52 | ngx.say("5xx Code Count:", dict:get(identifier .. "__5xx_code_count") or 0) 53 | ngx.exit(ngx.HTTP_OK) 54 | else 55 | ngx.say("type is error!") 56 | ngx.exit(ngx.HTTP_OK) 57 | end 58 | end 59 | 60 | return stat_util -------------------------------------------------------------------------------- /status_api.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- yapu.wang@dianping.com 3 | -- Created by wangyapu on 2016/07/05 15:29. 4 | -- 5 | 6 | local statistics_dict = ngx.shared.statistics_dict 7 | local stat_util = require("stat_util") 8 | 9 | local uri_args = ngx.req.get_uri_args() 10 | local server_name = uri_args["domain"] 11 | local type = uri_args["type"] 12 | 13 | if server_name then 14 | stat_util.showByDomainAndType(statistics_dict, type, server_name) 15 | else 16 | stat_util.show(statistics_dict) 17 | end 18 | 19 | 20 | --------------------------------------------------------------------------------