Shell自动化实践:日志管理的极简闭环
服务器运维中,日志累积会占用磁盘空间、降低检索效率,手动清理耗时且易出错。本文分享企业级Shell日志自动清理归档脚本,实现全流程自动化,适配新手入门与企业落地,同步拆解核心逻辑与部署步骤。
本文围绕需求分析、脚本实现、核心拆解、落地部署、扩展优化展开,确保脚本可直接复用,逻辑清晰易懂。
一、需求分析:明确自动化核心目标
结合运维场景,脚本需满足5大核心需求,兼顾灵活与健壮:
灵活适配:自定义日志目录、归档目录,无需修改核心逻辑;
精准归档:按修改时间筛选指定天数前日志,压缩留存;
空间释放:自动删除过期归档文件,避免累积爆满;
可追溯:记录脚本执行日志,便于异常排查;
异常防护:参数校验+异常处理,避免脚本崩溃或误操作。
适配:主流Linux发行版,依赖系统自带tar、find等命令,无需额外安装。
二、完整脚本实现:可直接复制落地
脚本命名为log_auto_clean.sh,建议存放于/usr/local/shell/,关键参数可直接修改,注释清晰:
#!/bin/bash
# 脚本名称:log_auto_clean.sh
# 功能:日志自动校验、归档、过期删除,全程无人工干预
# 版本:1.0 适配:CentOS 7+/Ubuntu 18+/Debian 10+
# 日期:2026-02-09 依赖:tar、find、touch、mkdir(系统自带)
# 核心配置参数(按需修改)
LOG_DIR="/var/log/app" # 日志源目录
ARCHIVE_DIR="/data/log_archive" # 归档目录(建议独立磁盘)
ARCHIVE_DAYS=7 # 日志归档阈值(天)
DELETE_DAYS=30 # 归档删除阈值(天)
SCRIPT_LOG="/var/log/log_auto_clean_script.log" # 脚本执行日志
# 日志输出函数(带时间戳、级别)
log_info() {
local msg="$1"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] [INFO] $msg" >> "$SCRIPT_LOG"
}
log_error() {
local msg="$1"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] [ERROR] $msg" >> "$SCRIPT_LOG"
exit 1 # 非0退出,便于告警捕获
}
# 目录校验与初始化(前置检查)
check_dir() {
if [ ! -d "$LOG_DIR" ]; then
log_error "日志源目录 $LOG_DIR 不存在,请检查配置!"
fi
if [ ! -d "$ARCHIVE_DIR" ]; then
log_info "创建归档目录 $ARCHIVE_DIR ..."
mkdir -p "$ARCHIVE_DIR" || log_error "创建归档目录失败!"
fi
local script_log_dir=$(dirname "$SCRIPT_LOG")
if [ ! -w "$script_log_dir" ]; then
log_error "脚本日志目录无写入权限!"
fi
}
# 日志归档(核心功能)
archive_log() {
log_info "开始归档 $ARCHIVE_DAYS 天前的.log日志"
find "$LOG_DIR" -type f -mtime +"$ARCHIVE_DAYS" -name "*.log" | while read -r log_file; do
if [ -f "$log_file" ]; then
archive_file="$ARCHIVE_DIR/$(basename "$log_file")_$(date +'%Y%m%d').tar.gz"
tar -zcf "$archive_file" "$log_file" || log_error "压缩 $log_file 失败!"
log_info "归档成功:$log_file -> $archive_file"
# 可选:归档后删除原日志(取消注释启用)
# rm -f "$log_file" && log_info "已删除原日志:$log_file"
fi
done
local log_count=$(find "$LOG_DIR" -type f -mtime +"$ARCHIVE_DAYS" -name "*.log" | wc -l)
[ "$log_count" -eq 0 ] && log_info "无符合条件日志,归档跳过"
}
# 过期归档删除(核心功能)
delete_archive() {
log_info "开始删除 $DELETE_DAYS 天前的.tar.gz归档"
find "$ARCHIVE_DIR" -type f -mtime +"$DELETE_DAYS" -name "*.tar.gz" -exec rm -f {} \;
log_info "过期归档删除完成"
}
# 主执行流程
main() {
touch "$SCRIPT_LOG" || log_error "创建脚本日志失败!"
log_info "========== 日志自动清理归档脚本(1.0)开始执行 =========="
check_dir
archive_log
delete_archive
log_info "========== 脚本执行完成,全程无异常 ==========\n"
}
# 启动脚本
main三、核心功能拆解:吃透设计逻辑
聚焦脚本核心设计,帮你快速理解逻辑、灵活修改,无需死记硬背。
3.1 配置参数设计
核心思路「参数与逻辑分离」,集中管理可修改项,降低维护成本:
LOG_DIR:日志源目录(如Nginx日志/var/log/nginx);ARCHIVE_DIR:建议独立磁盘存放,避免占用系统盘;ARCHIVE_DAYS:默认7天,保留近期日志便于排查;DELETE_DAYS:默认30天,符合多数企业日志留存规范;SCRIPT_LOG:脚本执行日志,用于异常排查。
3.2 关键函数解析
(1)日志输出函数 log_info/log_error
规范日志格式(时间戳+级别),log_error 异常时退出脚本,便于告警捕获。
(2)目录校验函数 check_dir
脚本执行前校验目录存在性、权限,归档目录不存在时自动创建,提升健壮性。
(3)日志归档函数 archive_log
核心功能:筛选指定天数前的.log文件,压缩归档,生成规范命名,避免重名。
(4)过期归档删除函数delete_archive
批量删除过期归档包,仅删除.tar.gz文件,避免误删,释放磁盘空间。
3.3 主执行流程
按「初始化日志→目录校验→日志归档→过期删除」执行,形成自动化闭环,逻辑清晰。
四、落地部署:实战步骤(新手必看)
3步部署+测试+定时配置,实现全自动化,避免踩坑。
4.1 脚本部署(3步)
# 1. 创建脚本目录
mkdir -p /usr/local/shell
# 2. 创建脚本并复制完整代码
vim /usr/local/shell/log_auto_clean.sh
# 3. 添加可执行权限
chmod +x /usr/local/shell/log_auto_clean.sh4.2 手动测试(关键)
# 手动执行脚本
/usr/local/shell/log_auto_clean.sh
# 查看执行日志,确认正常
tail -f /var/log/log_auto_clean_script.log测试成功:无ERROR日志,出现「执行完成」标识,归档目录有对应压缩包(如有符合条件日志)。
常见排查:权限不足(chmod 755)、目录错误、磁盘爆满(df -h)。
4.3 配置定时执行(核心)
# 编辑crontab任务
crontab -e
# 添加:每天凌晨2点执行(负载最低)
0 2 * * * /usr/local/shell/log_auto_clean.sh > /dev/null 2>&1
# 重启crontab生效(CentOS/Ubuntu分别执行)
systemctl restart crond # CentOS
systemctl restart cron # Ubuntu/Debian说明:0 2 * * *为每天凌晨2点,脚本路径需写绝对路径,屏蔽无用输出。
4.4 日常监控
# 查看近期执行记录
tail -n 10 /var/log/log_auto_clean_script.log
# 检查crontab服务状态
systemctl status crond # CentOS
systemctl status cron # Ubuntu/Debian五、扩展与优化:适配更多场景
基础版脚本可按需扩展,以下为4个常用方向,附核心代码片段。
5.1 多目录支持
适配多应用日志管理,将LOG_DIR改为数组,循环遍历:
LOG_DIRS=("/var/log/nginx" "/usr/local/tomcat/logs" "/var/log/mysql")
# archive_log函数中循环遍历数组,其余逻辑不变5.2 日志大小筛选
仅归档大于指定大小的日志,避免小文件频繁归档:
# 添加-size +100M(仅归档大于100MB日志)
find "$LOG_DIR" -type f -mtime +"$ARCHIVE_DAYS" -name "*.log" -size +100M | while read -r log_file;5.3 邮件告警
脚本失败时发送告警邮件,修改log_error函数,依赖mail命令:
ALERT_EMAIL="ops@example.com" # 运维邮箱
log_error() {
local msg="$1"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] [ERROR] $msg" >> "$SCRIPT_LOG"
echo "$msg" | mail -s "【告警】脚本执行失败" "$ALERT_EMAIL"
exit 1
}5.4 归档校验
校验归档包完整性,避免损坏:
tar -zcf "$archive_file" "$log_file" || log_error "压缩失败!"
# 新增校验
if ! tar -tf "$archive_file" > /dev/null 2>&1; then
log_error "归档包 $archive_file 损坏!"
fi六、总结
本文脚本可直接落地,核心思路为「参数化配置、分函数实现、异常处理、定时执行」,解决日志累积痛点,解放运维双手。
脚本兼具实用性与可扩展性,核心逻辑可举一反三,适配更多运维自动化场景,新手可快速上手,逐步提升自动化能力。