java以编程方式创建复合过滤器,以在log4j 2中定义多个过滤器
要为log4j(版本2)中的一个元素定义多个过滤器,需要一个复合过滤器(根据documentation)。 在使用编程配置时,我不知道如何创建/添加这样的过滤器元素:
import java.io.IOException;
import java.net.URI;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
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.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.CompositeFilterComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.KeyValuePairComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
public class ConfigurationFactory_Demo {
public static void main(String[] args) {
ConfigurationFactory configurationFactory = new ConfigurationFactoryClass();
ConfigurationFactory.setConfigurationFactory(configurationFactory);
Logger logger = LogManager.getLogger("com.logger");
logger.info( String.format("Logging Event"));
}
public static class ConfigurationFactoryClass extends ConfigurationFactory {
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
return getConfiguration(loggerContext, source.toString(), null);
}
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) {
ConfigurationBuilder builder = newConfigurationBuilder();
return createConfiguration(name, builder);
}
@Override
protected String[] getSupportedTypes() {
return new String[] {"*"};
}
Configuration createConfiguration(final String configurationName, ConfigurationBuilder configuration) {
configuration.setConfigurationName(configurationName);
configuration.setStatusLevel(Level.INFO);
// Create appender:
AppenderComponentBuilder appenderComponent = configuration.newAppender("stdout", "CONSOLE");
appenderComponent.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
LayoutComponentBuilder layoutComponent = configuration.newLayout("PatternLayout");
layoutComponent.addAttribute("pattern", "%msg%n");
appenderComponent.add(layoutComponent); // adding layout to appender
configuration.add(appenderComponent); // adding appender to configuration
// Create root logger:
RootLoggerComponentBuilder rootLoggerComponent = configuration.newRootLogger(Level.ERROR);
rootLoggerComponent.add(configuration.newAppenderRef("stdout"));
configuration.add(rootLoggerComponent); // adding logger to configuration
// Create logger:
LoggerComponentBuilder loggerComponent = configuration.newLogger("com.logger", Level.TRACE);
loggerComponent.addAttribute("additivity", false);
AppenderRefComponentBuilder appenderRefComponent = configuration.newAppenderRef("stdout");
appenderRefComponent.addAttribute("level", "TRACE");
// Create filter 'Marker':
FilterComponentBuilder filterComponent_marker = configuration.newFilter("MarkerFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL);
filterComponent_marker.addAttribute("marker", "MarkerTag");
// Create filter 'Thread Context Map:
FilterComponentBuilder filterComponent_threadContextMap;
filterComponent_threadContextMap = configuration.newFilter("ThreadContextMapFilter", Filter.Result.ACCEPT, Filter.Result.DENY);
KeyValuePairComponentBuilder keyValuePairComponent;
keyValuePairComponent = configuration.newKeyValuePair("key", "value");
filterComponent_threadContextMap.addComponent(keyValuePairComponent);
boolean useCompositeFilter = false;
if (useCompositeFilter) {
CompositeFilterComponentBuilder filterComponent_composite = null; // HOW TO INITIALIZE 'CompositeFilterComponentBuilder' ?
filterComponent_composite.add(filterComponent_marker);
filterComponent_composite.add(filterComponent_threadContextMap);
// appenderRefComponent.add(filterComponent_composite); // HOW TO ADD 'CompositeFilterComponentBuilder' to appender-reference ?
} else {
appenderRefComponent.add(filterComponent_marker); // adding filter directly to appender-reference
appenderRefComponent.add(filterComponent_threadContextMap); // adding second filter directly to appender-reference (NOT ALLOWED)
}
loggerComponent.add(appenderRefComponent); // adding appender-reference to logger
configuration.add(loggerComponent); // adding logger to configuration
try { configuration.writeXmlConfiguration(System.out); } catch (IOException e) {}
BuiltConfiguration buildConfiguration = configuration.build();
return buildConfiguration;
}
}
}
这段Java代码的结果如下所示。它生成错误“AppenderRef没有与元素ThreadContextMapFilter匹配的参数”
<?xml version="1.0" ?>
<Configuration name="18b4aac2" status="INFO">
<Appenders>
<CONSOLE name="stdout" target="SYSTEM_OUT">
<PatternLayout pattern="%msg%n"/>
</CONSOLE>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="stdout"/>
</Root>
<Logger name="com.logger" level="TRACE" additivity="false">
<AppenderRef ref="stdout" level="TRACE">
<MarkerFilter onMatch="ACCEPT" onMismatch="NEUTRAL" marker="MarkerTag"/>
<ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="key" value="value"/>
</ThreadContextMapFilter>
</AppenderRef>
</Logger>
</Loggers>
</Configuration>
正确的配置应为:
<?xml version="1.0" ?>
<Configuration name="18b4aac2" status="INFO">
<Appenders>
<CONSOLE name="stdout" target="SYSTEM_OUT">
<PatternLayout pattern="%msg%n"/>
</CONSOLE>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="stdout"/>
</Root>
<Logger name="com.logger" level="TRACE" additivity="false">
<AppenderRef ref="stdout" level="TRACE">
<Filters>
<MarkerFilter onMatch="ACCEPT" onMismatch="NEUTRAL" marker="MarkerTag"/>
<ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="key" value="value"/>
</Filters>
</ThreadContextMapFilter>
</AppenderRef>
</Logger>
</Loggers>
</Configuration>
在这种情况下,如何以编程方式定义复合过滤器
# 1 楼答案
可以使用
ConfigurationBuilder.newComponent()
方法实例化CompositeFilter: