Nginx的日志处理


背景

之前一直被各种咨询nginx的使用问题.
大部分都是性能, 加模块, 以及一些tcp端口等的问题.

其实这些都还好, 还有一个比较麻烦的问题时日志相关的. 
nginx的日志稍有不注意就会变的非常大. 导致不可用.
其实应该是实现logrotate的方式比较好一些. 

其实实现方式也有多种, 可以使用nginx脚本原生实现, 也可以使用logrotate , 其实也可以实现自己手写脚本. 
所以这里想总结一下. 便于以后使用.

worker_processes  auto;
events {
    worker_connections  10250;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    gzip            on;
    keepalive_timeout  65;

    log_format main  '远程地址: $remote_addr 请求发生时间: [$time_iso8601] 状态: $status  请求总用时: $request_time 后端服务总耗时: $upstream_response_time 代理建立连接用时: $upstream_connect_time 代理发送header的用时: $upstream_header_time  后端服务器地址: $upstream_addr  链接序列号: $connection 当前链接的请求数: $connection_requests 请求体大小: $body_bytes_sent 后端服务器状态: $upstream_status 请求url: $request ' ;

    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
      set $date $1$2$3;
        }

   access_log  logs/$date.access.log main ;
   error_log   logs/$date.error.log main ; 

    server {
        listen       80;
        server_name  localhost ;
        location /{
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header REMOTE-HOST $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:5200/;
        }
    }
}

日志清理方式

cd /opt/nginx/logs
find . -mtime +10  -iname *.log  -exec rm -rf {} \; 

添加到计划任务内, 每天凌晨两点左右执行.

logrotate的方式

其实 nginx 内部使用 if 判断并不是好事情, 会影响一定的性能. 
所以认为比较好的方式应该是外部进行处理

logrotate的方式应该是比较优雅的方式. 
需要注意 logrotate 并不是一个后台服务
他是基于linux 的cron 计划任务进行处理的. 

如果没有安装的话 可以使用 yum 或者是 apt-get 的方式在线安装
yum install logrotate -y 方式安装.

使用注意事项

可以使用编译指定, 也可以使用 配置文件参数指定的方式来指定很多配置.

比如 access_log 和error_log的设置 可以将目录放到与logrotate一致的目录里面. 

比如pid 可以使用如下命令进行指向:

pid /var/run/nginx.pid;

然后再使用配置文件进行处理.
需要注意:
如果有多个nginx进行, 
建议设置多个不同的日志清理. 
同事建议由多个pid. 建议有多个log文件名, 进行区别, 避免出现混乱的现象.

配置文件说明

nginx的配置文件一般为:

cat > /etc/logrotate.d/nginx <<EOF
/var/log/nginx/*.log /var/log/nginx/*/*.log{
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 640 root adm
    sharedscripts
    postrotate
      if [ -f /var/run/nginx.pid ]; then 
         kill -USR1 `cat /var/run/nginx.pid`  
      fi
    endscript
}
EOF

编译注意事项

./configure --prefix=/usr/nginx \
--sbin-path=/usr/nginx/nginx \
--conf-path=/usr/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--with-http_ssl_module \
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.3 \
--with-openssl=../openssl-1.1.1w \
--with-stream \
--with-stream_ssl_preread_module \
--with-cc-opt='-O3' \
--with-cpu-opt=core \
--with-http_sub_module \
--add-module=../nginx-sticky

自己编写脚本

now=`date +%Y%m%d`
mv /var/log/nginx/nginx.log /var/log/nginx/nginx_${now}.log
touch /var/log/nginx/nginx.log
if [ -f /var/run/nginx.pid ]; then 
    kill -USR1 `cat /var/run/nginx.pid`  
fi

tar -czvf /var/log/nginx/nginx_${now}.tar.gz  /var/log/nginx/nginx_${now}.log  --remove-files 

find /var/log/nginx/ -mtime +10  -iname *.tar.gz  -exec rm -rf {} \;

总结

这次仅是进行了一次预演
脚本还没有测试. 最近家里事情比较多. 
有点力不从心, 希望这次记录的脚本没有太大的问题.