我正在使用一个使用log4j的现有系统,我想更新到log4j2。
有一个自定义的spring bean从文件加载配置。我需要保持这种方法。我不能使用“log4j.configurationFile”系统属性。
我们有一个属性文件,其中指定了当前log4j.xml的路径(NFS共享)
spring bean有这个代码......
public class Log4jConfigurationBean implements ResourceLoaderAware,
InitializingBean {
private ResourceLoader resourceLoader;
private boolean enabled;
private String location;
/**
* Default, no argument constructor.
*/
public Log4jConfigurationBean() {
enabled = true;
}
/**
* Sets whether or not this bean should load an external configuration
* defined by {@link #setLocation(Resource)}. If <code>false</code>, this
* bean does nothing.
*
* <p>
* Default value is <code>true</code>.
* </p>
*
* @param enabled
* <code>false</code> causes this bean to do nothing
*/
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
/**
* Sets the location of the external log4j configuration (xml or properties)
* to be loaded.
*
* @param location
* the location of the external configuration to be loaded.
* @throws IllegalStateException
* if there is a problem resolving the location resource
* @throws NullPointerException
* if <code>resource</code> is <code>null</code>
*/
public void setLocation(final String location) {
this.location = StringUtils.trimToNull(location);
}
@Override
public void setResourceLoader(final ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
/**
* @throws IllegalStateException
* if enabled and no location has be set, or if the external
* configuration is neither xml or properties.
*/
@Override
public void afterPropertiesSet() throws Exception {
URL configURL = null;
if (null != location) {
try {
final Resource resource = resourceLoader.getResource(location);
if (null != resource) {
configURL = resource.getURL();
}
} catch (IOException e) {
throw new IllegalArgumentException(
"Could not resolve configuration location due to error: ",
e);
}
}
if (enabled && null == configURL) {
throw new IllegalStateException(
"Log4j configuration enabled, but configuration location is not set.");
}
if (enabled) {
if (configURL.getFile().toLowerCase().endsWith(".xml")) {
DOMConfigurator.configure(configURL);
} else if (configURL.getFile().toLowerCase()
.endsWith(".properties")) {
PropertyConfigurator.configure(configURL);
} else {
throw new IllegalStateException(
"Configuration must be properties or xml: "
+ configURL.getFile());
}
}
}
}
在log4j2中没有PropertyConfigurator。 如何以相同的方式加载log4j2.xml文件。
log4j2.xml文件的文件路径在spring属性文件中指定。
目标是让war文件在类路径中包含log4j2.xml文件。在本地盒子上进行开发时将使用此选项。
当网络应用程序部署到qa环境时,有一个属性文件包含以下键/值对...
# Should an external file be used for log4j configuration
log4j.enabled=true
log4j.location=file:/paht to log4j2.xml
spring bean正在使用这些值来决定是否应该使用外部log4j2.xml文件而不是类路径上的文件。
我尝试使用这样的spring bean ...代码已执行,但它仍然使用类路径上的配置文件。
public class Log4j2ConfigurationBean implements ResourceLoaderAware, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(Log4j2ConfigurationBean.class);
private ResourceLoader resourceLoader;
private boolean enabled;
private String location;
/**
* Default, no argument constructor.
*/
public Log4j2ConfigurationBean() {
enabled = true;
}
/**
* Sets whether or not this bean should load an external configuration defined by {@link #setLocation(Resource)}. If <code>false</code>, this bean does nothing.
*
* <p>
* Default value is <code>true</code>.
* </p>
*
* @param enabled
* <code>false</code> causes this bean to do nothing
*/
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
/**
* Sets the location of the external log4j configuration (xml or properties) to be loaded.
*
* @param location
* the location of the external configuration to be loaded.
* @throws IllegalStateException
* if there is a problem resolving the location resource
* @throws NullPointerException
* if <code>resource</code> is <code>null</code>
*/
public void setLocation(final String location) {
this.location = StringUtils.trimToNull(location);
}
@Override
public void setResourceLoader(final ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
/**
* @throws IllegalStateException
* if enabled and no location has be set, or if the external configuration is neither xml or properties.
*/
@Override
public void afterPropertiesSet() throws Exception {
URL configURL = null;
if (enabled) {
if (StringUtils.isBlank(location)) {
throw new IllegalStateException("Log4j2 configuration enabled, but configuration location is not set.");
}
try {
System.out.println(this.getClass().getName() + " : Loading log4j2 configuration with " + location);
final Resource resource = resourceLoader.getResource(location);
if (null != resource) {
configURL = resource.getURL();
}
} catch (IOException e) {
throw new IllegalArgumentException("Could not resolve configuration location due to error: ", e);
}
if (configURL.getFile().toLowerCase().endsWith(".xml")) {
try {
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");
System.setProperty("AsyncLogger.RingBufferSize", "8192");
ConfigurationFactory configurationFactory = XmlConfigurationFactory.getInstance();
ConfigurationSource configurationSource = new ConfigurationSource(configURL.openStream(), configURL);
Configuration configuration = configurationFactory.getConfiguration(configurationSource);
configuration.start();
log.info("Log4j2 configured with {}", location);
log.info("System property Log4jContextSelector set to {}", System.getProperty("Log4jContextSelector"));
log.info("System property AsyncLogger.RingBufferSize set to {}", System.getProperty("AsyncLogger.RingBufferSize"));
} catch (Exception e) {
System.out.println(this.getClass().getName() + " : Could not initialize log4j2 with resource " + location);
System.out.println(e.getStackTrace());
}
} else {
throw new IllegalStateException("Configuration must be xml: " + configURL.getFile());
}
} else {
System.out.println(this.getClass().getName() + " : External log4j2 configuration not configured.");
}
}
}
感谢。