学而实习之 不亦乐乎

Linux 下 Nginx 日志配置及切割

2023-11-11 19:29:54

一、Nginx 日志配置

日志句法:

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

默认: access_log logs / access.log合并;

语境: http,server,location,if in location,limit_except

  1. [buffer=size] 设置缓冲日志写入的路径,格式和配置。
  2. gzip[=level] 如果使用该gzip参数,则在写入文件之前,缓冲的数据将被压缩。压缩级别可以设置在1(最快,较少压缩)和9(最慢,最佳压缩)之间。默认情况下,缓冲区大小等于64K字节,压缩级别设置为1.由于数据是以原子块压缩的,因此日志文件可以随时解压或由“ zcat” 读取。
  3. [flush=time]  保存在缓存区中的最长时间。

示例如下:

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;
  • remote_addr, $http_x_forwarded_for 记录客户端IP地址
  • remote_user 记录客户端用户名称
  • request 记录请求的URL和HTTP协议
  • status 记录请求状态
  • body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。
  • bytes_sent 发送给客户端的总字节数。
  • connection 连接的序列号。
  • connection_requests 当前通过一个连接获得的请求数量。
  • msec 日志写入时间。单位为秒,精度是毫秒。
  • pipe 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。
  • http_referer 记录从哪个页面链接访问过来的
  • http_user_agent 记录客户端浏览器相关信息
  • request_length 请求的长度(包括请求行,请求头和请求正文)。
  • request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。
  • time_iso8601 ISO8601标准格式下的本地时间。
  • time_local 通用日志格式下的本地时间。

二、日志的切割

1、使用 logrotate 工具

方式一:在 /etc/logrotate.d/下添加切割日志的任务。

添加或修改 /etc/logrotate.d/nginx ,这种方式不需要自行在 crontab 中自行添加计划任务。如下:

# cat /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily
    missingok
    rotate 7
    dateext
    # compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

在该配置文件中,每个参数作用如下:

  • /var/log/nginx/为nginx日志的存储目录,可以根据实际情况进行修改。
  • daily:日志文件将按天轮循。
  • weekly:日志文件将按周轮循。
  • monthly:日志文件将按月轮循。
  • missingok:在日志轮循期间,任何错误将被忽略,例如“文件无法找到”之类的错误。
  • rotate 7:一次存储7个日志文件。对于第8个日志文件,时间最久的那个日志文件将被删除。
  • dateext:定义日志文件后缀是日期格式,也就是切割后文件是:xxx.log-20160402.gz这样的格式。如果该参数被注释掉,切割出来是按数字递增,即前面说的 xxx.log-1这种格式。
  • compress:在轮循任务完成后,已轮循的归档将使用gzip进行压缩。
  • delaycompress:总是与compress选项一起用,delaycompress选项指示logrotate不要将最近的归档压缩,压缩将在下一次轮循周期进行。这在你或任何软件仍然需要读取最新归档时很有用。
  • notifempty:如果是空文件的话,不进行转储。
  • create 640 nginx adm:以指定的权限和用书属性,创建全新的日志文件,同时logrotate也会重命名原始日志文件。
  • postrotate/endscript:在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。在这种情况下,rsyslogd进程将立即再次读取其配置并继续运行。注意:这两个关键字必须单独成行。

方式二:结合 crontab 使用 logrotate 工具

定义日志轮滚策略

# vim nginx-log-rotate

/data/weblogs/*.log {
    nocompress
    daily
    copytruncate
    create
    notifempty
    rotate 7
    olddir /data/weblogs/old_log
    missingok
    dateext
    postrotate
        /bin/kill -HUP `cat /var/run/nginx.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

/data/weblogs/*.log使用通配符时,/data/weblogs/目录下的所有匹配到的日志文件都将切割。如果要切割特定日志文件,就指定到该文件。

需要注意的是你们的nginx.pid位置,不一定是在/usr/local/nginx/nginx.pid

设置计划任务

59 23 * * * root ( /usr/sbin/logrotate -f /PATH/TO/nginx-log-rotate)

2、使用 shell 脚本

按天进行日志切割,脚本如下:

#!/bin/bash

year=`date +%Y`
month=`date +%m`
day=`date +%d`
logs_backup_path="/usr/local/nginx/logs_backup/$year$month" #日志存储路径
logs_path="/usr/local/nginx/logs/" #要切割的日志路径
logs_access="access" #要切割的日志
logs_error="error"
pid_path="/usr/local/nginx/logs/nginx.pid" #nginx的pid
[ -d $logs_backup_path ]||mkdir -p $logs_backup_path
rq=`date +%Y%m%d`
#mv ${logs_path}${logs_access}.log ${logs_backup_path}/${logs_access}_${rq}.log
mv ${logs_path}${logs_error}.log ${logs_backup_path}/${logs_error}_${rq}.log
kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)

设置计划任务

# crontab –e
59 23 * * * bash /usr/local/nginx/shell/cut_ngnix_log.sh   #每天23:59分开始执行;