Nginx切割

lishihuan大约 7 分钟

Nginx切割

需要保留Nginx6个月日志

https://zhuanlan.zhihu.com/p/431186457open in new window

https://blog.csdn.net/xiaojin21cen/article/details/122309230open in new window

https://www.cnblogs.com/cherishthepresent/p/17552749.htmlopen in new window

https://www.cnblogs.com/even160941/p/13903291.htmlopen in new window

https://linux.cn/article-4126-1.htmlopen in new window

https://www.jb51.net/article/248232.htmopen in new window

1. Linux 日志管理工具 | logrotate

Linux日志管理工具logrotate

安装:yum -y install logrotate crontabs

2. 配置logrotate

/etc/logrotate.d/目录下,创建一个名为nginx的文件,

vim /etc/logrotate.d/nginx

内容如下:

这个配置将每天切换一次日志,并保留180天的日志。日志文件切换后,Nginx将会开始写入新的日志文件。

额外说明: 脚本中不可添加注释

/usr/local/nginx/logs/*.log {
    daily ## 转储周期设置  daily:指定转储周期为每天、weekly:指定转储周期为每周、monthly:指定转储周期为每月
    rotate 180 ## 结合daily 使用,这里实现 日志保留180天
    copytruncate#备份日志并截断
    delaycompress#转储的日志到下一次转储时才压缩
    compress#转储后使用gzip压缩
    notifempty#日志为空时不处理
    missingok#切割中遇到日志错误忽略
    dateext#在转储后的日志加上日期做后缀
    dateformat -%Y%m%d#指定日期的格式
}

参数说明:

  • daily:转储周期设置 可选值为 daily:天,monthly:月,weekly:周,yearly:年

  • rotate:日志文件保存的轮数,0指没有备份

logrotate配置中,rotate属性是一个关键参数,它指定了日志文件保存的轮数(或版本数)。当一个日志文件达到指定的轮数后,logrotate会按照配置执行一系列操作,比如:

  1. 文件重命名:它将当前的日志文件(例如access.log)重命名为access.log.1
  2. 创建新文件:创建一个新日志文件,继续记录新的日志,比如access.log
  3. 压缩旧文件:如果配置中包含了compress指令,旧的备份文件(如access.log.1)会压缩为.gz格式,便于存储和管理。

rotate值的含义是,当一个文件达到该数字后,就会创建一个新的文件,循环进行,老文件的备份会保留指定的轮数。例如,rotate 180表示日志文件将被保存180个版本,也就是180天,然后会被新的日志文件替换。

以下是一个例子:

yaml复制代码access_log /path/to/access.log common rotate 30

这表示access.log的日志文件将会保留30个版本,每30天创建一个新的线性备份文件,如access.log.1access.log.2直到access.log.30,当超过30天后,最旧的access.log.1会被删除。

请注意,logrotate默认的配置是每天创建一个文件,如果要保留一定天数的文件,你需要结合dailyrotate指令一起使用。

  • copytruncate: 用于还在打开中的日志文件,把当前日志备份并截断

    在备份日志文件后将原文件清空,而不是创建新文件。这对于不能重新打开日志文件的服务(如一些老版本的Nginx)很有用。

  • delaycompress:转储的日志到下一次转储时才压缩

    总是与compress选项一起用,delaycompress选项指示logrotate不要将最近的归档压缩,压缩将在下一次轮循周期进行。这在你或任何软件仍然需要读取最新归档时很有用

  • dateext:使用日期作为命名格式

  • **compress:**在轮循任务完成后,已轮循的归档将使用gzip进行压缩

  • **nocompress:**如果你不希望对日志文件进行压缩,设置这个参数即可

  • **notifempty:**如果日志文件为空,轮循不会进行

  • **sharedscripts:**表示postrotate脚本在压缩了日志之后只执行一次

  • **create 0644 nginx root:**以指定的权限创建全新的日志文件,同时logrotate也会重命名原始日志文件

  • **postrotate或endscript:**最通常的作用是让应用重启,以便切换到新的日志文件, 在所有其它指令完成后,postrotate和endscript里面指定的命令将被执行。在这种情况下,rsyslogd 进程将立即再次读取其配置并继续运行

3. 配置cron任务

logrotate的执行通常由cron任务进行调度。我们需要设置一个cron任务,在每天特定的时间(如凌晨1点)执行logrotate

首先,打开crontab编辑器:

crontab -e

然后,添加以下行到crontab文件:

0 1 * * * /usr/sbin/logrotate /etc/logrotate.d/nginx
## 或者
0 1 * * * /usr/sbin/logrotate /etc/logrotate.d/nginx >> /var/log/logrotate.log

这将在每天凌晨1点执行logrotate,并使用我们在/etc/logrotate.d/nginx文件中定义的规则。

保存并关闭crontab文件。现在,你的Nginx服务器应该已经配置好了每天凌晨1点切换日志,并保留180天的日志。

0 1 * * * Cron 表达式说明

  • 0:表示分钟,这里是第0分钟。
  • 1:表示小时,这里是第1小时,也就是凌晨1点。
  • *:第一个星号代表一月中的哪一天,星号表示每一天。
  • *:第二个星号代表月份,星号表示每个月。
  • *:第三个星号代表一周中的哪一天,星号表示每一天。

cron状态检查

sudo service crond status
sudo service crond start

说明:

可能会出现执行后,没有看到nginx被切换,这个是因为logrotate 认为当前的日志文件还不需要切割

  • 可以通过 /usr/sbin/logrotate -f /etc/logrotate.d/nginx 命令强行执行 切割日志文件
  • sudo logrotate --debug /etc/logrotate.d/nginx 选项来测试配置文件
[root@localhost log]# sudo logrotate --debug /etc/logrotate.d/nginx  ## 测试配置文件
reading config file /etc/logrotate.d/nginx
Allocating hash table for state file, size 15360 B ## logrotate 创建了一个大小为 15360 字节的哈希表来保存状态文件

Handling 1 logs ## 正在处理 1 个日志文件

rotating pattern: /usr/local/nginx/logs/*.log  after 1 days (180 rotations) ## 的设置是每隔 1 天轮转一次日志文件,最多保留 180 份轮转的日志。
empty log files are not rotated, old logs are removed ## 空的日志文件不会被轮转,旧的日志文件会被删除。
considering log /usr/local/nginx/logs/access.log ## logrotate 正在考虑是否需要轮转 access.log 文件。
  log does not need rotating (log has been rotated at 2024-4-28 12:18, that is not day ago yet) ## access.log 文件不需要轮转,因为它在不到一天前的时间(2024-4-28 12:18)已经被轮转过了。
considering log /usr/local/nginx/logs/error.log
  log does not need rotating (log has been rotated at 2024-4-28 11:19, that is not day ago yet) ## error.log 文件不需要轮转,因为它在不到一天前的时间(2024-4-28 11:19)已经被轮转过了

就上面的内容来说,这个输出 logrotate 读取了配置文件,并根据配置文件的设置考虑了是否需要轮转 access.logerror.log 文件。但是,由于这些文件在不到一天前已经被轮转过了,因此 logrotate 认为这些文件现在不需要轮转。

4. 启动命令

后期是用 cron 任务进行执行,下面的命令不用执行

可以通过logrotate -vf /etc/logrotate.d/nginx 进行检查是否能正常执行

logrotate /etc/logrotate.conf # 启动所有配置的日志管理

logrotate /etc/logrotate.d/xxx # 启动xxx服务的日志管理

logrotate -f /etc/logrotate.d/xxx # 强制生效,执行一次

logrotate -vf /etc/logrotate.d/nginx # 强制生效,执行一次,同时打印执行信息 --

其他方式

也可以通过写脚本实现对日志的切割,没有尝试过

https://www.cnblogs.com/zhupengfei/p/14787060.htmlopen in new window

1. 创建clearNginxLog.sh文件

#!/bin/bash

LOG_PATH="/data/nginx/log/"
save_days=1
YESTERDAY=$(date -d "yesterday" +%Y%m%d)
echo "———————————————–"
echo "运行时间:[$(date +"%Y-%m-%d %H:%M:%S")]"
#删除指定日期以前的文件
echo "删除[$save_days]天以前的日志文件"
#find $LOG_PATH -mtime +$save_days -exec rm -rf {} \;
find $LOG_PATH -mtime +$save_days -type f -name \*.log | xargs rm -f

# 循环文件重命名
echo "循环文件重命名"
#for f in $LOG_PATH*.log; do cp $f ${f%.html}.php; done
for var in $LOG_PATH*.log; do mv "$var" "${var%.log}_$YESTERDAY.log"; done

#向nginx主进程发送USR1信号,重新打开日志文件,否则会继续往mv后的文件写数据的。原因在于:linux系统中,内核是根据文件描述符来找文件的。如果不这样操作导致日志切割失败。
echo "向nginx发送信号"
kill -USR1 `ps axu | grep "nginx: master process" | grep -v grep | awk '{print $2}'`

echo "清理完成"
echo "———————————————–"

2. crontab中添加任务

crontab -e

每天0点执行

0 0 * * * /data/nginx/conf/clearNginxLog.sh >> /var/log/clearNginx.log 2>&1

:q!退出 :wq保存退出

然后重启crontab服务 --- 不确定是否需要重启

  • 其他脚本
#!/bin/bash
path=/data/log/nginx
nginx=$(cat /usr/local/nginx/logs/nginx.pid)
date_dir=$(date +%Y%m%d)
if [ ! -d $path/$date_dir ]
then
  # TODO: handle this
  mkdir $path/"$date_dir"
  true
fi

mv $path/access.log $path/"$date_dir"/access_"$date_dir".log
kill -USR1 $nginx       #使用USR1参数通知Nginx进程切换日志文