介绍
tomcat在8.5之后就不在提供额外的日志支持,在Linux系统中导致日志文件过于庞大,本例换用log4j2对其切割
(采用tomcat+war的形式部署).
- tomcat在8.5之后就不在提供额外的日志支持(Extras),常见的tomcat-juli-adapters.jar和tomcat-juli.jar在之后的版本中已经被弃用
- 之前采用log4j 1.x 现如今已经是log4j 2.x 保证我们能够与时俱进
安装教程
- 一、将tomcat-log-.jar,log4j-core-.jar,log4j-api-*.jar ( * 为版本号)拷贝到tomcat/bin目录下.
- 二、在catalina.sh中添加第一步的三个jar(直接在 tomcat-juli.jar 后面追加).
# koujiang Add tomcat-log.jar to classpath
# tomcat-log.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/tomcat-log-1.0.jar" ] ; then
CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/tomcat-log-1.0.jar
else
CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/tomcat-log-1.0.jar
fi
# koujiang Add tomcat-log.jar to classpath
# tomcat-log.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/log4j-api-2.11.2.jar" ] ; then
CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/log4j-api-2.11.2.jar
else
CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/log4j-api-2.11.2.jar
fi
# koujiang Add tomcat-log.jar to classpath
# tomcat-log.jar can be over-ridden per instance
if [ -r "$CATALINA_BASE/bin/log4j-core-2.11.2.jar" ] ; then
CLASSPATH=$CLASSPATH:$CATALINA_BASE/bin/log4j-core-2.11.2.jar
else
CLASSPATH=$CLASSPATH:$CATALINA_HOME/bin/log4j-core-2.11.2.jar
fi
- 三、添加log4j2.xml配置文件
## Set juli LogManager config file if it is present and an override has not been issued
#if [ -z "$LOGGING_CONFIG" ]; then
# if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
# LOGGING_CONFIG="-Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties"
# else
# # Bugzilla 45585
# LOGGING_CONFIG="-Dnop"
# fi
#fi
# koujiang Set juli LogManager config file if it is present and an override has not been issued
if [ -z "$LOGGING_CONFIG" ]; then
if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then
LOGGING_CONFIG="-Dlog4j.configurationFile=$CATALINA_BASE/conf/log4j2.xml"
else
# Bugzilla 45585
LOGGING_CONFIG="-Dnop"
fi
fi
使用说明
- 1、tomcat的日志在bin目录下的tomcat-juli.jar,且由LogFactory完成Logger的选择,默认采用jdk(如有兴趣请自行查看源码)
获取日志构造器 ServiceLoader<Log> logLoader = ServiceLoader.load(Log.class); Constructor<? extends Log> m=null; for (Log log: logLoader) { Class<? extends Log> c=log.getClass(); try { m=c.getConstructor(String.class); break; } catch (NoSuchMethodException | SecurityException e) { throw new Error(e); } discoveredLogConstructor=m; } 通过构造器获取Log public Log getInstance(String name) throws LogConfigurationException { if (discoveredLogConstructor == null) { return DirectJDKLog.getInstance(name); } try { return discoveredLogConstructor.newInstance(name); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new LogConfigurationException(e); } }
- 2、由于使用ServiceLoader加载Log(juli)接口的实现类,为此添加一个实现类
1、定义个类TomcatLogger并使用log4j2实现org.apache.juli.logging.Log 2、由于ServiceLoader需要配置映射,为此在resources文件中添加META-INF/services/并在此文件夹下添加一个文件 文件名为org.apache.juli.logging.Log,文件内容为此接口的实现类,本例中为com.koujiang.tomcat.log.TomcatLogger
- 3、配置Tomcat
tomcat启动类为org.apache.catalina.startup.Bootstrap,此类依然包含了日志 为此需要在tomcat启动的时候就需要将日志配置好,因此采用classpath(jdk会依据classpath去查找class文件),于是添加到catalina.sh中. 配置文件如果一并打包在jar中确实不符合情理,于是依据log4j2的配置加载顺序中log4j.configurationFile是有系统配置中获取, 于是就在启动前将log4j2.xml设置到系统配置中去(此例子采用覆盖logging.properties配置的方式)
拓展
- ServiceLoader.load或者Service.providers SPI(使用场景Dubbo、JDBC)
- JDK加载方式 Classpath
- Java -D 用于设置系统参数
- 如果你开心可直接将log4j2的两个jar的源码合并到此项目就下次就更方便了
参与贡献
- log4j2 Configuration
- [Tomcat changelog](http://tomcat.apache.org/tomcat-8.5-doc/changelog.html#Tomcat_8.5.47_(markt)
- Tomcat 8.5.4 Extras 58588
启动日志
[root@alone bin]# ./catalina.sh run
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar:/usr/local/tomcat/bin/tomcat-log-1.0.jar:/usr/local/tomcat/bin/log4j-api-2.11.2.jar:/usr/local/tomcat/bin/log4j-core-2.11.2.jar
00:38:16.638 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Server version name: Apache Tomcat/8.5.46
00:38:16.641 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Server built: Sep 16 2019 18:16:19 UTC
00:38:16.641 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Server version number: 8.5.46.0
00:38:16.641 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->OS Name: Linux
00:38:16.642 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->OS Version: 3.10.0-957.5.1.el7.x86_64
00:38:16.642 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Architecture: amd64
00:38:16.642 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Java Home: /usr/java/jdk1.8.0_221-amd64/jre
00:38:16.642 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->JVM Version: 1.8.0_221-b11
00:38:16.642 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->JVM Vendor: Oracle Corporation
00:38:16.654 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->CATALINA_BASE: /usr/local/tomcat
00:38:16.654 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->CATALINA_HOME: /usr/local/tomcat
00:38:16.654 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Dlog4j.configurationFile=/usr/local/tomcat/conf/log4j2.xml
00:38:16.654 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
00:38:16.654 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
00:38:16.655 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
00:38:16.655 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
00:38:16.660 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Dignore.endorsed.dirs=
00:38:16.660 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Dcatalina.base=/usr/local/tomcat
00:38:16.661 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Dcatalina.home=/usr/local/tomcat
00:38:16.661 [main] INFO org.apache.catalina.startup.VersionLoggerListener - koujiang:-->Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
00:38:16.661 [main] INFO org.apache.catalina.core.AprLifecycleListener - koujiang:-->The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
00:38:16.812 [main] INFO org.apache.coyote.http11.Http11NioProtocol - koujiang:-->Initializing ProtocolHandler ["http-nio-8080"]
00:38:16.826 [main] INFO org.apache.tomcat.util.net.NioSelectorPool - koujiang:-->Using a shared selector for servlet write/read
00:38:16.859 [main] INFO org.apache.coyote.ajp.AjpNioProtocol - koujiang:-->Initializing ProtocolHandler ["ajp-nio-8009"]
00:38:16.862 [main] INFO org.apache.tomcat.util.net.NioSelectorPool - koujiang:-->Using a shared selector for servlet write/read
00:38:16.863 [main] INFO org.apache.catalina.startup.Catalina - koujiang:-->Initialization processed in 650 ms
00:38:16.892 [main] INFO org.apache.catalina.core.StandardService - koujiang:-->Starting service [Catalina]
00:38:16.892 [main] INFO org.apache.catalina.core.StandardEngine - koujiang:-->Starting Servlet Engine: Apache Tomcat/8.5.46