日志清理脚本

2023-11-20

需求背景

解决某些中间件或者应用日志无法自动清理的情况,比如:Nacos 的 access 日志清理,临时目录文件清理等。

简介

Filename         clear-logs.sh
Revision         0.0.3
Date             2020/06/05
Author           jiangliheng
Email            jiang_liheng@163.com
Website          https://github.com/jiangliheng/ops-scripts
Description      删除 N 天前的文件
Copyright        Copyright (c) jiangliheng
License          GNU General Public License

变更记录

  • Version 0.0.3 2020/07/28

增加 支持仅匹配目录类型,默认是查询每个文件并删除

  • Version 0.0.2 2020/07/21
    优化 支持正则表达式匹配日志文件
    增加 支持配置多目录清理
    增加 支持调试模式

  • Version 0.0.1 2020/06/05

  • 删除 N 天前的日志文件,仅删除匹配 “.log” 的日志文件

选项

sh clear-logs.sh [options] <value> ...

  * -p <value>                 删除日志的路径,多个目录用 "," 隔开,如:"/logs1,/logs2"
    -d <value>                 删除 N 天前的日志文件,即保留 N 天日志,默认:7
    -e <value>                 正则表达式匹配日志文件,如:"*.log*"
    -D                         仅匹配目录类型,默认是查询每个文件并删除,即 find 命令增加 “-type d” 参数
    -t                         调试模式,控制台打印日志,不删除日志文件
    --help                     帮助信息
    -v, --version              版本信息

  * 表示必输,& 表示条件必输,其余为可选

示例

1. 清理多个目录中 7 天前的日志文件
sh clear-logs.sh -p /home/nacos/logs,/home/nacos/nacos/logs
sh clear-logs.sh -p /home/nacos/logs,/home/nacos/nacos/logs -d 7

2. 清理 30 天前的日志文件
sh clear-logs.sh -p /home/nacos/logs -d 30

3. 清理 30 天前的匹配正则表达式的日志文件,调试模式
sh clear-logs.sh -p /home/nacos/logs -d 30 -e "*.log*" -t

4. 清理 30 天前的日志目录,调试模式
sh ${SCRIPT_NAME} -p /home/nacos/logs -d 30 -D -t

使用场景

Nacos access 日志清理

crontab 定时任务设置

$ crontab -e
0 1 * * * sh /home/nacos/clear-logs.sh -p /home/nacos/nacos/logs -d 7

clear-logs 日志文件,其中 ERROR 关键字会红色显示:

# cat /tmp/nacos-clear-logs/clear-logs.sh-202006.log
2020-06-07 01:00:01 [ INFO] ====>> Start cleaning up log files: [/home/nacos/nacos/logs]
2020-06-07 01:00:01 [ INFO] -- Clean up log file: [/home/nacos/nacos/logs/access_log.2020-04-02.log]
2020-06-07 01:00:01 [ INFO] ====>> End cleaning up log files: [/home/nacos/nacos/logs]
2020-06-08 01:00:01 [ INFO] ====>> Start cleaning up log files: [/home/nacos/nacos/logs]
2020-06-08 01:00:01 [ERROR] In the [/home/nacos/nacos/logs] directory, the log [7] days ago was not found!
2020-06-08 01:00:01 [ INFO] ====>> End cleaning up log files: [/home/nacos/nacos/logs]

脚本

$ cat clear-logs.sh
#!/bin/bash
#================================================================
# HEADER
#================================================================
#    Filename         clear-logs.sh
#    Revision         0.0.3
#    Date             2020/06/05
#    Author           jiangliheng
#    Email            jiang_liheng@163.com
#    Website          https://jiangliheng.github.io/
#    Description      删除 N 天前的日志
#    Copyright        Copyright (c) jiangliheng
#    License          GNU General Public License
#
#================================================================
#
#  Version 0.0.3 2020/07/28
#     增加 支持仅匹配目录类型,默认是查询每个文件并删除
#
#  Version 0.0.2 2020/07/21
#     优化 支持正则表达式匹配日志文件
#     增加 支持配置多目录清理
#     增加 支持调试模式
#
#  Version 0.0.1 2020/06/05
#     删除 N 天前的日志文件,仅删除匹配  "*.log*"  的日志文件
#
#================================================================
#%名称(NAME)
#%       ${SCRIPT_NAME} - 删除 N 天前的日志
#%
#%概要(SYNOPSIS)
#%       sh ${SCRIPT_NAME} [options] <value> ...
#%
#%描述(DESCRIPTION)
#%       删除 N 天前的日志文件
#%
#%选项(OPTIONS)
#%       * -p <value>                 删除日志的路径,多个目录用 "," 隔开,如:"/logs1,/logs2"
#%         -d <value>                 删除 N 天前的日志文件,即保留 N 天日志,默认:7
#%         -e <value>                 正则表达式匹配日志文件,如:"*.log*"
#%         -D                         仅匹配目录类型,默认是查询每个文件并删除,即 find 命令增加 “-type d” 参数
#%         -t                         调试模式,控制台打印日志,不删除日志文件
#%         --help                     帮助信息
#%         -v, --version              版本信息
#%
#%       * 表示必输,& 表示条件必输,其余为可选
#%
#%示例(EXAMPLES)
#%
#%       1. 清理多个目录中 7 天前的日志文件
#%       sh ${SCRIPT_NAME} -p /home/nacos/logs,/home/nacos/nacos/logs
#%       sh ${SCRIPT_NAME} -p /home/nacos/logs,/home/nacos/nacos/logs -d 7
#%
#%       2. 清理 30 天前的日志文件
#%       sh ${SCRIPT_NAME} -p /home/nacos/logs -d 30
#%
#%       3. 清理 30 天前的匹配正则表达式的日志文件,调试模式
#%       sh ${SCRIPT_NAME} -p /home/nacos/logs -d 30 -e "*.log*" -t
#%
#%       4. 清理 30 天前的日志目录,调试模式
#%       sh ${SCRIPT_NAME} -p /home/nacos/logs -d 30 -D -t
#%
#================================================================
# END_OF_HEADER
#================================================================

# header 总行数
SCRIPT_HEADSIZE=$(head -200 "${0}" |grep -n "^# END_OF_HEADER" | cut -f1 -d:)
# 脚本名称
SCRIPT_NAME="$(basename "${0}")"
# 版本
VERSION="0.0.3"

# 默认保留 7 天
DAYS=7
# 脚本执行日志目录
CLEAR_LOGS_LOG_PATH=/tmp/$(whoami)-clear-logs
# 日志文件
LOGFILE=${CLEAR_LOGS_LOG_PATH}/${SCRIPT_NAME}-$(date +%Y%m).log

# usage
function usage() {
  head -"${SCRIPT_HEADSIZE:-99}" "${0}" \
  | grep -e "^#%" \
  | sed -e "s/^#%//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" -e "s/\${VERSION}/${VERSION}/g"
}

# 初始化创建脚本日志目录
function init() {
  # 目录不存在,则创建
  if [ ! -d "${CLEAR_LOGS_LOG_PATH}" ]
  then
    mkdir -p "${CLEAR_LOGS_LOG_PATH}"
  fi

  # 日志文件不存在,则创建
  if [ ! -f "${LOGFILE}" ]
  then
    touch "${LOGFILE}"
  fi
}

# 记录 INFO log
function infoLog() {
  # 判断调试模式,调试模式时,打印到控制台
  if [ -n "${TEST_MODE}" ]
  then
    echo "$(date "+%Y-%m-%d %H:%M:%S") [ INFO] ${1}"
  else
    echo "$(date "+%Y-%m-%d %H:%M:%S") [ INFO] ${1}" >> "${LOGFILE}"
  fi
}

# 记录 ERROR log
function errorLog() {
  # 判断调试模式,调试模式时,打印到控制台
  if [ -n "${TEST_MODE}" ]
  then
    echo -e "$(date "+%Y-%m-%d %H:%M:%S") \033[31m[ERROR]\033[0m ${1}"
  else
    echo -e "$(date "+%Y-%m-%d %H:%M:%S") \033[31m[ERROR]\033[0m ${1}" >> "${LOGFILE}"
  fi
}

# 清理 log
function clearLog() {
  # 清理目录
  clear_log_path=${1}

  infoLog "====>> Start cleaning up log files: [${clear_log_path}]"
  cd "${clear_log_path}" || exit

  # 查询要清理的文件
  if [ -n "${REGULAR_EXPRESSION}" ]
  then
    if [ -n "${TYPE}" ]
    then
      clear_log_files=$(find "${clear_log_path}" -mtime +${DAYS} -name "${REGULAR_EXPRESSION}" -type d)
    else
      clear_log_files=$(find "${clear_log_path}" -mtime +${DAYS} -name "${REGULAR_EXPRESSION}")
    fi
  else
    if [ -n "${TYPE}" ]
    then
      clear_log_files=$(find "${clear_log_path}" -mtime +${DAYS} -type d)
    else
      clear_log_files=$(find "${clear_log_path}" -mtime +${DAYS})
    fi
  fi

  # 没有找到匹配文件,记录日志
  if [ -z "${clear_log_files}" ]
  then
    errorLog "In the [${clear_log_path}] directory, the log [${DAYS}] days ago was not found!"
  # 否则开始清理
  else
    # 临时记录要清理的文件
    echo "${clear_log_files}" > log_files.tmp

    # 循环清理日志文件
    while IFS= read -r item
    do
      # 判断调试模式,调试模式时,不删除文件
      if [ -z "${TEST_MODE}" ]
      then
        rm -rf "${item}"
      fi

      infoLog "-- Clean up log file: [${item}]"
    done < log_files.tmp

    # 删除临时文件
    rm log_files.tmp
  fi

  infoLog "====>> End cleaning up log files: [${clear_log_path}]"
}

# 主方法
function main() {
  # 初始化
  init

  # 参数必输校验
  if [ -z "${LOGS_PATH}" ]
  then
    printf "Parameter [-p] is required!\n"
    exit 1
  fi

  # 数字合法性校验,且必须大于 0,即至少保留1if ! [ "${DAYS}" -gt 0 ] 2>/dev/null
  then
    printf "Parameter [-d] must be a number greater than 0!\n"
    exit 1
  fi

  # 多目录判断
  result=$(echo "${LOGS_PATH}" | grep ",")
  # 多个目录
  if [[ "X${result}" != "X" ]]; then
    # 转换为数组
    logs_path_array=${LOGS_PATH//,/ }

    # 循环清理
    for path in ${logs_path_array}
    do
      # 目录合法性校验
      if [ ! -d "${path}" ]
      then
       printf "[%s] is not a directory!\n" "${path}"
       exit 1
      fi

      clearLog "${path}"
    done
  # 一个目录
  else
    # 目录合法性校验
    if [ ! -d "${LOGS_PATH}" ]
    then
     printf "[%s] is not a directory!\n" "${LOGS_PATH}"
     exit 1
    fi

    clearLog "${LOGS_PATH}"
  fi
}

# 判断参数个数
if [ $# -eq 0 ];
then
  usage
  exit 1
fi

# getopt 命令行参数
if ! ARGS=$(getopt -o vtDd:e:p: --long help,version -n "${SCRIPT_NAME}" -- "$@")
then
  # 无效选项,则退出
  exit 1
fi

# 命令行参数格式化
eval set -- "${ARGS}"

while [ -n "$1" ]
do
  case "$1" in
    -p)
      LOGS_PATH=$2
      shift 2
      ;;

    -d)
      DAYS=$2
      shift 2
      ;;

    -e)
      REGULAR_EXPRESSION=$2
      shift 2
      ;;

    -t)
      TEST_MODE=true
      shift;;

    -D)
      TYPE=true
      shift;;

    -v|--version)
      printf "%s version %s\n" "${SCRIPT_NAME}" "${VERSION}"
      exit 1
      ;;

    --help)
      usage
      exit 1
      ;;

    --)
      shift
      break
      ;;

    *)
      printf "%s is not an option!" "$1"
      exit 1
      ;;

  esac
done

main

参考链接:
日志清理脚本-V0.0.3(增加多目录清理、正则表达式匹配、调试模式;部分细节优化):https://mp.weixin.qq.com/s/IV2WSUUW-NQ6Ee93e6A22g

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

日志清理脚本 的相关文章

随机推荐

  • 深聊测开领域之:虫剂悖论

    测试免疫 1 初识虫剂悖论 2 应对虫剂悖论 2 1 更新测试策略 2 2 更新测试用例 1 初识虫剂悖论 提到 虫剂悖论 pesticide paradox 我相信很多人都没听说的 除非是生物学专业的同学或者砖家 虫剂悖论描述的是重复使用
  • Log4j2突发重大漏洞之解决方案

    漏洞描述 Apache Log4j2是一款优秀的Java日志框架 与Logback平分秋色 大量主流的开源框架采用了Log4j2 像Apache Struts2 Apache Solr Apache Druid Apache Flink等均
  • wget: 无法解析主机地址

    root hadoop102 wget O etc yum repos d CentOS Base repo http mirrors aliyun com repo Centos 6 repo 2018 10 09 14 22 53 ht
  • 云服务器车牌识别系统,人脸识别/车牌识别系统安防视频云服务EasyCVR支持大华SDK语音对讲...

    TSINGSEE青犀视频平台EasyCVR内 已经能够通过国标GB28181协议实现语音对讲功能 在大华SDK的研发方面 也开发了该功能 本文和大家分享下 EasyCVR语音对讲主要用于实现本地平台与前端设备所处环境间的语音交互 解决本地平
  • SQLite的shell简单使用

    下载最新的shell for windows http www sqlite org sqlite shell win32 x86 3070800 zip 解压后得到 sqlite3 exe1 1 创建数据库 C sqlite3 gt sq
  • 使用moment.js推算当前时间的前多少天

    在项目中遇到一个问题 推算当前时间的前7天 30天 当然使用js一点点推算可以的 但是可以使用moment js 简单就可以推算出来 获取当前时间 moment format YYYY MM DD HH mm ss 当前时间的前7天 mom
  • QLineEdit和QPushButton实现了输入用户名、密码并验证的功能

    使用QLineEdit和QPushButton实现了输入用户名 密码并验证的功能 该程序使用正则表达式限制了用户名和密码只能包含数字 字母和下划线 且长度在4到16个字符之间 如果输入的用户名和密码符合要求 则弹出一个消息框显示 登录成功
  • 【安装篇】- 基于 VMWARE Oracle Linux7.9 安装 Oracle19c RAC 详细配置方案

    作者 yanwei 来源 墨天轮 https www modb pro db 95684 大家好 我是 JiekeXu 很高兴又和大家见面了 今天和大家一起来看看 Linux7 9 安装 Oracle19c RAC 详细配置方案 欢迎点击上
  • Mockito的使用(二)——@InjectMocks、@Spy、@Mock

    项目中 有些函数需要处理某个服务的返回结果 而在对函数单元测试的时候 又不能启动那些服务 这里就可以利用Mockito工具 其中有如下三种注解 InjectMocks 创建一个实例 简单的说是这个Mock可以调用真实代码的方法 其余用 Mo
  • 鸿蒙系统可以微信吗,鸿蒙系统可以用微信吗?微信鸿蒙版本下载-游戏大玩家...

    微信是一款由腾讯开发的聊天社交软件 在这里你可以去进行和更多好友的交流 我们给你提供了多种不同的交流模式 享受更加独特的交流带给你的全新体验 使用语音 文字 表情包 图片 视频等等都种不同的方式 我们让大家们的交流更加的便利起来 微信鸿蒙版
  • Python+Opencv 调用USB摄像头(一)

    一 最简单的调用笔记本内置相机 import cv2 引入库 cap cv2 VideoCapture 0 while True ret frame cap read cv2 imshow Video frame 读取内容 if cv2 w
  • 10 微服务流程规范篇:高速迭代的研发过程需要怎样的规范?

    上一课时 我讲解了微服务质量保障体系的全景概览 本课时我主要讲解流程规范 高速迭代的研发过程需要怎样的规范呢 业务流程阶段 众所周知 产品研发是为业务服务的 在深入讲解产品研发流程之前 我们先整体看下业务流程 分为 3 个阶段 产品研发阶段
  • C++新特性

    std bind 概述 std bind 是一个C 函数模板 简单说它就像一个函数适配器 用来接受一个可调用对象 callable object 生成一个新的可调用对象来 适应 原对象的参数列表 该函数模板定义在头文件 include
  • Ubuntu - OpenSSH安装或升级

    1 准备安装包 openssl 1 0 2o tar gz wget https www openssl org source openssl 1 0 2o tar gz https www openssl org source opens
  • 插入排序超详解释,一看就懂

    目录 一 插入排序的相关概念 1 基本思想 2 基本操作 有序插入 二 插入排序的种类 三 直接插入排序 1 直接插入排序的过程 顺序查找法查找插入位置 2 使用 哨兵 直接插入排序 四 直接插入排序算法描述 五 折半插入排序 1 查找插入
  • linux 操作mysql 命令_linux下mysql操作命令大全

    Linux下掌握基本的mysql操作命令大全能够为你学习linux中mysql提供更好的帮助 下面由学习啦小编为大家整理了linux下mysql操作命令大全的相关知识 希望对大家有帮助 linux的mysql操作命令大全详解 linux的m
  • uniapp.request遇到的坑

    uniapp request遇到的坑 发起post请求的时候data接收不到参数 解决 发起请求中添加 uni request header content type application x www form urlencoded
  • 索引优化之Explain 及慢查询日志

    索引 本质是数据结构 简单理解为 排好序的快速查找数据结构 以索引文件的形式存储在磁盘中 目的 提高数据查询的效率 优化查询性能 就像书的目录一样 优势 提高检索效率 降低IO成本 排好序的表 降低CPU的消耗劣势 索引实际也是一张表 该表
  • Java 实现MySQL数据库插入1000万条数据

    Java 实现MySQL数据库插入1000万条数据 针对某些特殊测试 需要添加大量数据 且这些测试具有一定的规律性 可以按照以下的sql脚本循环添加 可以是1000条 也可以是一百万条 Java实现 准备表一张 CREATE TABLE t
  • 日志清理脚本

    需求背景 解决某些中间件或者应用日志无法自动清理的情况 比如 Nacos 的 access 日志清理 临时目录文件清理等 简介 Filename clear logs sh Revision 0 0 3 Date 2020 06 05 Au