Log4j2进阶使用(按大小时间备份日志)

Log4j2进阶使用(按大小时间备份日志),第1张

本文介绍Log4j2进阶使用,

基本使用请参考 Log4j2基本使用入门 。

本文基于上面的基本使用入门,

主要介绍按照日志大小和时间备份日志,

并且限制备份日志的个数,

以及删除过期的备份日志。

由于日志信息是不断追加到日志文件的,

经过一段时间会导致日志文件很大,

所以需要及时分割过大的日志文件,

以及限制日志文件占用的硬盘空间,

及时清理掉不用的过期的日志文件。

RollingFileAppender能实现上面提出的需求,

它需要配置TriggeringPolicy和RolloverStrategy,

TriggeringPolicy触发策略决定何时执行备份,

RolloverStrategy翻转策略决定如何执行备份。

如果没有配置RolloverStrategy翻转策略,

RollingFileAppender将使用DefaultRolloverStrategy,

而且DefaultRolloverStrategy支持自定义删除文件 *** 作。

LOG_HOME用于指定当前日志存放的目录,

LOG_BACKUP用于指定备份日志存放的目录,

FILE_NAME用于指定日志文件的名称。

在需要的地方使用${LOG_HOME}引用即可。

本章通过配置log4j2.xml,

实现如下目标:

最多保存3个日志备份文件,

每个日志文件大小不超过1MB。

这里增加了一个类型为RollingFile的Appender,

name为RollingSizeFile,

FileName为${LOG_HOME}/${FILE_NAME}.log,

指定了当前正在打印的日志文件名称,

和文件存放的相对路径;

filePattern为${LOG_HOME}/${LOG_BACKUP}/${FILE_NAME}-%i.log,

指定了备份后的日志文件名称和存放路径,

其中%i表示备份文件名按照正整数开始递增。

SizeBasedTriggeringPolicy策略指定了文件大小:

当日志文件达到1MB时生成备份文件,

大小以字节为单位指定,

后缀为KB、MB或GB,例如1GB。

如果不填,默认值为10MB。

AppenderRef指定打印日志到新增的name为RollingSizeFile的Appender。

运行测试程序,

打印一段时间的日志,

在项目下会生成如下目录和文件:

可以看到logs目录下有test.log文件和backup目录,

backup目录下有test-1.log等7个备份文件,

而且每个文件的大小都是1MB。

上面由于没有配置RolloverStrategy滚动策略,

RollingFileAppender使用DefaultRolloverStrategy,

DefaultRolloverStrategy默认最多保存7个备份文件。

RollingFile中增加DefaultRolloverStrategy默认滚动策略,

并且指定最多保存3个备份文件:

修改后效果如下:

本章通过配置log4j2.xml,

实现如下目标:

每1分钟备份一次日志文件,

删除3分钟前备份的日志文件。

这里的配置和第4步中略有不同,

name为RollingTimeFile,

主要是filePattern、TimeBasedTriggeringPolicy配置不一样,

filePattern为${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd-HH-mm}.log,

其中$${date:yyyy-MM}指定了备份文件存放的目录为当前年月,

比如目录2019-09,而不是backup了,

${FILE_NAME}-%d{yyyy-MM-dd-HH-mm}.log指定了备份后的日志文件名称,

精确到分钟的一个时间戳。

TimeBasedTriggeringPolicy策略指定了生成备份文件的策略。

这个配置要和filePattern结合使用,

上面filePattern中的命名规则是${FILE_NAME}-%d{yyyy-MM-ddHH-mm}.log,

最小的时间粒度是mm,即分钟,

而TimeBasedTriggeringPolicy设置的interval是1,

结合起来就是每1分钟生成一个新文件。

同理,如果要每1小时生成一个新文件,

则改成%d{yyyy-MM-ddHH},最小粒度为小时,

如果再把interval该为12,

那就是每12小时生成一个新文件。

AppenderRef指定打印日志到新增的name为RollingTimeFile的Appender。

运行测试程序,

打印一段时间的日志,

在项目下会生成如下目录和文件:

可以看到logs目录下有test.log文件和2019-09备份目录,

2019-09目录下有test-2019-09-27-17-20.log等14个备份文件,

而且每个文件的大小都不一样,与该时间段内打印的日志多少有关。

随着时间推移会生成2019-10之类的目录,

而且目录下的备份文件也会越来越多。

RollingFile中增加DefaultRolloverStrategy策略,

删除3分钟前备份的日志文件:

Delete表示删除满足条件的文件,

basePath指定了需要处理的日志目录,

因为备份的日志在basePath下的年月目录($${date:yyyy-MM}),

所以maxDepth设置为2,代表扫描的目录深度,

maxDepth="1"表示当前目录。

指定文件名称:

匹配二级目录下的扩展名为.log的文件。

指定文件过期时间:

age的单位:D、H、M、S,分别表示天、小时、分钟、秒。

匹配最后修改时间为3分钟前的文件。

修改后效果如下:

查看目录时的当前时间是2019-09-29 15:44,

可以看到只保存了3分钟内生成的3个日志,

随着时间的推移,

生成新日志test-2019-09-29-15-44.log,

删除旧日志test-2019-09-29-15-41.log,

该目录下始终只有当前时间3分钟内的备份日志。

可以把按大小和时间备份结合起来使用,

实现更复杂的日志文件备份需求。

本章通过配置log4j2.xml,

实现如下目标:

每1分钟备份一次日志文件,

每个日志文件大小不超过1MB,

如果在1分钟内日志文件超过1MB,

则生成以当前时间+序号的备份日志,

但是每分钟内最多保存3个备份日志,

并且删除5分钟前备份的日志文件。

大部分配置和上面说过的一致,

就是简单的组合起来即可,

需要注意的是filePattern:

备份文件名${FILE_NAME}-%d{yyyy-MM-dd-HH-mm}-%i.log结合了时间和序号。

运行测试程序,

打印一段时间的日志,

在项目下会生成如下目录和文件:

看到2019-09目录下只有5分钟内的备份日志,

每分钟的备份日志最多有3个文件,

根据日志具体打印的情况,

少的时候可能1分钟只有1或者2个文件,

多的时候最多也只有3个文件,

在这1分钟内后生成的日志会覆盖掉前面的。

下面给出完整的配置文件,

供大家开发时参考使用:

slf4j+log4j2基础教程(拿来即用教程)

log4j2 RollingRandomAccessFile配置

log4j2 入门教程

log4j 包里面有一个 SQL 的 appender ,但我知道以前的版本中有bug,因为它生成 SQL 时用的是 createStatement 拼接字符串而不是 PreparedStatement ,因此当消息内容中有单引号或特殊符号时 SQL 都有语法错误执行不成功。

你需要自己扩展一下它提供自己的 SQLAppender 来做这件事。在网上搜索一个像 decompiler 这样的 Java 反编译器或从 Apache 网站去下载 log4j 源码来看一下 SQL appender 是怎么样的,我们改写它把这个 bug 解决了就可以用了。

如果你打算用 ODBC 数据源而不是 JDBC 来做,你需要确保你的 JRE 是 Oracle / Sun 提供的,因为像 IBM 的 JRE 就没有自带 ODBC 驱动程序,或者你自己去手工下载第三方的 ODBC 驱动程序。

从你的错误消息说 数据源找不到,对比下面这个图片,你没有设置它的 driver 参数,左边所有以 set 开头的方法就是表示你在 log4j.properties 文件中可以给它设置的参数,比如,setPassword 表示这个 JDBC Appender 有一个属性  password。

log4j.appender.mySQLAppender.password = 密码

log4j.appender.mySQLAppender.user = 用户名

。。。 其它 set 方法对应的属性列举在这里。。。

依此类推。

我们需要纠正的 bug 在这里面,你需要提供自己的类继承原来的 JDBCAppender 把这个 statement 改成 PreparedStatement 来访问数据库,就是需要 stmt.setString(1, myMsg)这种,而不是直接拼接字符串的。

看了它的 JDBCAppender.execute 方法就知道这里有一个 bug:

配置log4j2日志记录至数据库

1、建立用于保存日志的数据库表:

CREATE TABLE `sys_log` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `level` varchar(32) NOT NULL,

  `logger` varchar(100) NOT NULL,

  `message` varchar(1000) DEFAULT NULL,

  `exception` varchar(10000) DEFAULT NULL,

  `date_add` datetime NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4

2、配置 databaseAppender :

<JDBC name="databaseAppender" tableName="sys_log">

      <ConnectionFactory class="cc.s2m.web.s2mBlog.util.StaticProp" method="getDatabaseConnection" />

      <Column name="date_add" isEventTimestamp="true" />

      <Column name="level" pattern="%level" />

      <Column name="logger" pattern="%logger" />

      <Column name="message" pattern="%message" />

      <Column name="exception" pattern="%ex{full}" />

    </JDBC>

3、其中 cc.s2m.web.s2mBlog.util.StaticProp 类的getDatabaseConnection方法为获取可用的datasource:

DriverManagerDataSource ds = new DriverManagerDataSource()

ds.setDriverClassName("com.mysql.jdbc.Driver")

ds.setUrl("jdbc:mysql://127.0.0.1/s2mBlog?characterEncoding=utf8")

ds.setUsername("root")

ds.setPassword("123456")

return ds.getConnection()

4、指派需要记录的日志,使用 databaseAppender 即可:

<logger name="SYSLOG" level="INFO" additivity="false">

      <appender-ref ref="databaseAppender"/> 

</logger>


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9901824.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-03
下一篇 2023-05-03

发表评论

登录后才能评论

评论列表(0条)

保存