很多小伙伴在记录GC日志的时候都喜欢使用UseGCLogFileRotation这个参数,比如:

-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps
-Xloggc:/home/GCEASY/gc.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=20M

上面的例子中,JVM的一个日志文件达到了20M以后,就会写入另一个新的文件,最多会有5个日志文件,他们的名字分别是:gc.log.0、gc.log.1、gc.log.2、gc.log.3、gc.log.4.

但是,这么做会有以下几个问题:

问题1:丢失旧的日志

如果你配置的日志文件个数是5个,一段时间过后就会产生出来5个日志文件,假如最老的是gc.log.0,最近的是gc.log.4,当gc.log.4到达20M以后,日志会重新写入到gc.log.0,gc.log.0之前的内容会被清空掉!

问题2:日志会变混乱

假如现在还是有5个日志文件:gc.log.0到gc.log.4,现在JVM重启了,此时GC的日志会重新从gc.log.0开始写入,但是gc.log.1、gc.log.2、gc.log.3、gc.log.4这里面的日志却还是之前旧的日志!新旧日志就掺杂在了一起!要解决这个问题,在重启服务器之前你需要把老的日志全部迁移到其他地方。

问题3:不方便日志集中管理

这种情况下,当前活动的日志文件的后缀名会被标记为.current,假如当前活动的日志文件是gc.log.3,那么他的文件名会被命名成gc.log.3.current,如果你要把不同机器上的日志文件都放到一个集中的地方去的话,大多数运维人员都会使用rsyslog,但是这种命名方式对rsyslog来说是一个非常大的挑战!

问题4:对日志分析工具不友好

当使用日志分析工具(gceasy、GCViewer)来分析日志的时候需要上传多个日志文件而不是一个!

推荐的解决办法:

可以给GC日志的文件后缀加上时间戳,当JVM重启以后,会生成新的日志文件,新的日志也不会覆盖老的日志,只需要在日志文件名中添加%t的后缀即可:

-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps
-Xloggc:/home/GCEASY/gc-%t.log

%t会给文件名添加时间戳后缀,格式是YYYY-MM-DD_HH-MM-SS。这样就非常简单了克服了UseGCLogFileRotation存在的所有的问题!