# Logging errors via error\_page + post\_action?

**URL:** <https://www.ruby-forum.com/t/logging-errors-via-error-page-post-action/225104>\
**Category:** NGINX\
**Created:** [December 13, 2012, 4:45am UTC](https://www.ruby-forum.com/t/logging-errors-via-error-page-post-action/225104 "2012-12-13T04:45:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [December 13, 2012, 4:45am UTC](https://www.ruby-forum.com/t/logging-errors-via-error-page-post-action/225104/1 "2012-12-13T04:45:22Z")

</div>

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

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)

–  
Rob M.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Robert\_Mueller](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbce88/32.png) [@Robert\_Mueller](https://www.ruby-forum.com/u/Robert_Mueller)\
**Post date:** [January 17, 2013, 5:42am UTC](https://www.ruby-forum.com/t/logging-errors-via-error-page-post-action/225104/2 "2013-01-17T05:42:50Z")

</div>

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

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)

–  
Rob M.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Robert\_Mueller](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bbce88/32.png) [@Robert\_Mueller](https://www.ruby-forum.com/u/Robert_Mueller)\
**Post date:** [January 21, 2013, 4:54am UTC](https://www.ruby-forum.com/t/logging-errors-via-error-page-post-action/225104/3 "2013-01-21T04:54:43Z")

</div>

Hello!

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

> 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.

> ```
> internal;
> 
> ```
> 
> to effectively “log” the error for later.
> 
> 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 D.

> **[F5 NGINX: Built for cloud-native apps. Ready for AI traffic.](https://www.f5.com/products/nginx)**
>
> Deliver modern applications with NGINX. Explore high-performance load balancing, API gateways, and web server solutions trusted by top global enterprises.
