Chr*_*tto 59 logging nginx http-post
我有我的配置设置来处理一堆GET请求,这些请求可以渲染处理分析和解析查询字符串以进行日志记录的像素.使用额外的第三方数据流,我需要处理对给定URL的POST请求,该URL在其请求主体内部具有预期可记录格式的JSON.我不想使用辅助服务器,proxy_pass只想将整个响应记录到关联的日志文件中,就像它对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;
}
Run Code Online (Sandbox Code Playgroud)
这是我想要做的事情:POST请求(不起作用):
location /bk {
log_format bk_tracking $request_body;
access_log /mnt/logs/nginx/bk.access.log bk_tracking;
}
Run Code Online (Sandbox Code Playgroud)
冰壶curl http://myurl/bk -d name=example给了我一个404页面找不到.
然后我尝试了:
location /bk.gif {
empty_gif;
log_format bk_tracking $request_body;
access_log /mnt/logs/nginx/bk.access.log bk_tracking;
}
Run Code Online (Sandbox Code Playgroud)
冰壶curl http://myurl/bk.gif -d name=example给了我一个405 Not Allowed.
我目前的版本是nginx/0.7.62.非常感谢任何正确方向的帮助!谢谢!
更新 所以现在我的帖子看起来像这样:
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; }
Run Code Online (Sandbox Code Playgroud)
它正确记录发布数据,但在请求者端返回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; }
Run Code Online (Sandbox Code Playgroud)
然后它200正确返回,但不再记录发布数据.
另一个更新 Kinda找到了一个有效的解决方案.希望这可以帮助其他人.
aho*_*ann 67
这个解决方案就像一个魅力(2017年更新,以表示log_format需要在nginx配置的http部分):
log_format postdata $request_body;
server {
# (...)
location = /post.php {
access_log /var/log/nginx/postdata.log postdata;
fastcgi_pass php_cgi;
}
}
Run Code Online (Sandbox Code Playgroud)
我认为诀窍是让nginx相信你会调用一个cgi脚本.
boq*_*apt 35
试试echo_read_request_body.
" echo_read_request_body ...显式读取请求体,以便$ request_body变量始终具有非空值(除非正文非常大,以至于它已被Nginx保存到本地临时文件中)."
location /log {
log_format postdata $request_body;
access_log /mnt/logs/nginx/my_tracking.access.log postdata;
echo_read_request_body;
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*tto 11
好.所以最后我能够记录帖子数据并返回200.这是一种hacky解决方案,我并不为此感到自豪,它基本上覆盖了error_page的自然行为,但是我对nginx加时间线的经验不足使我找到了这个解决方案:
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;
}
Run Code Online (Sandbox Code Playgroud)
现在根据该配置,似乎代理传递将一直返回200.偶尔我会得到500但是当我扔错误日志看看发生了什么时,我的所有request_body数据都在那里,我看不出问题.所以我抓住了它并写入了同一个日志.由于nginx不喜欢跟踪变量的相同名称,我只是使用my_tracking_2并写入与返回200时相同的日志.绝对不是最优雅的解决方案,我欢迎任何更好的解决方案.我见过post模块,但在我的场景中,我无法从源代码重新编译.
Bru*_*uno 10
下面的解决方案是我找到的最好的格式。
log_format postdata escape=json '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$request_body"';
server {
listen 80;
server_name api.some.com;
location / {
access_log /var/log/nginx/postdata.log postdata;
proxy_pass http://127.0.0.1:8080;
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个输入
curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://api.deprod.com/postEndpoint
Run Code Online (Sandbox Code Playgroud)
产生那个伟大的结果
201.23.89.149 - [22/Aug/2019:15:58:40 +0000] "POST /postEndpoint HTTP/1.1" 200 265 "" "curl/7.64.0" "{\"key1\":\"value1\", \"key2\":\"value2\"}"
Run Code Online (Sandbox Code Playgroud)
小智 7
FWIW,这个配置对我有用:
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;
}
Run Code Online (Sandbox Code Playgroud)
nginx日志格式取自这里:http://nginx.org/en/docs/http/ngx_http_log_module.html
无需额外安装任何东西
为我工作GET并POST要求:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
只是改变upstream_ip和upstream_port
| 归档时间: |
|
| 查看次数: |
150448 次 |
| 最近记录: |