nginx+lua在web開發(fā)中現(xiàn)在越來越多用于實現(xiàn)一些公共策略邏輯,比如防攻擊等,nginx有著高性能高并發(fā)的處理框架,lua語言開發(fā)也簡單,這次我們嘗試在nginx層用lua實現(xiàn)我們請求日志的打印。 在開發(fā)調(diào)試、問題排查中,日志信息很重要,尤其是一個請求的輸入及輸出信息,但nginx本身的日志定義不能打印輸出信息及POST參數(shù),我們往往會在后端業(yè)務(wù)代碼中(如用PHP)打印一個這樣的notice日志,不過也可以在nginx中用lua中實現(xiàn),所有經(jīng)過這個nginx的請求日志都會按你想要的格式打印出來,這樣實現(xiàn)簡單而且統(tǒng)一。下面介紹下我在nginx中用lua實現(xiàn)的一個日志打印腳本。 nginx+lua的具體開發(fā)教程見這里 https://github.com/openresty/lua-nginx-module,我就不介紹了,下面主要是介紹一下實現(xiàn)代碼: 我們要建立nginx各個處理階段的代碼文件,首先創(chuàng)建一個access.lua文件,代碼如下: if ngx.var.log_val ~= nil then local request = "["..ngx.var.time_local.."] ".."\""..ngx.var.request_method.." "..ngx.var.scheme.."://".. ngx.var.host..ngx.var.request_uri.."\"" local post = "" local delimiter = "" local item = "" ngx.req.read_body() local args, err = ngx.req.get_post_args() if args then for key, val in pairs(args) do item = "" if type(val) == "string" then key = string.gsub(key,"%c"," ") val = string.gsub(val,"%c"," ") item = key.."="..val elseif type(val) == "table" then item = key.."=" local tstr = ""; local tdelimiter = "" for k, v in pairs(val) do if type(v) == "string" then tstr = tstr..tdelimiter..v tdelimiter = ',' end end item = item..tstr end post = post..delimiter..item delimiter = "&" end end ngx.var.log_val = request.." ".." postdata=["..post.."] output=[" end 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 這個文件主要是記錄請求的時間、url及輸入?yún)?shù)等信息,包括post數(shù)據(jù) 接著創(chuàng)建一個body_filter.lua文件,內(nèi)容如下: if ngx.var.log_val ~= nil then local newcontent = string.gsub(ngx.arg[1],"%c"," ") ngx.var.log_val = ngx.var.log_val..newcontent end 1 2 3 4 這里記錄輸出信息,開發(fā)中發(fā)現(xiàn)ngx.arg[1]與任何字符串進行連接的話,日志打印都會打印兩次,除了與內(nèi)置log_val變量連接,原因可能跟內(nèi)部跳轉(zhuǎn)有關(guān),所以這里就兩行代碼,不會有更多其它操作。 再創(chuàng)建一個log.lua文件,內(nèi)容如下: if ngx.var.log_val ~= nil then function mylog(msg) file = io.open ("/home/rong/nginx/logs/monitor.log","a+") file:write (msg) file:flush(); file:close(); end ngx.var.log_val = ngx.var.log_val.."] httpstatus=".. ngx.var.status.." request_time="..ngx.var.request_time.."\n" mylog(ngx.var.log_val) end 1 2 3 4 5 6 7 8 9 10 11 12 這里將拼接起來的各個日志信息寫入文件。 創(chuàng)建了各個階段的處理文件,將其加入nginx配置文件中,如下: ...... access_by_lua_file /home/rong/nginx/conf/access.lua; body_filter_by_lua_file /home/rong/nginx/conf/body_filter.lua; log_by_lua_file /home/rong/nginx/conf/log.lua; ..... 1 2 3 4 5 注意nginx配置中 client_body_buffer_size 與 client_max_body_size的值要設(shè)得一樣大,且不能過小。 最后還要在server段定義一個變量,作為存儲每條日志信息用 server{ ...... set $log_val ''; ...... } 1 2 3 4 5 6 這樣,有請求過來時,在 /home/rong/nginx/logs/monitor.log文件 中就可以很清楚地看到輸入輸出信息了。 --------------------- 作者:micweaver 來源:CSDN 原文:https://blog.csdn.net/MICweaver/article/details/66473183 版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接! |
|