--- title: 自动清理日志脚本 categories: - 基础运维 tags: - bash - cli - 命令行工具 - 脚本 - Crontab abbrlink: lnd7yqpw date: 2023-10-05 21:34:38 --- 公司的业务服务会打日志到磁盘, 程序已经做了日志切割, 时间一长磁盘占满会导致业务异常, 普通的清理逻辑是使用crontab定时删除文件, 比如每天1点删除创建日期超过30天的日志文件, 大部分情况下工作是OK的, 但是执行周期太长, 如果当天日志暴增, 不能及时删除文件. 也会有隐患, 优化版脚本如下: 日志清理分以下几种: 1. 历史日志, 并且未在写入的日志, 这种可以直接删除掉. 2. 当前正在写入的日志, 需要清理, 这种不能删除, 可以通过清空文件的方式来释放空间 > set -euo pipefail 的作用: > set -e: 脚本中有任何一条命令执行失败, 整个脚本就失败 > set -u: 脚本中的变量有任何一个变量为空, 整个脚本执行失败 > -o pipefail: 脚本中的管道中任何一条命令执行失败, 也会认为脚本执行失败 脚本内容: ```bash #!/bin/bash set -uo pipefail # 磁盘的文件系统(df -h里面显示的) FILESYSTEM="/dev/vda1" # 业务日志目录 LOGS_FOLDER="/logs/" # 这里的日志文件不做处理, 一般是需要保留的当天日志. EXCLUDE_LOGS="ingeek-vck-gateway-service.log|ingeek-vck-gateway-trace.log|ipp-gateway-service.log|ipp-gateway-trace.log" # 这里的日志只清空,不删除 TSF_LOGS=( /var/log/tsf/stdout /root/tsf-agent/exec/1255000068/application-nyg9mpa2/group-maeg9ev3/agent.log ) # 清理日志记录 LOG=/root/clean.log # 当前时间 NOW=$(date +'%Y-%m-%d %H:%M:%S') USEAGE=$(df -h | grep -vE 'tmpfs|cdrom' | grep "${FILESYSTEM}" | awk '{print $(NF-1)}' | cut -d "%" -f1) echo "${NOW} filesystem used ${USEAGE}%" >> ${LOG} 2>&1 if [ $USEAGE -ge 80 ]; then for i in ${TSF_LOGS[*]}; do echo "${NOW} clean $i" >> ${LOG} 2>&1 echo "" > $i done logfile=$(ls -t ${LOGS_FOLDER} | grep -Ev ${EXCLUDE_LOGS} | tail -1) echo "${NOW} clean ${logfile}" >> ${LOG} 2>&1 rm -f ${LOGS_FOLDER}${logfile} fi ``` 磁盘使用率低于80%不会执行操作, 所以可以缩短crontab执行的间隔, 我一般设置成5分钟检测一次, crontab 内容: ```bash */5 * * * * /data/tools/clean.sh > /dev/null 2>&1 ``` {% note warning modern %} 注意: crontab最后需要保留一个空行 {% endnote %}