从$ request_bodyloggingPOST数据

我有我的configuration设置来处理一堆GET请求,使渲染的像素能够正常工作,以处理分析和parsing查询string以进行日志logging。 有了额外的第三方数据stream,我需要处理一个POST请求到一个给定的url,它的请求体内有一个预期的可login格式的JSON。 我不想在proxy_pass上使用辅助服务器,只想将整个响应logging到关联的日志文件中,就像GET请求所做的一样。 我正在使用的代码片段如下所示:

GET请求(很好用):

 location ^~ /rl.gif { set $rl_lcid $arg_lcid; if ($http_cookie ~* "lcid=(.*\S)") { set $rl_lcid $cookie_lcid; } empty_gif; log_format my_tracking '{ "guid" : "$rl_lcid", "data" : "$arg__rlcdnsegs" }'; access_log /mnt/logs/nginx/my.access.log my_tracking; rewrite ^(.*)$ http://my/url?id=$cookie_lcid? redirect; } 

这是有点什么我想要做的:POST请求(这是行不通的):

 location /bk { log_format bk_tracking $request_body; access_log /mnt/logs/nginx/bk.access.log bk_tracking; } 

curl的curl http://myurl/bk -d name=example给了我一个404页未find。

然后我试着:

 location /bk.gif { empty_gif; log_format bk_tracking $request_body; access_log /mnt/logs/nginx/bk.access.log bk_tracking; } 

Curling curl http://myurl/bk.gif -d name=example给了我405 Not Allowed

我目前的版本是nginx/0.7.62 。 任何帮助正确的方向非常感谢! 谢谢!

更新所以现在我的post看起来像这样:

 location /bk { if ($request_method != POST) { return 405; } proxy_pass $scheme://127.0.0.1:$server_port/dummy; log_format my_tracking $request_body; access_log /mnt/logs/nginx/my.access.log my_tracking; } location /dummy { set $test 0; } 

它正确地logging了发布数据,但在请求者端返回404。 如果我改变上面的代码返回一个200像这样:

 location /bk { if ($request_method != POST) { return 405; } proxy_pass $scheme://127.0.0.1:$server_port/dummy; log_format my_tracking $request_body; access_log /mnt/logs/nginx/my.access.log my_tracking; return 200; } location /dummy { set $test 0; } 

然后正确返回200 ,但不再logging发布数据。

另一个更新有点find了一个工作解决scheme。 希望这可以帮助他人的方式。

这个解决scheme就像一个魅力:

 location = /post.php { log_format postdata $request_body; access_log /var/log/nginx/postdata.log postdata; fastcgi_pass php_cgi; } 

我认为这个技巧是让nginx相信你会调用一个cgi脚本。

试试echo_read_request_body。

“ echo_read_request_body …显式读取请求体,这样$ request_bodyvariables将总是有非空值(除非主体太大,已经被Nginx保存到本地临时文件中)。

 location /log { log_format postdata $request_body; access_log /mnt/logs/nginx/my_tracking.access.log postdata; echo_read_request_body; } 

好。 所以最后我能够login后的数据,并返回200.这是一个hacky的解决scheme,我不能自豪的基本上覆盖了error_page的自然行为,但我经验的nginx加上时间表导致我这个解决scheme:

 location /bk { if ($request_method != POST) { return 405; } proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_redirect off; proxy_pass $scheme://127.0.0.1:$server_port/success; log_format my_tracking $request_body; access_log /mnt/logs/nginx/my_tracking.access.log my_tracking; } location /success { return 200; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/nginx-default; log_format my_tracking $request_body; access_log /mnt/logs/nginx/my_tracking.access.log my_tracking_2; } 

现在根据这个configuration,似乎代理通行证会一直返回200。 偶尔我会得到500,但是当我扔了一个error_log看看发生了什么,我的所有request_body数据都在那里,我看不到一个问题。 所以我抓住了,并写了同一个日志。 由于nginx不喜欢跟踪variables的同名,所以我只使用了my_tracking_2,并在返回200时写入相同的日志。绝对不是最优雅的解决scheme,我欢迎任何更好的解决scheme。 我已经看过post模块,但在我的情况下,我不能从源代码重新编译。

FWIW,这个configuration为我工作:

 location = /logpush.html { if ($request_method = POST) { access_log /var/log/nginx/push.log push_requests; proxy_pass $scheme://127.0.0.1/logsink; break; } return 200 $scheme://$host/serviceup.html; } # location /logsink { return 200; } 

取自这里的nginx日志格式: http : //nginx.org/en/docs/http/ngx_http_log_module.html

不需要额外安装任何东西

为我的GETPOST请求工作:

 upstream my_upstream { server upstream_ip:upstream_port; } location / { log_format postdata '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" "$request_body"'; access_log /path/to/nginx_access.log postdata; proxy_set_header Host $http_host; proxy_pass http://my_upstream; } } 

只需更改upstream_ipupstream_port

我有一个类似的问题。 GET请求工作,他们(空)的请求体被写入日志文件。 POST请求在404上失败。试验了一下,我发现所有的 POST请求都失败了。 我发现一个论坛发帖询问有关POST请求和解决scheme那里为我工作。 解决scheme? 在proxy_pass行之前添加一个proxy_header行,就像下面例子中的一样。

 server { listen 192.168.0.1:45080; server_name foo.example.org; access_log /path/to/log/nginx/post_bodies.log post_bodies; location / { ### add the following proxy_header line to get POSTs to work proxy_set_header Host $http_host; proxy_pass http://10.1.2.3; } } 

(这与nginx 1.2.1是相称的。)