项目上线时,在服务器搭建了nginx 环境后就开始运行了,没有设置 nginx 日志等配置,都是采用默认策略,日志存储位置:
../nginx/logs/access.log
,并且只会放在一个日志文件中,无法像 Logback 按日 期输出文件,导致 access.log 越来越大。Nginx 这些日志文件在悄无声息地膨胀,直到某一天,磁盘空间告急,应用异常宕机,还会导致占用服务器磁盘且排查日志时间长,搜索了一些解决方法后,整理成本文,希望此方案可以解决日志文件此类问题。
本文针对的是已经正在线上运行的 nginx 服务,如果是从零开始配置,直接跳到第4步、第5步即可。
1、关闭文件句柄占用
分片日志前把需要把历史文件清理,减少磁盘占用,如果需要历史文件记得请先备份文件。
先关闭 nginx 日志记录功能,在 /nginx/conf/nginx.conf 文件中 http 模块中 access_log 设置为 off,并重启 nginx ;
检查文件并重启命令:./nginx/sbin/nginx -t``./nginx/sbin/nginx -s reload
http {
include mime.types;
default_type application/octet-stream;
...
access_log off;
error_log off;
...
}
重启完成后,检查该日志文件是否还有句柄占用(句柄占用就表示还有进程占用文件,即使删除文件也不生效,无法释放磁盘,所以需要先关闭进程),检查句柄占用的命令:lsof access.log
,此时命令无内容输出就可以了。
2、清空历史日志
清空日志的命令:echo "" > access.log
。这条命令执行效率很高,清理60G的文件对系统性能毫无影响。
3、开启日志记录功能
日志清理完后,再把/nginx/conf/nginx.conf
文件中 http 模块中 access_log
直接注释掉再重启 nginx 就可以了。
http {
include mime.types;
default_type application/octet-stream;
...
#access_log off;
#error_log off;
...
}
4、执行日志分片脚本
日志脚本 nginx_log_split.sh
放在 ../nginx/logs
下面,和 access.log
所在目录同级,需要给脚步可执行权限 chmod 774 nginx_log_split.sh
。
执行脚本就可看到效果,会自动创建 history_log 文件夹,会将日志文件按月份分文件夹,按天级别存储。如果线上访问量非常大的话,也可以按小时级别分片。
sh nginx_log_split.sh
#!/bin/bash
# 此处请设置nginx 绝对路径
nginx_home=/home/user/nginx/
nginx_log_path=${nginx_home}logs/
current_date=$(date +%Y-%m-%d)
access_log_file_name=access.log
error_log_file_name=error.log
history_file_path=${nginx_home}logs/history_log/$(date +%Y-%m)
# check if the nginx server alive
if [ -e ${nginx_log_path}nginx.pid ];then
# create log folder for nginx log file
if [ ! -e ${history_file_path} ];then
mkdir -p ${history_file_path}
echo "$(date) create folder success"
fi
# rename the log file with current date
if [ -e $nginx_log_path$access_log_file_name ];then
mv ${nginx_log_path}${access_log_file_name} ${history_file_path}/access-${current_date}.log
echo "$(date) rename access.log successfully"
else
echo "$(date) access.log file no exist,skip"
fi
if [ -e $nginx_log_path$error_log_file_name ];then
mv ${nginx_log_path}${error_log_file_name} ${history_file_path}/error-${current_date1}.log
echo "$(date) rename error.log successfully"
else
echo "$(date) error.log file no exist,skip"
fi
# reopen the nginx server log
${nginx_home}/sbin/nginx -s reopen
echo "$(date) reload log file success"
else
echo "$(date) nginx server is close,skip"
fi
5、脚本设置定时执行
我们希望日志每天都能自动分片,每天拆分成一个文件,所以只需要设置脚本定时执行即可。Centos 有定时任务功能,设置 Corn 表达式,就会自动执行了。
查看当前的定时任务列表:crontab -l
,编辑定时任务: crontab -e
每天23点59分分割日志
59 23 * * * /home/user/nginx/logs/nginx_log_split.sh > /home/user/nginx/logs/history_log/execute.log 2>&1
执行脚本的输出日志会重定向到 …/nginx/logs/history_log/execute.log 。
以上,Nginx 日志文件就实现自动分片,运行效果良好。 error.log 分片方法同上。
评论区