日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

openresty开发系列36--openresty执行流程之6日志模块处理阶段

發(fā)布時(shí)間:2025/3/20 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 openresty开发系列36--openresty执行流程之6日志模块处理阶段 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

openresty開發(fā)系列36--openresty執(zhí)行流程之6日志模塊處理階段

一)header_filter_by_lua ?

語法:header_filter_by_lua <lua-script-str>
語境:http,server,location,location if
階段:output-header-filter
一般用來設(shè)置cookie和headers,在該階段不能使用如下幾個(gè)API:
1、output API(ngx.say和ngx.send_headers)
2、control API(ngx.exit和ngx.exec)
3、subrequest API(ngx.location.capture和ngx.location.capture_multi)
4、cosocket API(ngx.socket.tcp和ngx.req.socket)

案例一:

location / {
??? header_filter_by_lua 'ngx.header.Foo = "blah"';
??? echo "Hello World!";
}

案例二:

http { ?
?
??? log_format? main? '$msec $status $request $request_time ' ?
????????????????????? '$http_referer $remote_addr [ $time_local ] ' ?
????????????????????? '$upstream_response_time $host $bytes_sent ' ?
????????????????????? '$request_length $upstream_addr'; ?
?
??? access_log? logs/access.log main buffer=32k flush=1s; ?
?
??? upstream remote_world { ?
??????? server 127.0.0.1:8080; ?
??? } ?
?
??? server { ?
??????? listen 80; ?
?
??????? location /exec { ?
??????????? content_by_lua ' ?
??????????????? local cjson = require "cjson" ?
??????????????? local headers = { ?
??????????????????? ["Etag"] = "662222165e216225df78fbbd47c9333", ?
??????????????????? ["Last-Modified"] = "Sat, 24 July 2019 16:58:22 GMT", ?
??????????????? } ?
??????????????? ngx.var.my_headers = cjson.encode(headers) ?
??????????????? ngx.var.my_upstream = "remote_world" ?
??????????????? ngx.var.my_uri = "/world" ?
??????????????? ngx.exec("/upstream") ?
??????????? '; ?
??????? } ?
?
??????? location /upstream { ?
??????????? internal; ?
?
??????????? set $my_headers $my_headers; ?
??????????? set $my_upstream $my_upstream; ?
??????????? set $my_uri $my_uri; ?
??????????? proxy_pass http://$my_upstream$my_uri; ?
?
??????????? header_filter_by_lua ' ?
??????????????? local cjson = require "cjson" ?
??????????????? headers = cjson.decode(ngx.var.my_headers) ?
??????????????? for k, v in pairs(headers) do ?
??????????????????? ngx.header[k] = v ?
??????????????? end ?
??????????? '; ?
??????? } ?
??? } ?
?
?
??? server { ?
??????? listen 8080; ?
?
??????? location /world { ?
??????????? echo "hello world"; ?
??????? } ?
??? } ?
} ?

二)body_filter_by_lua
語法:body_filter_by_lua <lua-script-str>
語境:http,server,location,location if
階段:output-body-filter
輸入的數(shù)據(jù)時(shí)通過ngx.arg[1](作為lua的string值),通過ngx.arg[2]這個(gè)bool類型表示響應(yīng)數(shù)據(jù)流的結(jié)尾。

這個(gè)指令可以用來篡改http的響應(yīng)正文的;會(huì)調(diào)用幾次
在該階段不能利用如下幾個(gè)API:
1、output API(ngx.say和ngx.send_headers)
2、control API(ngx.exit和ngx.exec)
3、subrequest API(ngx.location.capture和ngx.location.capture_multi)
4、cosocket API(ngx.socket.tcp和ngx.req.socket)

輸入的數(shù)據(jù)時(shí)通過ngx.arg[1],通過ngx.arg[2]這個(gè)bool范例暗示響應(yīng)數(shù)據(jù)流的末了。
基于這個(gè)原因,’eof’只是nginx的鏈接緩沖區(qū)的last_buf(對主requests)或last_in_chain(對subrequests)的標(biāo)志。
運(yùn)行以下呼吁可以當(dāng)即終止運(yùn)行接下來的lua代碼:
return ngx.ERROR
這會(huì)將響應(yīng)體截?cái)鄬?dǎo)致無效的響應(yīng)。lua代碼可以通過修改ngx.arg[1]的內(nèi)容將數(shù)據(jù)傳輸?shù)较掠蔚?br />nginx output body filter階段的其它模塊中去。譬喻,將response body中的小寫字母舉辦反轉(zhuǎn),我們可以這么寫:

案例一

location /t {
??? echo hello world12;
??? echo hi yile;
??? body_filter_by_lua '
??????? ngx.log(ngx.ERR,"ngx.arg[1]=",ngx.arg[1]," arg[2]=",ngx.arg[2])
??????? ngx.arg[1] = string.upper(ngx.arg[1])
??? ';
}

盡管只有兩個(gè) echo,但是 body_filter_by_lua* 會(huì)被調(diào)用三次!

第三次調(diào)用的時(shí)候,ngx.arg[1] 為空字符串,而 ngx.arg[2] 為 true。
這是因?yàn)?#xff0c;Nginx 的 upstream 相關(guān)模塊,以及 OpenResty 的 content_by_lua,
會(huì)單獨(dú)發(fā)送一個(gè)設(shè)置了 last_buf 的空 buffer,來表示流的結(jié)束。這算是一個(gè)約定俗成的慣例,所以有必要在運(yùn)行相關(guān)邏輯之前,
檢查 ngx.arg[1] 是否為空。當(dāng)然反過來不一定成立,ngx.arg[2] == true 并不代表 ngx.arg[1] 一定為空。


案例二

location /t {
??? echo hello world;
??? echo hiya globe;

??? body_filter_by_lua '
??????? ngx.log(ngx.ERR,"ngx.arg[1]=",ngx.arg[1]," arg[2]=",ngx.arg[2])
??????? local chunk = ngx.arg[1]
??????? if string.match(chunk, "hello") then
??????????? ngx.arg[2] = true? -- new eof
??????????? return
??????? end

??????? ngx.arg[1] = nil
??? ';
}

這是因?yàn)?#xff0c;當(dāng)body filter看到了一塊包括”hello“的字符塊后當(dāng)即將”eof“標(biāo)志配置為了true,
從而導(dǎo)致響應(yīng)被截?cái)嗔说匀皇怯行У幕馗病?br />
三)log_by_lua,log_by_lua_file

在log階段指定的lua日志,并不會(huì)替換access log,而是在那之后調(diào)用。

在該階段不能利用如下幾個(gè)API:
1、output API(ngx.say和ngx.send_headers)
2、control API(ngx.exit和ngx.exec)
3、subrequest API(ngx.location.capture和ngx.location.capture_multi)
4、cosocket API(ngx.socket.tcp和ngx.req.socket)

可以利用此階段,把日志統(tǒng)一收集到日志服務(wù)器中

location / {
??? echo "Hello World!";
??? log_by_lua_block {
??????? ngx.log(ngx.ERR,msg)
??? }
}
elk日志收集分析

轉(zhuǎn)載于:https://www.cnblogs.com/reblue520/p/11446487.html

總結(jié)

以上是生活随笔為你收集整理的openresty开发系列36--openresty执行流程之6日志模块处理阶段的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。