从Apollo初始化Log4j2的配置
从Apollo初始化Log4j2的配置
1. 实现步骤
通过编写ApolloLog4j2ConfigurationFactory类继承ConfigurationFactory,然后重写getConfiguration方法,在获取log4j2初始配置信息时从Apollo中读取配置信息并初始化log4j2。
实现代码:
package com.dm.dmga.log4j;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigChangeListener;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.Order;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.properties.PropertiesConfigurationBuilder;
import java.net.URI;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Set;
/**
* Log4j2的Apollo配置类
* <dl>
* <dt>主要实现功能:</dt>
* <dd>
* <ol>
* <li>log4j2初始化时通过该类从Apollo加载相应的log4j2的配置信息</li>
* <li>当通过Apollo修改log4j2配置后,能立即生效。例如,动态修改日志级别。</li>
* </ol>
* </dd>
* </dl>
*
* @author zxb
* @version 1.0.0
* 2018年05月16日 10:10
* @since 1.0.0
*/
@Plugin(name = "ApolloLog4j2ConfigurationFactory", category = ConfigurationFactory.CATEGORY)
@Order(50)
public class ApolloLog4j2ConfigurationFactory extends ConfigurationFactory {
/** Log4j2的NameSpace名称 */
private static final String LOG4J2_NAMESPACE = "dmga-dmdg.log4j2";
@Override
protected String[] getSupportedTypes() {
return new String[]{"*"};
}
@Override
public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
return getConfiguration(loggerContext, source.toString(), null);
}
@Override
public Configuration getConfiguration(LoggerContext loggerContext, String name, URI configLocation) {
// 从Apollo读取log4j2配置
Config config = ConfigService.getConfig(LOG4J2_NAMESPACE);
Set<String> propertyNames = config.getPropertyNames();
Properties properties = new Properties();
for (String propertyName : propertyNames) {
String propertyValue = config.getProperty(propertyName, null);
properties.setProperty(propertyName, propertyValue);
}
// 添加log4j2配置的监听器
config.addChangeListener(new Log4j2ConfigChangeListener(properties));
// 构造log4j2的Configuration
return new PropertiesConfigurationBuilder()
.setRootProperties(copyProperties(properties))
.setLoggerContext(loggerContext)
.build();
}
/**
* 复制Properties
*
* @param properties 原Properties对象
* @return 新Properties对象
*/
private Properties copyProperties(Properties properties) {
Properties newProperties = new Properties();
Enumeration<String> enumeration = (Enumeration<String>) properties.propertyNames();
while (enumeration.hasMoreElements()) {
String propertyName = enumeration.nextElement();
newProperties.put(propertyName, properties.getProperty(propertyName));
}
return newProperties;
}
private class Log4j2ConfigChangeListener implements ConfigChangeListener {
private Properties configProperties;
public Log4j2ConfigChangeListener(Properties configProperties) {
this.configProperties = configProperties;
}
public void onChange(ConfigChangeEvent changeEvent) {
String newValue;
ConfigChange configChange;
for (String changedKey : changeEvent.changedKeys()) {
configChange = changeEvent.getChange(changedKey);
newValue = configChange.getNewValue();
configProperties.put(changedKey, newValue);
}
// 构造新配置并应用到LoggerContext
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration newConfiguration = new PropertiesConfigurationBuilder()
.setRootProperties(copyProperties(configProperties))
.setLoggerContext(ctx)
.build();
ctx.updateLoggers(newConfiguration);
}
}
}
2. 问题描述
该代码在与Spring整合时出现问题,部分报错信息如下:
com.google.inject.ProvisionException: Unable to provision, see the following errors:
1) Tried proxying com.ctrip.framework.apollo.util.ConfigUtil to support a circular dependency, but it is not an interface.
at com.ctrip.framework.apollo.internals.DefaultInjector$ApolloModule.configure(DefaultInjector.java:59)
while locating com.ctrip.framework.apollo.util.ConfigUtil
1 error
at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
at com.ctrip.framework.apollo.internals.DefaultInjector.getInstance(DefaultInjector.java:38)
at com.ctrip.framework.apollo.build.ApolloInjector.getInstance(ApolloInjector.java:35)
at com.ctrip.framework.apollo.spi.DefaultConfigFactory.<init>(DefaultConfigFactory.java:29)
at com.ctrip.framework.apollo.spi.DefaultConfigFactory$$FastClassByGuice$$5ee2e445.newInstance(<generated>)
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:111)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:90)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:268)
at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1019)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1015)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
at com.ctrip.framework.apollo.internals.DefaultInjector.getInstance(DefaultInjector.java:38)
at com.ctrip.framework.apollo.build.ApolloInjector.getInstance(ApolloInjector.java:35)
at com.ctrip.framework.apollo.spi.DefaultConfigFactoryManager.getFactory(DefaultConfigFactoryManager.java:44)
at com.ctrip.framework.apollo.internals.DefaultConfigManager.getConfig(DefaultConfigManager.java:35)
at com.ctrip.framework.apollo.ConfigService.getConfig(ConfigService.java:61)
at com.dm.dg.common.apollo.log4j2.ApolloLog4j2ConfigurationFactory.getConfiguration(ApolloLog4j2ConfigurationFactory.java:59)
at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:353)
at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:260)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:615)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:636)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:231)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:121)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:270)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
at com.ctrip.framework.apollo.util.ConfigUtil.<clinit>(ConfigUtil.java:20)
at com.ctrip.framework.apollo.util.ConfigUtil$$FastClassByGuice$$4efdc5f4.newInstance(<generated>)
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:111)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:90)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:268)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1019)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1085)
at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1015)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
at com.ctrip.framework.apollo.internals.DefaultInjector.getInstance(DefaultInjector.java:38)
at com.ctrip.framework.apollo.build.ApolloInjector.getInstance(ApolloInjector.java:35)
at com.ctrip.framework.apollo.spring.config.PropertySourcesProcessor.<init>(PropertySourcesProcessor.java:45)
at com.ctrip.framework.apollo.spring.config.ConfigPropertySourcesProcessor.<init>(ConfigPropertySourcesProcessor.java:19)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1151)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1103)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:86)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:106)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:249)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
com.ctrip.framework.apollo.exceptions.ApolloConfigException: Unable to load instance for com.ctrip.framework.apollo.util.ConfigUtil!
at com.ctrip.framework.apollo.internals.DefaultInjector.getInstance(DefaultInjector.java:42)
at com.ctrip.framework.apollo.build.ApolloInjector.getInstance(ApolloInjector.java:35)
at com.ctrip.framework.apollo.spi.DefaultConfigFactory.<init>(DefaultConfigFactory.java:29)
at com.ctrip.framework.apollo.spi.DefaultConfigFactory$$FastClassByGuice$$5ee2e445.newInstance(<generated>)
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:89)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:111)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:90)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:268)
at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56)
at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:194)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41)
at com.google.inject.internal.InjectorImpl$2$1.call(InjectorImpl.java:1019)
at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092)
at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1015)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
at com.ctrip.framework.apollo.internals.DefaultInjector.getInstance(DefaultInjector.java:38)
at com.ctrip.framework.apollo.build.ApolloInjector.getInstance(ApolloInjector.java:35)
at com.ctrip.framework.apollo.spi.DefaultConfigFactoryManager.getFactory(DefaultConfigFactoryManager.java:44)
at com.ctrip.framework.apollo.internals.DefaultConfigManager.getConfig(DefaultConfigManager.java:35)
at com.ctrip.framework.apollo.ConfigService.getConfig(ConfigService.java:61)
at com.dm.dg.common.apollo.log4j2.ApolloLog4j2ConfigurationFactory.getConfiguration(ApolloLog4j2ConfigurationFactory.java:59)
at org.apache.logging.log4j.core.config.ConfigurationFactory$Factory.getConfiguration(ConfigurationFactory.java:353)
at org.apache.logging.log4j.core.config.ConfigurationFactory.getConfiguration(ConfigurationFactory.java:260)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:615)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:636)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:231)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:153)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
3. 问题原因
在spring
的配置文件beans-common.xml
中,引入了apollo:config
导致该问题。
依赖链如下: apollo:config
> ConfigUtil初始化 > Log4j2初始化 > ApolloLog4j2ConfigurationFactory初始化 > ConfigUtil初始化
但是,一旦在加载apollo:config
之前就初始化Log4j2就不存在该问题。
4. 解决办法
综合上述问题分析,其实只要在Apollo的NameSpaceHandler初始化之前先初始化Log4j2即可解决问题。
主要解决思路:
1. Hook Apollo的NamespaceHandler,提前加载Log4j2。(没办法覆盖spring.handlers配置文件中的内容)
2. 在各种各样的工程启动时先加载Log4j2
3. 在Spring启动之前加载Log4j2(一定要在NamespaceHandler加载前)
4.1 基于Hook Apollo NamespaceHandler方式
这里又可以采用两种方式:
* 在当前工程添加同名的NamespaceHandler类以达到覆盖Apollo框架中的该类
* 添加自定义的NamespaceHandlder。
* 自定义一个NamespaceHandler继承于Apollo的NamespaceHandler
* 在springs.handler文件自定义一个key(namespace),然后指定value为NamespaceHandler类
* 在spring.schemas文件中指定xsd位置
* 在xsd文件中指定其namespace为刚才在springs.handler中定义的key
这么麻烦的主要原因是spring中无法直接覆盖jar包中定义的NamespaceHandler
具体操作如下:
1. 添加同名NamespaceHandler类
- 自定义NamespaceHandler(没有选择这个)
4.2 在Spring启动之前加载Log4j2(现在采用的方案)
尝试过各种Spring提供的Listener,它们的启动时机都比NamespaceHandler初始化时机晚,所以也就达不到要求。
最后,回头一想,Spring也用到了Logger框架,那么Spring加载过程中肯定会加载Log4j2吧。
经过查找,发现Spring采用的为commons-logging框架。那么现在只需要在工程中添加对应的bridge依赖包即可。
<!-- Commons-Logging Log4j2 Bridge -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.11.0</version>
</dependency>
通过该bridge,spring启动时直接先启动了log4j2,完美解决问题。
5. 附log4j2在Apollo中的配置
status = warn
strict = true
property.baseDir = logs
property.appName = log4j
property.pattern = [${appName}] %d [%t] %p %C{10}.%M:%L | %m%n
property.logSize = 50MB
property.errorLogSize = 50MB
appenders = console,rolling,error
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = ${pattern}
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${baseDir}/${appName}.log
appender.rolling.filePattern = ${baseDir}/$${date:yyyy-MM}/${appName}-%d{yyyy-MM-dd}-%i.log
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = ${pattern}
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = ${logSize}
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 10
appender.rolling.strategy.delete.type = Delete
appender.rolling.strategy.delete.basePath = ${baseDir}
appender.rolling.strategy.delete.maxDepth = 2
appender.rolling.strategy.delete.iffilename.type = IfFileName
appender.rolling.strategy.delete.iffilename.glob = */${appName}-*.log
appender.rolling.strategy.delete.iffilename.iflastmodified.type = IfLastModified
appender.rolling.strategy.delete.iffilename.iflastmodified.age = 10d
appender.rolling.strategy.delete.iffilename.iflastmodified.ifany.type = IfAny
appender.rolling.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilesize.type = IfAccumulatedFileSize
appender.rolling.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilesize.exceeds = 256 MB
appender.rolling.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilecount.type = IfAccumulatedFileCount
appender.rolling.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilecount.exceeds = 10
appender.error.type = RollingFile
appender.error.name = ErrorRollingFile
appender.error.fileName = ${baseDir}/${appName}Error.log
appender.error.filePattern = ${baseDir}/$${date:yyyy-MM}/${appName}Error-%d{yyyy-MM-dd}-%i.log
appender.error.layout.type = PatternLayout
appender.error.layout.pattern = ${pattern}
appender.error.policies.type = Policies
appender.error.policies.time.type = TimeBasedTriggeringPolicy
appender.error.policies.size.type = SizeBasedTriggeringPolicy
appender.error.policies.size.size = ${errorLogSize}
appender.error.strategy.type = DefaultRolloverStrategy
appender.error.strategy.max = 10
appender.error.strategy.delete.type = Delete
appender.error.strategy.delete.basePath = ${baseDir}
appender.error.strategy.delete.maxDepth = 2
appender.error.strategy.delete.iffilename.type = IfFileName
appender.error.strategy.delete.iffilename.glob = */${appName}Error-*.log
appender.error.strategy.delete.iffilename.iflastmodified.type = IfLastModified
appender.error.strategy.delete.iffilename.iflastmodified.age = 10d
appender.error.strategy.delete.iffilename.iflastmodified.ifany.type = IfAny
appender.error.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilesize.type = IfAccumulatedFileSize
appender.error.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilesize.exceeds = 256 MB
appender.error.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilecount.type = IfAccumulatedFileCount
appender.error.strategy.delete.iffilename.iflastmodified.ifany.ifaccumulatedfilecount.exceeds = 10
logger.dm.name = com.dm
logger.dm.level = debug
logger.spring.name = org.springframework
logger.spring.level = info
logger.axis2.name = org.apache.axis2
logger.axis2.level = info
rootLogger.level = warn
rootLogger.appenderRef.stdout.ref = STDOUT
rootLogger.appenderRef.rolling.ref = RollingFile
rootLogger.appenderRef.error.ref = ErrorRollingFile
rootLogger.appenderRef.error.level = error