openresty开发系列36--openresty执行流程之6日志模块处理阶段
openresty开发系列36--openresty执行流程之6日志模块处理阶段
一)header_filter_by_lua
语法:header_filter_by_lua <lua-script-str>
语境:http,server,location,location if
阶段:output-header-filter
一般用来设置cookie和headers,在该阶段不能使用如下几个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
输入的数据时通过ngx.arg[1](作为lua的string值),通过ngx.arg[2]这个bool类型表示响应数据流的结尾。
这个指令可以用来篡改http的响应正文的;会调用几次
在该阶段不能利用如下几个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)
输入的数据时通过ngx.arg[1],通过ngx.arg[2]这个bool范例暗示响应数据流的末了。
基于这个原因,’eof’只是nginx的链接缓冲区的last_buf(对主requests)或last_in_chain(对subrequests)的标志。
运行以下呼吁可以当即终止运行接下来的lua代码:
return ngx.ERROR
这会将响应体截断导致无效的响应。lua代码可以通过修改ngx.arg[1]的内容将数据传输到下游的
nginx output body filter阶段的其它模块中去。譬喻,将response body中的小写字母举办反转,我们可以这么写:
案例一
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])
';
}
尽管只有两个 echo,但是 body_filter_by_lua* 会被调用三次!
第三次调用的时候,ngx.arg[1] 为空字符串,而 ngx.arg[2] 为 true。
这是因为,Nginx 的 upstream 相关模块,以及 OpenResty 的 content_by_lua,
会单独发送一个设置了 last_buf 的空 buffer,来表示流的结束。这算是一个约定俗成的惯例,所以有必要在运行相关逻辑之前,
检查 ngx.arg[1] 是否为空。当然反过来不一定成立,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
';
}
这是因为,当body filter看到了一块包括”hello“的字符块后当即将”eof“标志配置为了true,
从而导致响应被截断了但仍然是有效的回覆。
三)log_by_lua,log_by_lua_file
在log阶段指定的lua日志,并不会替换access log,而是在那之后调用。
在该阶段不能利用如下几个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 / {
echo "Hello World!";
log_by_lua_block {
ngx.log(ngx.ERR,msg)
}
}
elk日志收集分析
openresty开发系列36--openresty执行流程之6日志模块处理阶段的更多相关文章
- openresty开发系列35--openresty执行流程之5内容content阶段
openresty开发系列35--openresty执行流程之5内容content阶段 content 阶段 ---init阶段---重写赋值---重写rewrite---access content ...
- openresty开发系列34--openresty执行流程之4访问阶段
openresty开发系列34--openresty执行流程之4访问阶段 访问阶段 用途:访问权限限制 返回403 nginx:allow 允许,deny 禁止 allow ip:deny ip: 涉 ...
- openresty开发系列33--openresty执行流程之3重写rewrite和重定向
openresty开发系列33--openresty执行流程之3重写rewrite和重定向 重写rewrite阶段 1)重定向2)内部,伪静态 先介绍一下if,rewrite指令 一)if指令语法:i ...
- openresty开发系列33--openresty执行流程之2重写赋值阶段
openresty开发系列33--openresty执行流程之2重写赋值阶段 一)重写赋值阶段 1)set_by_lua 语法:set_by_lua $res <lua-script-str&g ...
- openresty开发系列32--openresty执行流程之1初始化阶段
openresty开发系列32--openresty执行流程之初始化阶段 一)初始化阶段 1)init_by_lua init_by_lua_block init_by_lua_file语 ...
- openresty开发系列20--lua的时间操作
openresty开发系列20--lua的时间操作 在 Lua 中,函数 time.date 和 difftime 提供了所有的日期和时间功能.在 OpenResty 的世界里,不推荐使用这里的标准时 ...
- openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息
openresty开发系列40--nginx+lua实现获取客户端ip所在的国家信息 为了实现业务系统针对不同地区IP访问,展示包含不同地区信息的业务交互界面.很多情况下系统需要根据用户访问的IP信息 ...
- openresty开发系列38--通过Lua+Redis 实现动态封禁IP
openresty开发系列38--通过Lua+Redis 实现动态封禁IP 一)需求背景为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单.对于黑名单之内的 IP ,拒绝 ...
- openresty开发系列37--nginx-lua-redis实现访问频率控制
openresty开发系列37--nginx-lua-redis实现访问频率控制 一)需求背景 在高并发场景下为了防止某个访问ip访问的频率过高,有时候会需要控制用户的访问频次在openresty中, ...
随机推荐
- Flask入门到放弃(五)—— 蓝图
转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10980094.html 蓝图 Blueprint 模块化 随着flask程序越来越复杂,我们需要对 ...
- 搭建helm私服ChartMuseum
介绍 ChartMuseum是一个用Go(Golang)编写的开源Helm Chart Repository服务器 ChartMuseum是一个用Go(Golang)编写的开源Helm Chart R ...
- 如何利用python教程判断一个 IP 在不在线?
假设今天老板给我们一个任务,让我们判断一下一个 IP 在不在线.我们随手用 python 写一个 ping IP 的代码: import os host = input('请输入要检测的 IP : ' ...
- vsftpd配置文件
一.默认配置 1. 允许匿名用户和本地用户登录 anonymous_enable=YES local_enable=YES 2. 匿名用户使用的登录名为ftp或anonymous,密码为空:匿名用户不 ...
- 【Flask】 python学习第一章 - 5.0 模板
jinjia2 模板 python实现 flask 内置语言 参照Djago实现 设置模板文件夹 设置模板语言 jinja2 demo6_template.html ----> 从代码渲染 ...
- Kali下的内网劫持(二)
前一小节说到在Kali下可以进行捕获客户端的图片,那么同样的,客户端访问的网页也是可以捕获的: . 以上可以看出监听完毕,那么在被监听端访问阿里云的一个网站: 在监听端用urlsnart这个工具进行捕 ...
- NGINX并发量优化
NGINX并发量优化 一.压力测试 命令:ab -c 2000 -n 2000 web服务器的地址 ab:压力测试工具 -c:client缩写,客户端的数量 -n:总的访问量,所有客户端总共的访问量. ...
- Tarjan算法分解强连通分量(附详细参考文章)
Tarjan算法分解强连通分量 算法思路: 算法通过dfs遍历整个连通分量,并在遍历过程中给每个点打上两个记号:一个是时间戳,即首次访问到节点i的时刻,另一个是节点u的某一个祖先被访问的最早时刻. 时 ...
- MySQL数据的优化方案
一.选取最使用的字段属性 mysql可以使用的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快,因此在创建表的时候,为了获得更好的性能,我们可以将表中的字段的宽度尽量设 ...
- 深度学习Keras框架笔记之Activation类使用
使用 keras.layers.core.Activation(activation) Apply an activation function tothe input.(貌似是把激活函数应用到输入数 ...