默认tomcat运行产生的日志catalina.out文件不会自动分割,会一直不断累积增多,长此以往会影响服务器性能,如果服务器硬盘空间不是很大,很可能会超过磁盘空间,影响tomcat运行。
同时运维人员查看日志时,如果日志文件过大,打开日志也是问题,解决方法是把日志catalina.out文件进行分割处理。对应传统部署方式使用cronolog进行日志切割,但对于云模式容器化部署,这种方式改动较大,最终考虑通过脚本分割日志文件,并且编写脚本定时删除过久日志,本文将对实现的全过程进行记录。
1整体介绍
对于Linux系统安全来说,日志文件是极其重要的工具,管理好海量的日志文件对管理有重大意义。本文将介绍一些实用的日志分割方法,详细讲解脚本分割方式,希望能够方便Linux/Unix管理员对日志文件进行有效管理。
1.1业务需求
在生产环境中,当我们使用tomcat服务时,如果用户量过多,又没有日志切割,将会产生大量日志,一天的日志都能有好几个G大小。当我们需要查看日志记录时非常麻烦。因此日志切割非常有必要。
1.2分割作用
随着服务访问量越来越大,服务器产生的日志文件也会越来越大,对其进行分割管理,单个日志文件不会变得异常庞大,有利于对日志进行综合分析、监控等。另外,当服务器遇到故障时,运维人员就要打开日志文件进行分析,打开的过程不会消耗很长时间,也势必会减少处理故障的时间。
2分割种类
tomcat的日志分割有三种方法,分别为用cronolog分割catalina.out文件、使用log4j分割catalina.out文件、使用shell脚本分割catalina.out文件。
2.1cronolog
使用cronolog比较简单,无需附加其他jar包,但是查看当天的catalina.out时必须使用日期后缀,不太方便。
容器化tomcat分割需要对容器内部的tomcat进行一定修改,相对繁琐。
2.2log4j分割
使用log4j的配置,稍微繁琐一些,但是感觉更加灵活,而且可以不改变原来的catalina.out的查看方式。
容器化tomcat分割需要对容器内部的tomcat进行一定修改,相对繁琐。
2.3shell脚本
脚本是使用一种特定的描述性语言,依据一定格式编写的可执行文件,又称作宏或批处理文件,脚本通常可以由应用程序临时调用并执行。使用灵活,分割方式自由控制,但需要使用者了解shell脚本的编写逻辑、cron的语法格式以及写入cron中自动执行此脚本。
容器化tomcat分割比较简单,不需要对容器内部的tomcat进行修改,但需要对k8s相关命令有所了解。
3配置过程
根据对上述3种日志分割方法的对比,选择了调整最小、侵入性最低的shell脚本方式实现日志分割,下面详细介绍脚本内各命令的作用。
3.1分割脚本
以下脚本存放目录为/opt/k8s/script/,编写脚本分割日志。
3.1.1脚本说明
下面就是分割容器内的日志脚本,整体思路如下:
1.master1和master2上创建日志分割脚本container-cut-log.sh;
2.脚本授权chmod a+x container-cut-log.sh;
3.检查vip,在有vip的服务器上执行分割脚本,原因是日志分割脚本会检查所有容器并分割日志,执行日志分割时,执行一次就可以了,没必要重复执行;
4.获取前一天日期;
5.加载k8s环境变量配置;
6.查询命名空间个数,循环查出每个命名空间名称;
7.通过命名空间查出,命名空间下有几个产品容器,循环查出每个产品容器名称;
8.通过命名空间和产品容器名称,,循环查出每个实例容器ID;
9.通过命名空间、产品容器名称、容器ID,先复制catalina.out为catalina.日期.out;
10.再通过命名空间、产品容器名称、容器ID,清空catalina.out,完成日志分割。
注意:虚拟ip需要根据实际情况修改。
3.1.2验证脚本
手动执行container-cut-log.sh脚本文件,查看执行日志,下图是截取的测试环境2个esb和2个idm日志分割的日志:
idm日志文件如下图:
3.2清理脚本
以下脚本存放目录为/opt/k8s/script/,编写脚本删除10天之前的日志文件。
3.2.1脚本说明
下面就是删除超过10天的日志脚本,整体思路如下:
1.master1和master2上创建日志清除脚本container-clean-log.sh;
2.脚本授权chmod a+x container-clean-log.sh;
3.检查vip,在有vip的服务器上执行清除脚本,原因是日志清除脚本会检查所有容器并删除日志,执行日志清除,执行一次就可以了,没必要重复执行;
4.加载k8s环境变量配置;
5.查询命名空间个数,循环查出每个命名空间名称;
6.通过命名空间查出,命名空间下有几个产品容器,循环查出每个产品容器名称;
7.通过命名空间和产品容器名称,循环查出每个实例容器ID和产品日志外部映射路径;
8.通过容器ID和产品日志外部映射路径,删除10天之前的日志文件。
注意:虚拟ip需要根据实际情况修改。
3.2.2验证脚本
手动执行container-clean-log.sh脚本文件,查看执行日志,下图是截取的测试环境2个esb和2个idm日志分割的日志:
3.3定时任务
cron是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,会自动启动cron进程,cron进程每分钟会定期检查是否有需要执行的任务,如果有则自动执行该任务。
3.3.1设置任务
编写定时任务:
# crontab -e
05 00 * * * sudo /opt/k8s/script/container-cut-log.sh
10 00 * * * sudo /opt/k8s/script/container-clean-log.sh
保存退出
:wq
3.3.2验证任务
完成上述操作就可以了,这里为了方便测试,可以创建n天前创建的文件,然后等待计划任务执行,看看效果。
测试已经删除。
4收获总结
4.1技术收获
1.日志文件大于一定大小就只保留最后特定行数,其他都删除,减少日志文件大小;
2.shell命令使用判断,循环,变量是设置和使用;
3.在容器外部使用kubectl命令,执行容器内部文件;
4.使用conrtab编写定时任务,定时调用脚本;
5.手动在服务器上执行命令,和用conrtab调用脚本执行命令实际上结果会不同,因为conrtab调用脚本不会加载服务器上的环境变量配置。
4.2测试须知
测试是很重要的环节,测试时考虑的场景一定要全,如果没有覆盖全部场景,就会导致脚本执行后无法达到预期效果。笔者最开始编写的脚本,当时只有两个环境,场景覆盖的并不完全,测试时没有任何问题。当环境扩展到4个后,暴露出了脚本的遗漏,之后重新调整脚本解决了问题。如果当时考虑到了,这个问题就不会再发生了,后续要多注意这种问题,凡事多想想,避免反复。
4.3成长感悟
linux的shell脚本功能是真的很强,基本上绝大多数应用程序出现自身解决不了的问题时都可以使用脚本编写命令解决。工作中经常执行一连串有顺序的、规律的甚至是重复性强且繁琐的命令行来实现我们要的操作,反复手动输入命令将会极大程度上限制我们的效率,这时编写shell脚本是很好解决这些问题的途径。
学会日志分割、删除没必要保留日志的实际作用很大,在项目中正式环境的服务运行基本都是很平稳的,每天都会产生很多日志数据,时间久了就有可能影响服务的运行。所以建议在项目中部署服务时,都要进行日志分割和定时清理,保证服务器的稳定运行。