为了配置方便,我们将logback的相关变量参数放到配置文件system.properties中。在tomcat容器启动时,控制容器的加载顺序,先加载properties文件,再初始化logback。由于logback是通过StaticLoggerBinder中的静态代码块初始化,因此要在它之前加载配置文件,需要研究tomncat初始化的顺序。

下来看下tomcat启动都做了什么

十月 13, 2016 8:58:29 上午 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:ecf.meloans' did not find a matching property.
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Server version:        Apache Tomcat/7.0.68
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Server built:          Feb 8 2016 20:25:54 UTC
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Server number:         7.0.68.0
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: OS Name:               Windows 7
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: OS Version:            6.1
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Architecture:          amd64
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Java Home:             D:\program files\Java\jdk1.8.0_101\jre
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: JVM Version:           1.8.0_101-b13
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: JVM Vendor:            Oracle Corporation
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: CATALINA_BASE:         D:\program files\jr-tomcat-7.0.68
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: CATALINA_HOME:         D:\program files\jr-tomcat-7.0.68
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dmaven.multiModuleProjectDirectory=$M2_HOME
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dcatalina.base=D:\program files\jr-tomcat-7.0.68
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dcatalina.home=D:\program files\jr-tomcat-7.0.68
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dwtp.deploy=D:\program files\jr-tomcat-7.0.68\webapps
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Djava.endorsed.dirs=D:\program files\jr-tomcat-7.0.68\endorsed
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.VersionLoggerListener log
信息: Command line argument: -Dfile.encoding=UTF-8
十月 13, 2016 8:58:29 上午 org.apache.catalina.core.AprLifecycleListener lifecycleEvent
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: D:\program files\Java\jdk1.8.0_101\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Imaging\;C:\Program Files (x86)\AMD\ATI.ACE\Core-Static;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\java\jdk1.7.0_60\bin;C:\Program Files\TortoiseSVN\bin;.
十月 13, 2016 8:58:29 上午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-bio-8080"]
十月 13, 2016 8:58:29 上午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
十月 13, 2016 8:58:29 上午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 662 ms
十月 13, 2016 8:58:29 上午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
十月 13, 2016 8:58:29 上午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.68
十月 13, 2016 8:58:29 上午 org.apache.catalina.loader.WebappClassLoaderBase validateJarFile
信息: validateJarFile(D:\program files\jr-tomcat-7.0.68\webapps\ecf.meloans\WEB-INF\lib\servlet-api-2.5.jar) - jar not loaded. See Servlet Spec 3.0, section 10.7.2. Offending class: javax/servlet/Servlet.class
十月 13, 2016 8:58:32 上午 org.apache.catalina.startup.TldConfig execute
信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
十月 13, 2016 8:58:32 上午 org.apache.catalina.core.ApplicationContext log
信息: Spring WebApplicationInitializers detected on classpath: [com.midea.jr.ecf.meloans.utils.JrLogbackConfigLoader@11ed90a7]
set system logging parameter :log.app.version = 0.0.1
set system logging parameter :log.dir = d:/wangzy25/log
set system logging parameter :log.credit.accounting.level = ERROR
set system logging parameter :log.credit.accounting.task.level = DEBUG
set system logging parameter :log.app.env = development
set system logging parameter :log.credit.accounting.dao.level = ERROR
set system logging parameter :log.root.level = DEBUG
set system logging parameter :log.app.name = credit.accounting
set system logging parameter :log.system.name = com.midea.jr
十月 13, 2016 8:58:32 上午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring root WebApplicationContext
log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Class path contains multiple SLF4J bindings.

其中:

信息: Starting service Catalina
.
.
.
信息: Spring WebApplicationInitializers detected on classpath: [com.midea.jr.ecf.meloans.utils.JrLogbackConfigLoader@11ed90a7]
.
.
.
信息: Initializing Spring root WebApplicationContext
SLF4J: Class path contains multiple SLF4J bindings.

表示了Catalina启动-->WebApplicationInitializers-->WebApplicationContext-->SLF4J bindings

因此我们只要在SLF4J bindings之前加载配置文件即可。


方案1、通过配置listener,将其放到logback之前

package com.midea.jr.ecf.meloans.listener;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import ch.qos.logback.ext.spring.web.WebLogbackConfigurer;


/**
 * <p>Project:com.midea.jr.ecf			<p>
 * <p>Module:meloans.utils			<p>
 * <p>Description:加载系统配置文件 system.properties		<p>
 *
 * @author WANGZY25
 * @date 2016年10月12日 下午3:03:54
 */
public class LoadSystemConfigListener implements  ServletContextListener {	

	@Override
	public void contextInitialized( ServletContextEvent sce ) {
		Properties prop = new Properties();
		InputStream in = this.getClass().getResourceAsStream( "/system.properties" );
		System.out.println("***********  begin loading log configuration   *********");
		try {
			prop.load(in);
			Enumeration<Object> iter= prop.keys();
			while(iter.hasMoreElements()){
				String key = iter.nextElement().toString();
				if(key.startsWith( "log" )){
					System.setProperty( key, prop.getProperty( key ) );
					System.out.println( "set system logging parameter : "+key+" = "+prop.getProperty( key ) );
				}
			}
		} catch( IOException e ) {
			e.printStackTrace();
		}
		 WebLogbackConfigurer.initLogging(sce.getServletContext());
	}

	@Override
	public void contextDestroyed( ServletContextEvent sce ) {
		WebLogbackConfigurer.shutdownLogging(sce.getServletContext());
	}
}

同时在web.xml中,把这个listener配置到靠前的位置

<listener>
        <listener-class>com.midea.jr.ecf.meloans.utils.LoadSystemConfigListener</listener-class>
</listener>


方案2、重写WebApplicationInitializer

package com.midea.jr.ecf.meloans.listener;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.springframework.web.WebApplicationInitializer;


/**
 * <p>Project:com.midea.jr.ecf			<p>
 * <p>Module:meloans.utils			<p>
 * <p>Description:加载系统配置文件 system.properties		<p>
 *
 * @author WANGZY25
 * @date 2016年10月12日 下午3:03:54
 */
public class JrLogbackConfigLoader implements WebApplicationInitializer{
	
	@Override
	public void onStartup( ServletContext servletContext ) throws ServletException {
		Properties prop = new Properties();
		InputStream in = this.getClass().getResourceAsStream( "/system.properties" );
		try {
			prop.load(in);
			Enumeration<Object> iter= prop.keys();
			while(iter.hasMoreElements()){
				String key = iter.nextElement().toString();
				if(key.startsWith( "log" )){
					System.setProperty( key, prop.getProperty( key ) );
					System.out.println("set system logging parameter :"+key+" = "+prop.getProperty( key ));
				}
			}
		} catch( IOException e ) {
			e.printStackTrace();
		}
	}

}

参考地址:

Logback统一配置及环境变量加载问题

http://www.jianshu.com/p/39178af66aef

【飞天奔月出品】剖析logback2:logback启动

http://feitianbenyue.iteye.com/blog/2205631

图解Tomcat类加载机制

http://www.cnblogs.com/xing901022/p/4574961.html

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐