因为之前装了 fail2ban,对日志进行了一个统一管理,但是 nginx 本身不具备日志切割的功能,于是就导致了日志日积月累的庞大,面对一天十几万的 ssh 等各种乱七八糟的攻击请求,产生的日志不计其数,有必要进行每日切割。
解决办法:脚本 + 定时任务
原理:将日志以日期进行备份,再清除日志文件内容,达到类似切割的效果。
对于仅有一份日志的情况下脚本这样写:
#!/bin/bash log_path=/usr/local/nginx/logs/access.log save_path=/usr/local/nginx/logs/bak/access_$(date +%Y%m%d -d 'yesterday').log cp $log_path $save_path && echo > $log_path
但我的情况以及很多人的情况肯定不会是只有一份日志,那么就需要用循环来解决了。
logcut.sh 内容如下(遍历文件 取文件名 按文件名创建文件夹 再清空日志):
#!/bin/bash base_path=/path/to/nginx_log backup_path=/path/to/log_backup for log_path in $base_path/*; do log_name=$(basename $log_path .log) dstDir=$backup_path/$log_name if [ ! -d dstDir ]; then mkdir -p $dstDir fi save_path=$dstDir/log_$(date +%Y%m%d -d 'yesterday').log cp $log_path $save_path && echo >$log_path done
创建定时任务:
$crontab -e
输入内容:
0 0 * * * /path/to/logcut.sh #每天的00:00执行日志切分
查看定时任务是否添加成功:
crontab -l
后续
经过多次迭代,最后找 GPT 优化了一个最终版:
#!/bin/bash
# 默认选择为备份
idx='backup'
# 处理用户输入
if [ -z "$1" ]; then
echo ""
echo " backup: backup log now."
echo " clean: clean backup log"
echo ""
read -p "Please input: " idx
else
idx="$1"
fi
# 配置路径
log_path="/path/to/nginx_log"
backup_dst="/path/to/log_backup"
backup_log() {
for log_file in "$log_path"/*.log; do
# 检查日志文件是否存在,避免处理不存在的文件
[ -e "$log_file" ] || continue
# 获取文件名(去除路径和扩展名)
log_name=$(basename "$log_file" .log)
save_dir="$backup_dst/$log_name"
# 创建保存目录(如果不存在)
[ ! -d "$save_dir" ] && mkdir -p "$save_dir"
# 生成备份文件名
save_dst="$save_dir/log_$(date +%Y%m%d -d 'yesterday').log"
# 备份日志并清空原始日志
cp "$log_file" "$save_dst" && : > "$log_file"
# 更新备份目录的修改时间
touch "$save_dir"
done
# 更新备份目录本身的修改时间
touch "$backup_dst"
}
clean_log() {
find "$backup_dst" -type f -mtime +60 -exec rm -rfv {} \;
}
# 根据用户输入执行操作
case "$idx" in
backup)
echo "Backup log start."
backup_log
;;
clean)
echo "Clean log start."
clean_log
;;
*)
echo "Invalid, exit!"
;;
esac
以上。
参考:
本站由以下主机服务商提供服务支持:
0条评论