log_format和access_log的正确打开方式

nginx默认的log_format和access_log如下:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
access_log  logs/access.log;

上面的日志格式存在以下问题:
1,因为由于CDN和还有其他的nginx在请求的前面,上面的日志格式不能反映真实的用户IP。
2,缺少访问时长。
所以,我会把上面的日志格式log_format改写成:

    map $proxy_add_x_forwarded_for  $clientRealIp {
        ""  $remote_addr;
        ~^(?P<firstAddr>[0-9\.]+),?.*$      $firstAddr;
    }

    log_format  main  '$remote_addr:$remote_port - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$clientRealIp" "$proxy_add_x_forwarded_for" $request_time';

可是怎么都不生效,于是我查看了一下nginx的文档,其中对 log_format 的定义如下:

Syntax: log_format name [escape=default|json|none] string ...;
Default:    log_format combined "...";
Context:    http

对access_log的定义如下:

Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
        access_log off;
Default:    access_log logs/access.log combined;
Context:    http, server, location, if in location, limit_except

在上面的access_log定义中的format,究竟是个什么鬼?原来这个format对应的就是上面log_format中的name,也就是说我们对我们自己定义的log_format取一个name(可以随便,默认是combined),然后在access_log中一定要指定这个name,否则access_log就是用了默认的combined的log_format,这样也就是你无论如何改了都没有效。

所以,对于一开始定义的那个log_format,在access_log中,应该如下定义:

access_log  logs/access.log main;

这个main也就是上面的log_format定义的name。

发表评论

邮箱地址不会被公开。 必填项已用*标注