2011-02-08 2 views
44

로깅을 위해 쿼리 문자열을 분석하고 구문 분석을 처리 할 수있는 픽셀을 렌더링하는 GET 요청을 처리하도록 구성 설정을했습니다. 추가 제 3 자 데이터 스트림을 사용하면 JSON이 요청 본문 내에 예상되는 로그 형식으로 제공된 URL에 POST 요청을 처리해야합니다. proxy_pass과 함께 보조 서버를 사용하고 GET 요청과 같은 관련 로그 파일에 전체 응답을 기록하기를 원합니다. (잘 작동)

GET 요청 : 나는 다음과 같은 모양을 사용하고 일부 코드의 조각 POST 요청을 (않는 : 여기

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

는 내가 뭘하려고 오전 좀입니다 작동하지 않음) :

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 은 이제 내 게시물은 다음과 같습니다.

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를 반환하지만, 더 이상 포스트 데이터를 기록 : 나는 위의 코드를 변경하는 경우과 같이 200을 반환 없습니다.

다른 업데이트 킨다가 해결책을 찾았습니다. 희망적으로 이것은 다른 사람들을 도울 수 있기를 바랍니다.

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

이제 config에 따르면 프록시 패스가 항상 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 doesn 이후 프록시 나 fast-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 로그 형식 여기에서 촬영 : 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; 
    } 
} 

단지 upstream_ip 변경하고 upstream_port