2011-02-08 11 views
44

私は、GETリクエストを扱うための設定をしています。これは、解析を処理し、クエリ文字列を解析してロギングするためにうまく動作するピクセルをレンダリングします。追加のサードパーティのデータストリームを使用する場合、リクエスト本体の内部に予期されるログ可能な形式のJSONを持つ特定のURLへのPOSTリクエストを処理する必要があります。私は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; 
} 

は私がしようとしているものをちょっとです:ない POSTリクエスト(私は次のようなルックスを使用しているいくつかのコードのスニペット動作しません):

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

カーリング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; 
} 

カーリング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; } 

それは正しくポストデータのログ記録が、依頼者側に404が返されます。

UPDATE は、だから今私のポストは次のようになります。私は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を返しませんが、もはやポストデータを記録します。

別のアップデート Kindaが実用的な解決策を見つけました。うまくいけば、これは途中で他の人を助けることができます。

+0

あなたはこれでどこに行くのですか?私は同様の問題に反対している。 –

答えて

45

このソリューションは、魔法のように動作します(つまりLOG_FORMATを称えるために2017年に更新さはnginxの設定ファイルのHTTPの一部であることが必要) CGIスクリプト。

+10

私は "log_format postdata $ request_body;"に移動しなければなりませんnginxは "log_format指令はここでは許可されていません"と述べているため、サーバ部分へのアクセスはありません –

+4

これは正しい答えです。前述の@OlegNeumyvakinのように、私は 'log_format'部分を移動しなければなりませんでした。しかし、私の場合は、 "サーバー"ブロックの内部ではなく "http"ブロックの内側に移動しなければなりませんでした。しかし、これはトリックでした! – Matt

+1

@OlegNeumyvakin&Matt:私はあなた自身の解説を答えに入れました(現在レビュー待ちです)。ありがとうございました! –

8

最終的に私は投稿データをログに記録し、200を返すことができました。それは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; 
} 

今その設定によれば、プロキシパスが200のすべての時間を返すだろうと思われます。ときどき私は500を得るだろうが、何が起こっていたのかを見るためにerror_logを投げたとき、私のrequest_bodyデータはすべてそこにあり、私は問題を見ることができませんでした。だから私はそれをキャッチし、同じログに書きました。 nginxはトラッキング変数の同じ名前が好きではないので、私はmy_tracking_2を使用して、それが200を返すときと同じログに書きました。最も洗練されたソリューションではありません。投稿モジュールを見たことがありますが、私のシナリオでは、ソースから再コンパイルできませんでした。

log_format postdata $request_body; 

server { 
    # (...) 

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

私はトリックはnginxのは、あなたが呼び出すと信じて作っていると思う:

+1

あなたが思いついた解決策は、ここで受け入れられた答えと非常に似ています:http://stackoverflow.com/questions/17609472/really-logging-the-post-request-body-instead-of-with-nginx nginxはプロキシやファストcgiサーバに送信しない限り、本体を解析して、プロキシ自体を動作させます。 – turtlemonvh

+0

私たちはPOST要求を別の場所にproxy_passすることによって同様の解決策を使用します。 – arganzheng

0

私にも同様の問題がありました。 GETリクエストが機能し、(空の)リクエストボディがログファイルに書き込まれました。 POSTリクエストが404で失敗しました。ちょっと試してみると、すべて POSTリクエストが失敗していました。私はforum posting asking about POST requestsを見つけ、そこの解決策は私のために働いた。その解決策? 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である。)

29

はecho_read_request_bodyを試してみてください。

"echo_read_request_body ...ボディがNginxによってローカルの一時ファイルに保存されていない限り、$ request_body変数が常に空でない値を持つように、要求本体を明示的に読み取ります。

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

これは、fastcgiをインストールする必要がないので、受け入れられた答えよりもうまく機能しました – Fluffy

+4

@Fluffyはい、しかし 'echo_read_request_body'をインストールする必要があります... – NoamG

+3

' apt-get install nginx-full'でインストールします – firelynx

3

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; 
} 
+0

これも私のために働いた。乾杯! – Rafay

4

nginxログ形式:エクストラ

GETのために私のために働いた何かをインストールするには、http://nginx.org/en/docs/http/ngx_http_log_module.html

必要はありませんし、 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; 
    } 
} 

だけupstream_ip変更とupstream_port

関連する問題