57

I have a bunch of rewrite rules that I have to port from apache to nginx.

It's a rather painful process because I'm not able to see if my rewrite rules and "if" conditions are working as I want them to.

Apache did have debugging for its rewrite module. Whats can I do for nginx?

Randall
  • 307
  • 2
  • 17
Jiho Kang
  • 967
  • 2
  • 9
  • 8

4 Answers4

61

Enable rewrite_log:

rewrite_log on;

and set debug level in error_log directive:

error_log /var/log/nginx/localhost.error_log notice;
mkobit
  • 103
  • 1
  • 5
quanta
  • 50,327
  • 19
  • 152
  • 213
  • 1
    Note that this can be used for more than debugging rewrites. You can add "rewrite DEBUG DEBUG break;" anywhere you like in the nginx config and see when it gets hit. This rewrite line effectively does nothing (if location "DEBUG" is matched, replace it with "DEBUG") other than trigger a line to be logged. You can technically even output variables like this: "rewrite .* $request break;" or rewrite .* "'$http_x_forwarded_for' $request" break; - although this causes the request to fail. It would be better to add the variable to a custom log format for access_log. – Curtis Yallop Jul 12 '17 at 21:54
22

Enable debugging support, then set debug level in error_log.

error_log   /var/log/nginx/error.log debug;

Now you can tail the log and send your requests through. There's probably more detail than you want, but that can sometimes be a lifesaver.

Oh, and you should be aware that if is evil, in a location context at least...

Pablo A
  • 169
  • 9
rossnz
  • 629
  • 4
  • 5
  • 5
    `notice` is much better than `debug` as the `error_level` for debugging rewrites because it will skip a lot of low-level irrelevant debug info (e.g. SSL or gzip details; 50+ lines per request). – Dan Dascalescu Jul 02 '15 at 11:47
6

Using logs and and built-in support for debugging is definitely the most reasonable way. If you are doing some quick routing debugging at early stages and want to interact through the browser/client only, using the return 4xx "text"; directive may also give you the answer you want with very little effort. For example,

http {
  server {
    listen 80;
    server_name mydomain.net;
    return 404 "mydomain 80 route";
  }

  server {
    listen 80 default_server;
    return 404 "default 80 route";
  }
}

The text in the returned webpage will tell you which server block your request triggered.

Rob Bednark
  • 215
  • 1
  • 2
  • 8
fr_andres
  • 161
  • 1
  • 3
2

Another good debug step is to check if your Nginx rules are being taken into account at all:

location /test {
    return 200 'My test';
}