前些时候忽然发现内网服务器(基于OpenResty搭建的)中error.log 出现大量的 500 错误,排查后发现是一些简单的小bug致使的,不过这个让我意识到OpenResty中貌似没有对每一个服务监控的手段,查询后发现Tengie有一个叫 req_status 的模块能够用于作这样的统计,本来是想拿过来编译到OpenResty中,后来发现这个模块和Tengine有必定的绑定性,又不太想本身仿造一个,因而决定用 lua 加上一些配置来搞一个简单的请求统计。nginx
个人需求:json
1.基于 OpenResty 的服务器可以提供一个接口告知每一个 location 的访问量(单位是次);
2.在上述访问量中,统计出各个返回码的数量,好比多少个200,多少500,多少400错误这样;api
步骤:服务器
Step 1: curl
在 nginx.conf 定义一块共享内存名为 ngx_stats,以下:ui
worker_processes x; pid logs/nginx.pid; error_log logs/error.log warn; events { worker_connections 3000; } http { ... lua_shared_dict ngx_stats 16m; include ngx_private_cloud.conf; ... }
其次,在 server 级别写 rewrite, 以下:编码
server { ... rewrite_by_lua_file lua/rewrite/main.lua; location = /hello1 { content_by_lua 'ngx.say("oooo")'; } location = /hello { echo "hello world"; } location ~* /api/([\w_]+?)\.json { access_by_lua_file lua/comm/safe_request.lua; body_filter_by_lua_file lua/comm/safe_response.lua; content_by_lua_file lua/$1.lua; } ... }
到此为止,配置工做告一段落,接下来的即是完成 lua 编码lua
--main.lua local shared_status = ngx.shared['ngx_stats'] local uri = ngx.var.request_uri local value, flag = shared_status:get(uri) if nil == value then shared_status:set(uri, 1) else shared_status:incr(uri, 1) end --interface.lua local common = require "lua.comm.common" local shared_status = ngx.shared['ngx_stats'] local keys = shared_status:get_keys(0) local result = {} for index, value in pairs(keys) do stored, flag = shared_status:get(value) ngx.log(ngx.ERR, "index = ", index, " value = ", value, " stored = ", stored) -- table.insert(result, value, stored) result[value] = stored end ngx.say(common.json_encode(result))
接下来 咱们经过curl http://ip:port/api/interface.json 便能获得每一个location的访问次数了。url
固然这个实现还不完善,没有包含每一个location各类返回状态的统计,可是也是能够经过lua来实现的。code