Hello!2012/11/25 level077:
> 假设:log_format main "$cookie_1 $cookie_2 $cookie_3"
>
> 发送cookie:ngx.header['Set-Cookie'] = {'1=cookie_1; path=/', '2=cookie_2;
> path=/','3=cookie_3;path=/'}
>
> $sent_http_set_cookie 的值只是1=cookie_1; path=/
>
> 可不可以使用ngx.req.set_header重新设置,然后使用日志记录下来?
>
是的,$sent_http_set_cookie 只会返回第一个 Set-Cookie 头(因为 $sent_http_XXX
变量的值总是第一个 XXX 响应头的值)。
所以如果你有用到多个 Set-Cookie 头,最好在 Lua 中通过读取
ngx.header["Set-Cookie"]
将所有的 Set-Cookie 响应头的值都序列化到一个 nginx 变量中。下面是一个完整的例子:
log_format test '[$time_local] "$request" set-cookie: $my_cookie';
access_log logs/access2.log test;
server {
# entry point
location = /t {
set $my_cookie '';
proxy_pass http://127.0.0.1:$server_port/remote;
header_filter_by_lua '
local vals = ngx.header["Set-Cookie"]
if type(vals) == "table" then
vals = table.concat(vals, " ")
end
ngx.var.my_cookie = vals
';
}
# dummy location to emulate a remote service
location = /remote {
access_log off;
content_by_lua "
ngx.header['Set-Cookie'] = {
'1=cookie_1; path=/',
'2=cookie_2; path=/',
'3=cookie_3;path=/'
}
";
}
}
这里我们用 location = /remote 摸拟了一个生成 Set-Cookie 响应头的后端服务,然后在我们的主 location
中通过 proxy_pass 访问它。
请求 /t 接口可以在 logs/access2.log 中得到下面这一行记录:
[25/Nov/2012:20:14:34 -0800] "GET /t HTTP/1.1" set-cookie:
1=cookie_1; path=/ 2=cookie_2; path=/ 3=cookie_3;path=/
我们看到,三个 cookie 都被记录下来了。上面这个例子同样可以处理只有一个 cookie 的情形。
如果你的应用直接是使用 content_by_lua 来生成 cookie 的话,则无需再引入 header_filter_by_lua
了,直接在 content_by_lua 中把所有 cookie 的值序列化进 $my_cookie 变量中去即可,例如:
log_format test '[$time_local] "$request" set-cookie: $my_cookie';
access_log logs/access2.log test;
server {
location = /t {
set $my_cookie '';
content_by_lua "
local vals = {
'1=cookie_1; path=/',
'2=cookie_2; path=/',
'3=cookie_3;path=/'
}
ngx.header['Set-Cookie'] = vals
ngx.var.my_cookie = table.concat(vals, ' ')
";
}
}
效果是完全一样的。上面这两个例子都在我本机测试通过 :)
Best regards,
-agentzh