Logging errors via error_page + post_action?

Maxim Dounin mdounin at mdounin.ru
Mon Jan 21 03:54:28 UTC 2013


Hello!

On Thu, Jan 17, 2013 at 03:41:59PM +1100, Robert Mueller wrote:

> I posted this about a month ago and didn't hear anything, so I'm
> reposting again to hopefully catch some new eyes and see if anyone has
> any ideas.
> 
> ---
> 
> Hi
> 
> In our nginx setup we use proxy_pass to pass most requests to backend
> servers.
> 
> We like to monitor our logs regularly for any errors to see that
> everything is working as expected. We can grep the nginx logs, but:
> 
> a) That's not real time
> b) We can't get extended information about the request, like if it's a
> POST, what the POST body actually was

The "tail -F /path/to/log" is actually recommended solution.  It 
is realtime and doesn't introduce additional point of failure in 
client request processing.

> So what we wanted to do was use an error_page handler in nginx so if any
> backend returned an error, we resent the request details to an error
> handler script, something like:
> 
>     location / {
>       proxy_pass http://backend/;
>     }
> 
>     error_page 500 /internal_error_page_500;
>     location /internal_error_page_500 {
>       internal;
>       proxy_set_header X-URL      "$host$request_uri";
>       proxy_set_header X-Post     $request_body;
>       proxy_set_header X-Method   $request_method;
>       proxy_set_header X-Real-IP  $remote_addr;
>       proxy_pass http://local/cgi-bin/error.pl;
>     }
> 
> The problem is that this replaces any result content from the main /
> proxy_pass with the content that error.pl generates. We don't want that,
> we want to keep the original result, but just use the error_page handler
> to effectively "log" the error for later.
> 
> I thought maybe we could replace:
> 
>       proxy_pass http://local/cgi-bin/error.pl;
> 
> With:
> 
>       post_action http://local/cgi-bin/error.pl;
> 
> But that just causes nginx to return a "404 Not Found" error instead.
> 
> Is there any way to do this? Return the original result content of a
> proxy_pass directive, but if that proxy_pass returns an error code (eg
> 500, etc), do a request to another URL with "logging" information (eg
> URL, method, POST body content, etc)

The error_page is executed to replace content returned to client.  
It can't be used to do something in addition to normal request 
processing.

If you are brave enough to do post_action and understand 
consequences, you may do something like

    location / {
        proxy_pass http://backend/;
        post_action /post;
    }

    location = /post {
        if ($status != 500) {
            return 204;
        }

        # do something
    }

Though I wouldn't recommend using post_action unless you understand what 
it implies.  It's left undocumented on purpose.

-- 
Maxim Dounin
http://nginx.com/support.html



More information about the nginx mailing list