@ -13,29 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License .
* /
package org.springframework.bootstrap.logging ;
import java.lang.management.ManagementFactory ;
import java.util.HashMap ;
import java.util.Map ;
import org.springframework.context.ApplicationContext ;
import org.springframework.context.ApplicationContextInitializer ;
import org.springframework.context.ConfigurableApplicationContext ;
import org.springframework.core.Ordered ;
import org.springframework.core.env.ConfigurableEnvironment ;
import org.springframework.core.env.Environment ;
import org.springframework.core.io.ClassPathResource ;
import org.springframework.core.io.ResourceLoader ;
import org.springframework.util.ClassUtils ;
import org.springframework.util.Log4jConfigurer ;
/ * *
* < p >
* An { @link ApplicationContextInitializer } that configures a logging framework depending
* on what it finds on the classpath and in the { @link Environment } . If the environment
* contains a property < code > logging . config < / code > then that will be used to initialize
* the logging system , otherwise a default location is used . The classpath is probed for
* log4j and logback and if those are present they will be reconfigured , otherwise vanilla
* < code > java . util . logging < / code > will be used .
* < / p >
* < code > java . util . logging < / code > will be used . < / p >
*
* < p >
* The default config locations are < code > classpath : log4j . properties < / code > or
@ -57,12 +58,21 @@ import org.springframework.util.Log4jConfigurer;
* < li > < code > PID < / code > is set to the value of the current process ID if it can be
* determined < / li >
* < / ul >
* @author Dave Syer
*
* @author Dave Syer
* @author Phillip Webb
* /
public class LoggingInitializer implements
ApplicationContextInitializer < ConfigurableApplicationContext > , Ordered {
private static final Map < String , String > ENVIRONMENT_SYSTEM_PROPERTY_MAPPING ;
static {
ENVIRONMENT_SYSTEM_PROPERTY_MAPPING = new HashMap < String , String > ( ) ;
ENVIRONMENT_SYSTEM_PROPERTY_MAPPING . put ( "logging.file" , "LOG_FILE" ) ;
ENVIRONMENT_SYSTEM_PROPERTY_MAPPING . put ( "logging.path" , "LOG_PATH" ) ;
ENVIRONMENT_SYSTEM_PROPERTY_MAPPING . put ( "PID" , "PID" ) ;
}
private int order = Integer . MIN_VALUE + 1 ;
/ * *
@ -72,110 +82,138 @@ public class LoggingInitializer implements
@Override
public void initialize ( ConfigurableApplicationContext applicationContext ) {
String configLocation = getDefaultConfigLocation ( ) ;
ConfigurableEnvironment environment = applicationContext . getEnvironment ( ) ;
if ( environment . containsProperty ( "logging.config" ) ) {
configLocation = environment . getProperty ( "logging.config" ) ;
for ( Map . Entry < String , String > mapping : ENVIRONMENT_SYSTEM_PROPERTY_MAPPING
. entrySet ( ) ) {
if ( environment . containsProperty ( mapping . getKey ( ) ) ) {
System . setProperty ( mapping . getValue ( ) ,
environment . getProperty ( mapping . getKey ( ) ) ) ;
}
}
if ( environment . containsProperty ( "logging.file" ) ) {
String location = environment . getProperty ( "logging.file" ) ;
System . setProperty ( "LOG_FILE" , location ) ;
if ( System . getProperty ( "PID" ) = = null ) {
System . setProperty ( "PID" , getPid ( ) ) ;
}
if ( environment . containsProperty ( "logging.path" ) ) {
String location = environment . getProperty ( "logging.path" ) ;
System . setProperty ( "LOG_PATH" , location ) ;
}
LoggingSystem system = LoggingSystem . get ( applicationContext . getClassLoader ( ) ) ;
system . init ( applicationContext ) ;
}
if ( ! environment . containsProperty ( "PID" ) ) {
System . setProperty ( "PID" , getPid ( ) ) ;
private String getPid ( ) {
String name = ManagementFactory . getRuntimeMXBean ( ) . getName ( ) ;
if ( name ! = null ) {
return name . split ( "@" ) [ 0 ] ;
}
return "????" ;
}
initLogging ( applicationContext , configLocation ) ;
public void setOrder ( int order ) {
this . order = order ;
}
@Override
public int getOrder ( ) {
return this . order ;
}
private void initLogging ( ResourceLoader resourceLoader , String configLocation ) {
try {
if ( isLog4jPresent ( ) ) {
private static enum LoggingSystem {
/ * *
* Log4J
* /
LOG4J ( "org.apache.log4j.PropertyConfigurator" , "log4j.xml" , "log4j.properties" ) {
@Override
protected void doInit ( ApplicationContext applicationContext ,
String configLocation ) throws Exception {
Log4jConfigurer . initLogging ( configLocation ) ;
} else {
if ( isLogbackPresent ( ) ) {
LogbackConfigurer . initLogging ( configLocation ) ;
} else {
JavaLoggerConfigurer . initLogging ( configLocation ) ;
}
}
} catch ( RuntimeException e ) {
throw e ;
} ,
} catch ( Exception e ) {
throw new IllegalStateException ( "Cannot initialize logging from "
+ configLocation , e ) ;
}
}
/ * *
* Logback
* /
LOGBACK ( "ch.qos.logback.core.Appender" , "logback.xml" ) {
private boolean isLogbackPresent ( ) {
return ClassUtils . isPresent ( "ch.qos.logback.core.Appender" ,
ClassUtils . getDefaultClassLoader ( ) ) ;
}
@Override
protected void doInit ( ApplicationContext applicationContext ,
String configLocation ) throws Exception {
LogbackConfigurer . initLogging ( configLocation ) ;
}
} ,
private boolean isLog4jPresent ( ) {
return ClassUtils . isPresent ( "org.apache.log4j.PropertyConfigurator" ,
ClassUtils . getDefaultClassLoader ( ) ) ;
}
/ * *
* Java Util Logging
* /
JAVA ( null , "logging.properties" ) {
@Override
protected void doInit ( ApplicationContext applicationContext ,
String configLocation ) throws Exception {
JavaLoggerConfigurer . initLogging ( configLocation ) ;
}
} ;
private String getDefaultConfigLocation ( ) {
private final String className ;
String defaultPath = ClassUtils . getPackageName ( LoggingInitializer . class ) . replace (
"." , "/" )
+ "/" ;
private final String [ ] paths ;
if ( isLog4jPresent ( ) ) {
String path = "log4j.xml" ;
if ( ! new ClassPathResource ( path ) . exists ( ) ) {
path = "log4j.properties" ;
if ( ! new ClassPathResource ( path ) . exists ( ) ) {
path = defaultPath + path ;
}
}
return "classpath:" + path ;
private LoggingSystem ( String className , String . . . paths ) {
this . className = className ;
this . paths = paths ;
}
if ( isLogbackPresent ( ) ) {
String path = "logback.xml" ;
if ( ! new ClassPathResource ( path ) . exists ( ) ) {
path = defaultPath + path ;
public void init ( ApplicationContext applicationContext ) {
String configLocation = getConfigLocation ( applicationContext ) ;
try {
doInit ( applicationContext , configLocation ) ;
} catch ( RuntimeException ex ) {
throw ex ;
} catch ( Exception ex ) {
throw new IllegalStateException ( "Cannot initialize logging from "
+ configLocation , ex ) ;
}
return "classpath:" + path ;
}
String path = "logging.properties" ;
if ( ! new ClassPathResource ( path ) . exists ( ) ) {
path = defaultPath + path ;
}
return "classpath:" + path ;
protected abstract void doInit ( ApplicationContext applicationContext ,
String configLocation ) throws Exception ;
}
private String getConfigLocation ( ApplicationContext applicationContext ) {
Environment environment = applicationContext . getEnvironment ( ) ;
ClassLoader classLoader = applicationContext . getClassLoader ( ) ;
private String getPid ( ) {
String name = ManagementFactory . getRuntimeMXBean ( ) . getName ( ) ;
if ( name ! = null ) {
return name . split ( "@" ) [ 0 ] ;
// User specified config
if ( environment . containsProperty ( "logging.config" ) ) {
return environment . getProperty ( "logging.config" ) ;
}
// Common patterns
for ( String path : this . paths ) {
ClassPathResource resource = new ClassPathResource ( path , classLoader ) ;
if ( resource . exists ( ) ) {
return "classpath:" + path ;
}
}
// Fallback to the default
String defaultPath = ClassUtils . getPackageName ( LoggingInitializer . class ) ;
defaultPath = defaultPath . replace ( "." , "/" ) ;
defaultPath = defaultPath + "/" + this . paths [ this . paths . length - 1 ] ;
return "classpath:" + defaultPath ;
}
return "????" ;
}
public void setOrder ( int order ) {
this . order = order ;
}
public static LoggingSystem get ( ClassLoader classLoader ) {
for ( LoggingSystem loggingSystem : values ( ) ) {
String className = loggingSystem . className ;
if ( className = = null | | ClassUtils . isPresent ( className , classLoader ) ) {
return loggingSystem ;
}
}
return JAVA ;
}
@Override
public int getOrder ( ) {
return this . order ;
}
}