等保使用
使用方法: script.sh -[add|bak|stop] [服务名可以多个]
#!/bin/bash
# 日志备份脚本
CONTROL=$1
shift
ARGS=$@
# 定义参数
{
# 日志保存天数
LOG_EXP_DAY=180
# 每天几点进行备份
CRON_TIME="58 23 * * *"
}
# 加载配置
{
DATE=$(date +%Y-%m-%d)
DOCKER_CMD=$(which docker)
# 获取当前脚本路径
current_path=$(dirname "$(realpath "$0")")
SCRIPT_ABS_PATH=$(realpath "$0")
}
# 获取服务名
function get_service() {
${DOCKER_CMD} ps | grep -i "$1" | awk '{print $NF}'
}
# 输出
function out() {
if [ $# -ge 2 ]; then
local var1=$1
shift
local var2="$@"
echo -e "-> $(date +"%Y-%m-%d %H:%M:%S") -- INFO ${var1} \033[92m${var2}\033[0m"
else
echo -e "-> $(date +"%Y-%m-%d %H:%M:%S") -- INFO \033[92m$@\033[0m"
fi
}
# 错误
function error() {
if [ $# -ge 2 ]; then
local var1=$1
shift
local var2="$@"
echo -e "-> $(date +"%Y-%m-%d %H:%M:%S") -- ERR ${var1} \033[31m${var2}\033[0m"
else
echo -e "-> $(date +"%Y-%m-%d %H:%M:%S") -- ERR \033[31m$@\033[0m"
fi
}
# 清除日志内容
function clear_log() {
[[ ! -f $1 ]] && return
echo '' > $1
out "日志刷新"
}
# 删除超过限定日期的日志
function del_log_file() {
local log_bak_path="$1"
# 查找并删除超过指定天数的日志文件
find ${log_bak_path} -type f -mtime +${LOG_EXP_DAY} -exec rm -f {} \;
out "清除超过 ${LOG_EXP_DAY} 天的日志文件."
}
# 备份docker 上服务运行日志
function log_rotate () {
local log_file_path="" # 日志文件路径
[[ -z $@ ]] && error "服务不存在..." && exit 1
for i in $@ ; do # 考虑多个服务同时进行备份
{
out "开始备份: ${i}..."
[[ -z ${log_file_path} ]] && log_file_path=$(${DOCKER_CMD} inspect --format='{{.LogPath}}' ${i})
# 创建备份目录
local BUCKDIR=${current_path}/${i}_logs
[[ ! -d ${BUCKDIR} ]] && mkdir -p ${BUCKDIR}
# 备份
if [[ -f ${log_file_path} ]]; then
cp ${log_file_path} ${BUCKDIR}/${DATE}_${i}.log
clear_log ${log_file_path} # 刷新日志
fi
out "完成备份: ${i} | " "${BUCKDIR}"
} || error "备份失败: ${i}..."
del_log_file "${BUCKDIR}" # 清除过期日志
done
}
# 定时任务管理 (幂等)
function CRON() {
local action=$1 # 0 添加 1 删除
local servers=$2
[[ -z ${action} ]] && error "添加定时任务失败: 检查参数..." && exit 1
# 构造定时任务的时间和命令
local CRON_COMMAND="/bin/bash ${SCRIPT_ABS_PATH} -bak "${servers}" >> ${current_path}/"${servers}"_buckup_log.log 2>&1"
local CRON_ENTRY="$CRON_TIME $CRON_COMMAND"
# 创建临时的 crontab 文件
TEMP_CRON_FILE=$(mktemp)
if [[ ${action} -eq 0 ]] ;then # 添加定时任务
# 将现有的 crontab 任务导出到临时文件中
crontab -l > "$TEMP_CRON_FILE" 2>/dev/null
if grep -Fxq "$CRON_ENTRY" "$TEMP_CRON_FILE"; then
out "定时备份日志已开启..." "${servers}"
else
# 添加新的定时任务到临时文件中
echo "$CRON_ENTRY" >> "$TEMP_CRON_FILE"
# 将更新后的 crontab 文件安装回去
crontab "$TEMP_CRON_FILE"
# 输出结果
out "定时任务已成功设置。" "${servers}"
fi
elif [[ ${action} -eq 1 ]] ;then # 删除定时任务
crontab -l | grep -Fxv "$CRON_ENTRY" > "$TEMP_CRON_FILE"
# 将更新后的 crontab 文件安装回去
crontab "$TEMP_CRON_FILE"
else
error "非法参数" "${action}"
exit 1
fi
# 删除临时文件
rm "$TEMP_CRON_FILE"
}
# 日志备份
function ROTATE_LOG() {
for arg in ${ARGS}; do
local ser_name=$(get_service ${arg}) # 获取服务名
[[ -z ${ser_name} ]] && error "服务不存在..." "${arg}" && exit 1
case "${arg}" in
"nginx"|"NGINX"|"Ningx"|"redis"|"Redis"|"REDIS"|"minio"|"MINIO"|"Minio")
log_rotate ${ser_name} # 备份日志
;;
*)
error "无法识别参数..."
;;
esac
done
}
# 设置自动备份开关
function CONL_CRON() {
local state=$1
[[ -z ${state} ]] && error "参数错误..." && exit 1
for arg in ${ARGS}; do
case "${arg}" in
"nginx"|"NGINX"|"Ningx")
CRON ${state} "nginx"
;;
"redis"|"Redis"|"REDIS")
CRON ${state} "redis"
;;
"minio"|"MINIO"|"Minio")
CRON ${state} "minio"
;;
*)
error "无法识别参数..."
exit 1
;;
esac
done
echo ""
crontab -l
}
# 主函数
function main() {
[[ -z ${ARGS} ]] && error "请检查你的参数..." && exit 1
# 参数识别
case "${CONTROL}" in
"-add"|"-ADD"|"-Add")
out "添加定时任务..."
CONL_CRON 0
;;
"-bak"|"-Bak"|"-BAK")
out "Start bakcup."
ROTATE_LOG # 备份
;;
"-stop"|"-Stop"|"-del"|"-Del")
out "关闭自动备份..."
CONL_CRON 1
;;
*)
error "无法识别参数..."
;;
esac
}
main