Vor
Vor

Reputation: 35109

How to write only logs with 200 status

I'm trying to figure out how to do the following:

  1. Request is coming in.

  2. HttpLuaModule performs some action against the request. If request is valid than Lua will finish processing with ngx.exit(202). But there are some conditions that may (and will) occur during the processing and nginx might return 403 , 404, 503 Errors.

What I want to do is to write to access logs only requests that have 200 Status code. Basically I would like to do something like this:

location /foo {
    content_by_lua_file "/opt/nginx/lua/process.lua";
    if (status == 200) {
        access_log "/path/to/the/access_log"
    } 

I'm very new to both nginx and lua so for me it's a bit of a challenge to figure out where to place and if statement (ether after content_by_lua_file or in side lua file) and what this if statement should look like.

Upvotes: 11

Views: 18191

Answers (4)

Sithsu
Sithsu

Reputation: 2219

nginx 1.7.0+ allows using an if condition in access_log directive itself.

access_log path [format [buffer=size [flush=time]] [if=condition]];

The if parameter (1.7.0) enables conditional logging.
A request will not be logged if the condition evaluates to “0” or an empty string

Combined with map directive its possible to send log events to different logs based on various conditions.

http {

    map $status $normal {
        ~^2  1;
        default 0;
    }
    map $status $abnormal {
        ~^2  0;
        default 1;
    }
    map $remote_addr $islocal {
        ~^127  1;
        default 0;
    }

    server {

        access_log logs/access.log combined if=$normal;
        access_log logs/access_abnormal.log combined if=$abnormal;
        access_log logs/access_local.log combined if=$islocal;

    }  
}

http://nginx.org/en/docs/http/ngx_http_log_module.html
http://nginx.org/en/docs/http/ngx_http_map_module.html

Upvotes: 30

senz
senz

Reputation: 2158

In every question is a part of answer. You were very close:

if ($status != "200") {
    access_log off;
}

Check info for version availability here. http://nginx.org/en/docs/http/ngx_http_core_module.html#variables

Also, almost all access log format vars are available in "modern" versions: http://nginx.org/en/docs/http/ngx_http_log_module.html

Upvotes: 4

Vor
Vor

Reputation: 35109

This is the solution I came up with:

auth.lua

-- Some logic goes here
-- ....
-- ....
ngx.var.return_status = 200

nginx.conf

http {
   lua_package_path .....;
   lua_package_cpath ....;

   rewrite_by_lua_no_postpone on;

   server {
      
     set $return_status 1;
    
     location /foo {
        rewrite_by_lua_file "<apth_to_aut.lua";

        if ($return_status = 200) {
            access_log  <path_to_access_log>  format;
            return 200;
        }
     }
   }  
}

Upvotes: 2

robinkc
robinkc

Reputation: 1348

you can do it by using ngx.log and log_by_lua directives.

location /conditional_log{
        log_by_lua 'if ngx.status == 200 then ngx.log(ngx.ERR, "It is 200") end';
        content_by_lua 'ngx.say("I am ok") ngx.exit(200)';
    }

In the above code, we use log_by_lua which is called while running in log phase. In that if ngx.status == 200, we use ngx.log to trigger the logging using ngx.log.

This will write to error_log. Not sure how to write it to access_log.

For reference

http://wiki.nginx.org/HttpLuaModule#ngx.log

http://wiki.nginx.org/HttpLuaModule#log_by_lua

Upvotes: 4

Related Questions