2

在OpenResty中用lua实现一个简单的服务器状态监控

前些时候突然发现内网服务器(基于OpenResty搭建的)中error.log 出现大量的 500 错误,排查后发现是一些简单的小bug导致的,不过这个让我意识到OpenResty中貌似没有对每个服务监控的手段,查询后发现Tengie有一个叫 req_status 的模块可以用于做这样的统计,原本是想拿过来编译到OpenResty中,后来发现这个模块和Tengine有一定的绑定性,又不太想自己仿造一个,于是决定用 lua 加上一些配置来搞一个简单的请求统计。

我的需求:

1.基于 OpenResty 的服务器能够提供一个接口告知每个 location 的访问量(单位是次);
2.在上述访问量中,统计出各个返回码的数量,比如多少个200,多少500,多少400错误这样;

步骤:

Step 1:

在 nginx.conf 定义一块共享内存名为 ngx_stats,如下:

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 编码

--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的访问次数了。

当然这个实现还不完善,没有包含每个location各种返回状态的统计,但是也是可以通过lua来实现的。


河马大侠
368 声望125 粉丝

引用和评论

0 条评论