前些時候忽然發現內網服務器(基於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