Program Club

$ request_body에서 POST 데이터 로깅

proclub 2020. 12. 11. 18:59
반응형

$ request_body에서 POST 데이터 로깅


분석을 처리하고 로깅을 위해 쿼리 문자열을 구문 분석하는 데 잘 작동하는 픽셀을 렌더링하는 GET 요청을 처리하기위한 구성 설정이 있습니다. 추가 제 3 자 데이터 스트림을 사용하여 요청 본문 내부에 예상되는 로깅 가능한 형식의 JSON이있는 지정된 URL에 대한 POST 요청을 처리해야합니다. 보조 서버를 사용하고 싶지 않고 proxy_passGET 요청으로 수행하는 것과 같이 전체 응답을 연결된 로그 파일에 기록하고 싶습니다. 내가 사용중인 일부 코드 스 니펫은 다음과 같습니다.

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를 반환합니다. 위의 코드를 변경하여 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올바르게 반환 하지만 더 이상 게시 데이터를 기록하지 않습니다.

ANOTHER UPDATE 약간은 작동하는 해결책을 찾았습니다. 바라건대 이것이 다른 사람들을 도울 수 있기를 바랍니다.


이 솔루션은 매력처럼 작동합니다 (log_format이 nginx 구성의 http 부분에 있어야 함을 알리기 위해 2017 년에 업데이트 됨).

log_format postdata $request_body;

server {
    # (...)

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

나는 트릭이 nginx가 당신이 cgi 스크립트를 호출 할 것이라고 믿게 만드는 것이라고 생각합니다.


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

확인. 그래서 마침내 저는 포스트 데이터를 기록하고 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;
}

Now according to that config, it would seem that the proxy pass would return a 200 all the time. Occasionally I would get 500 but when I threw in an error_log to see what was going on, all of my request_body data was in there and I couldn't see a problem. So I caught that and wrote to the same log. Since nginx doesn't like the same name for the tracking variable, I just used my_tracking_2 and wrote to the same log as when it returns a 200. Definitely not the most elegant solution and I welcome any better solution. I've seen the post module, but in my scenario, I couldn't recompile from source.


FWIW, this config worked for me:

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 log format taken from here: http://nginx.org/en/docs/http/ngx_http_log_module.html

no need to install anything extra

worked for me for GET and POST requests:

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

just change upstream_ip and upstream_port


I had a similar problem. GET requests worked and their (empty) request bodies got written to the the log file. POST requests failed with a 404. Experimenting a bit, I found that all POST requests were failing. I found a forum posting asking about POST requests and the solution there worked for me. That solution? Add a proxy_header line right before the proxy_pass line, exactly like the one in the example below.

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

(This is with nginx 1.2.1 for what it is worth.)


The solution below was the best format I found.

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

}

For this input

curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST http://api.deprod.com/postEndpoint

Generate that great result

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\"}"

참고URL : https://stackoverflow.com/questions/4939382/logging-post-data-from-request-body

반응형