1

I've been trying to filter out a bunch of lines from the nginx access log. These lines contain a specific parameter, so I thought it would be easy to filter them out. Examples of the requests:

/index.php?cmd=thumb&#####
/index.php?cmd=preview&#####

where ##### can be anything. /index.php without this 'cmd' parameter (but possibly with other parameters) SHOULD be logged however.

I have tried the following

server {
    location ~ /index\.php\?cmd.* {
        access_log off;
    }
}

My guess is that location only looks at the file on the server you need, not any of the reuqest parameters. That could, for example, explain why location ~* \.(?:css|js)$ {access_log off;} (notice the $) also blocks logging request like /something.js?v=blahblah. As such, my first option would be invalid for sure. This is confirmed below (with source).

or

server {
    location /index.php {
        if ($arg_cmd) {
            access_log off;
        }
    }
}

or

http {
    map $request_uri $log {
        ~ /index\.php\?cmd.* 0;
        default 1;
    }

    access_log /var/log/nginx/access.log combined if=$log;
}

So far, all of the above do not have the desired result. I'm still convinced this should be possible and that I did something wrong in all of these implementations. Could someone please help me out?

Community
  • 1
  • 1
Guillaume
  • 11
  • 1
  • 5
  • Your second option looks promising - but you will need to place the `if` block inside the `location` block that processes your PHP scripts. It may look something like `location ~ \.php$ { ... }`. – Richard Smith Jan 12 '16 at 19:34
  • @RichardSmith Thx, since I only have an index.php in this instance, the `location /index.php {` as stated above IS the `location` block where the `fastcgi_pass` etc. resides. The `if` block won't work there, however. – Guillaume Jan 12 '16 at 19:50
  • Very strange. I tested your `if` block and it worked perfectly. Make sure you restart `nginx` to read the new configuration. – Richard Smith Jan 12 '16 at 19:56
  • @RichardSmith After every change I quickly do a `nginx -t` and then restart the service, so I'm sure that wasn't it. I have found a solution to get the third option working, though (removing a single space). Still wondering why the first and second won't work, so leaving this question open. – Guillaume Jan 12 '16 at 20:18
  • My guess is that `location` only looks at the file on the server you need, not any of the reuqest parameters. That could, for example, explain why `location ~* \.(?:css|js)$ {access_log off;}` (notice the `$`) also blocks logging request like `/something.js?v=blahblah`. As such, my first option would be invalid for sure. – Guillaume Jan 12 '16 at 20:30
  • Correct. The `location` directive tests a normalized URI - the query string (or argument list) is not considered. See [this document](http://nginx.org/en/docs/http/ngx_http_core_module.html#location) for details of the `location` directive. – Richard Smith Jan 12 '16 at 21:02
  • @RichardSmith For the second option, I don't know what value you gave the paramater `cmd` when testing, but I suppose it could be the case that `if ($arg_cmd)` might not evaluate to TRUE in my case (it takes its value and doesn't give a boolean on whether it exists or not). Hence, I should have done something like `if ($args ~ cmd)` (but then every parameter that includes "cmd" would suffice, so I guess `if ($args ~ ^cmd\=) {access_log off;}` if cmd is always the first argument would do it then)? – Guillaume Jan 12 '16 at 21:28
  • I was using a value that evaluated true. But if you have no control over the value of `cmd` you will have to resort to your less efficient solutions. – Richard Smith Jan 12 '16 at 21:48

1 Answers1

0
  1. First option was never going to work (see directly below it).
  2. Second option will only work if the value of the argument evaluates to TRUE. I had no control over the value itself (it was a hash) in my case, so this could not work for me. In my case, another option would be if ($args ~ ^cmd=.+) {access_log off;} if cmd is always the first argument, or just if ($args ~ cmd) {access_log off;}. (thx Richard Smith)
  3. I found out that the third option WILL work by removing the space between ~ and /index\.php\?cmd.* 0; This one allows me to globally set some more conditions to ignore, so I'm sticking with this one.
Guillaume
  • 11
  • 1
  • 5