nginx+lua在web開(kāi)發(fā)中現(xiàn)在越來(lái)越多用于實(shí)現(xiàn)一些公共策略邏輯,比如防攻擊等,nginx有著高性能高并發(fā)的處理框架,lua語(yǔ)言開(kāi)發(fā)也簡(jiǎn)單,這次我們嘗試在nginx層用lua實(shí)現(xiàn)我們請(qǐng)求日志的打印。 在開(kāi)發(fā)調(diào)試、問(wèn)題排查中,日志信息很重要,尤其是一個(gè)請(qǐng)求的輸入及輸出信息,但nginx本身的日志定義不能打印輸出信息及POST參數(shù),我們往往會(huì)在后端業(yè)務(wù)代碼中(如用PHP)打印一個(gè)這樣的notice日志,不過(guò)也可以在nginx中用lua中實(shí)現(xiàn),所有經(jīng)過(guò)這個(gè)nginx的請(qǐng)求日志都會(huì)按你想要的格式打印出來(lái),這樣實(shí)現(xiàn)簡(jiǎn)單而且統(tǒng)一。下面介紹下我在nginx中用lua實(shí)現(xiàn)的一個(gè)日志打印腳本。 nginx+lua的具體開(kāi)發(fā)教程見(jiàn)這里 https://github.com/openresty/lua-nginx-module,我就不介紹了,下面主要是介紹一下實(shí)現(xiàn)代碼: 我們要建立nginx各個(gè)處理階段的代碼文件,首先創(chuàng)建一個(gè)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 這個(gè)文件主要是記錄請(qǐng)求的時(shí)間、url及輸入?yún)?shù)等信息,包括post數(shù)據(jù) 接著創(chuàng)建一個(gè)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 這里記錄輸出信息,開(kāi)發(fā)中發(fā)現(xiàn)ngx.arg[1]與任何字符串進(jìn)行連接的話,日志打印都會(huì)打印兩次,除了與內(nèi)置log_val變量連接,原因可能跟內(nèi)部跳轉(zhuǎn)有關(guān),所以這里就兩行代碼,不會(huì)有更多其它操作。 再創(chuàng)建一個(gè)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 這里將拼接起來(lái)的各個(gè)日志信息寫入文件。 創(chuàng)建了各個(gè)階段的處理文件,將其加入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è)得一樣大,且不能過(guò)小。 最后還要在server段定義一個(gè)變量,作為存儲(chǔ)每條日志信息用 server{ ...... set $log_val ''; ...... } 1 2 3 4 5 6 這樣,有請(qǐng)求過(guò)來(lái)時(shí),在 /home/rong/nginx/logs/monitor.log文件 中就可以很清楚地看到輸入輸出信息了。 --------------------- 作者:micweaver 來(lái)源:CSDN 原文:https://blog.csdn.net/MICweaver/article/details/66473183 版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接! |
|