从java9开始,java引入了统一的日志管理JEP 158,而配置的方式也统一通过-Xloggc参数配置,通过这个选项可以统一配置子模块的日志,包括class loading,threading,gc,os。这篇文章就来梳理下相关的配置项

配置主要包含三个部分:

  • 通过tag或者log level指定什么日志可以被输出
  • 输出的信息内容,例如时间,进程号
  • 输出位置,文件、控制台等
    1. java -Xlog -version
    输出如下,第三列表示的就是模块/tag
    1. [0.002s][info][os,container] Memory Limit is: 3221225472
    2. [0.004s][info][biasedlocking] Aligned thread 0x00007f4b38015680 to 0x00007f4b38015800
    3. [0.004s][info][os,thread ] Thread attached (tid: 115152, pthread id: 139961161549568).
    4. [0.004s][info][os ] attempting shared library load of /opt/taobao/install/ajdk11.0.9.9-ant-blink.2021.2.8/lib/libzip.so
    5. [0.004s][info][os ] shared library load of /opt/taobao/install/ajdk11.0.9.9-ant-blink.2021.2.8/lib/libzip.so was successful
    6. [0.004s][info][class,path ] bootstrap loader class path=/opt/taobao/install/ajdk11.0.9.9-ant-blink.2021.2.8/lib/modules
    7. [0.004s][info][class,path ] opened: /opt/taobao/install/ajdk11.0.9.9-ant-blink.2021.2.8/lib/modules

image.png

上图可以帮助理解日志生效的流程,各个模块只管打日志,在日志输出阶段通过配置项进行过滤,装饰,类似于log4j等日志框架的实现。

配置什么日志可以被输出

什么信息能够被输出是通过=的键值对来配置的,这个就是上图中的selectors,所有的tag可以通过all来指定,log level是可选的,默认是info。

  1. java -Xlog:all=warning -version

一个selector可以通过 + 连接来指定多个tag,如果通过+号连接的selector,只有全部满足才会输出

  1. # 输出gc相关的日志
  2. java -Xlog:gc -version
  3. # 仅输出gc heap相关的日志
  4. java -Xlog:gc+heap -version

这里需要注意gc,heap相关的日志并不会在gc的selector下才输出,如果要都输出,那么就要用逗号链接各个tag,并列配置

  1. $ java -Xlog:gc=debug -version
  2. [0.003s][info][gc] Using Serial
  3. $ java -Xlog:gc,gc+heap=debug -version
  4. [0.003s][debug][gc,heap] Minimum heap 8388608 Initial heap 50331648 Maximum heap 805306368
  5. [0.003s][info ][gc ] Using Serial

那么为了获取gc所有的日志岂不是要把gc各个模块都加上了?大可不必,可以通过通配符

  1. # -Xlog:tag_1*,tag_2*,tag_n*
  2. java -Xlog:gc*=debug -version

以前我们配置打印类加载的日志是通过以下命令,我理解下面两个命令是等价的

  1. java -verbose:class -version
  2. java -Xlog:class+load -version

配置日志输出到哪里

在selector之后冒号分隔,指定日志输出的位置,一般只有三个地方配置

  • stdout
  • stderr
  • file=, 也可以直接指定文件名,file=可以被省略

在一个-Xlog配置中只能指定一个输出,但是可以指定多个-Xlog来达到输出多个的效果。output还可以指定文件滚动和滚动大小,默认不设置也是有滚动的

  1. java -Xlog:gc*:file=gc.log:time:filecount=10,filesize=10m

在jdk8中需要通过以下三个参数指定, 相比之下现在的配置方式简单了很多

  1. -XX:+UseGCLogFileRotation
  2. -XX:NumberOfGCLogFiles
  3. -XX:GCLogFileSize

配置日志的输出内容

可以配置的内容如下

time Current time and date in ISO-8601 format.
uptime Time since the start of the JVM in seconds and milliseconds (e.g., 6.567s).
timemillis The same value as generated by System.currentTimeMillis().
uptimemillis Milliseconds since the JVM started.
timenanos The same value as generated by System.nanoTime().
uptimenanos Nanoseconds since the JVM started.
pid The process identifier.
tid The thread identifier.
level The level associated with the log message.
tags The tag-set associated with the log message.
  1. $ java -Xlog:gc*:stdout:time -version
  2. [2021-02-08T20:30:53.935+0800] Heap region size: 1M
  3. [2021-02-08T20:30:53.938+0800] Using G1
  4. [2021-02-08T20:30:53.938+0800] Heap address: 0x00000000b0000000, size: 1280 MB, Compressed Oops mode: 32-bit
  5. [2021-02-08T20:30:53.988+0800] Periodic GC disabled

总结一下-Xlog配置的语法是

  1. -Xlog:<selectors>:<output>:<decorators>:<output-options>

最后在配置的时候如果还遇到问题可以查看help

  1. java -Xlog:help

参考
https://nipafx.dev/java-unified-logging-xlog/
https://sematext.com/blog/java-garbage-collection-logs/