I am creating a log4j2 logger programmatically and adding appenders to it.
I want the logger to write the messages in two different locations / files according to some parameter/criteria.
For this I found that RoutingAppender can be good option to route the messages in different locations.
And for the criteria with the help of which I want to route messages, I am using Marker as used in How to create multiple log file programatically in log4j2?
But I am enable to manage it properly.Below is my code snippet for reference :
public class Log4j2TestApplication {
private static final Marker MARKER1 = MarkerManager.getMarker("MARKER1");
private static final Marker MARKER2 = MarkerManager.getMarker("MARKER2");
public static void main(String[] args) {
String loggerName = "demoLogger";
final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
final LoggerComponentBuilder loggerComp = builder.newLogger(loggerName, Level.ALL).addAttribute("additivity",
false);
builder.add(loggerComp);
Configuration configuration = builder.build();
LoggerContext ctx = Configurator.initialize(builder.build());
ctx.start(configuration);
ctx.updateLoggers(configuration);
Logger logger = ctx.getLogger(loggerName);
Appender csvAppender = createCsvAppender(configuration);
Appender textAppender = createTextAppender(configuration);
csvAppender.start();
textAppender.start();
logger.addAppender(csvAppender);
logger.addAppender(textAppender);
Appender routingAppender = createRoutingAppender(configuration, textAppender, csvAppender);
routingAppender.start();
logger.addAppender(routingAppender);
logger.error(MARKER1, "the text message", "testing parameter");
logger.error(MARKER2, "the csv message", "testing parameter");
csvAppender.stop();
textAppender.stop();
routingAppender.stop();
}
private static Appender createCsvAppender(final Configuration config) {
return RollingFileAppender.newBuilder().setConfiguration(config).setName("csvAppender")
.withFileName("TestFile.csv").withFilePattern("TestFile.csv")
.withPolicy(SizeBasedTriggeringPolicy.createPolicy("100M"))
.withStrategy(DefaultRolloverStrategy.newBuilder().withConfig(config).build()).withImmediateFlush(true)
.setFilter(ThresholdFilter.createFilter(Level.ALL, Result.ACCEPT, Result.DENY)).setLayout(getCsvLayout(config))
.build();
}
private static Layout<String> getCsvLayout(final Configuration config) {
return new CsvParameterLayout(config, StandardCharsets.UTF_8, CSVFormat.DEFAULT.withDelimiter(','),
"column1;column2\n", null);
}
private static Appender createTextAppender(final Configuration config) {
return RollingFileAppender.newBuilder().setConfiguration(config).setName("txtAppender")
.withFileName("TestFile.txt").withFilePattern("TestFile.txt")
.withPolicy(SizeBasedTriggeringPolicy.createPolicy("100M"))
.withStrategy(DefaultRolloverStrategy.newBuilder().withConfig(config).build()).withImmediateFlush(true)
.setFilter(ThresholdFilter.createFilter(Level.ALL, Result.ACCEPT, Result.DENY)).setLayout(getTextLayout(config, "header\n"))
.build();
}
private static Layout<String> getTextLayout(final Configuration config, final String header) {
return PatternLayout.newBuilder().withConfiguration(config).withCharset(StandardCharsets.UTF_8)
.withPattern("[%d][%-5.-5p]").withHeader(header).build();
}
private static Appender createRoutingAppender(final Configuration config, Appender appender1, Appender appender2) {
Route[] routeArray = new Route[2];
routeArray[0] = Route.createRoute(appender1.getName(), "MARKER1", null);
routeArray[1] = Route.createRoute(appender2.getName(), "MARKER2", null);
Routes routes = Routes.newBuilder().withRoutes(routeArray).withPattern("marker").build();
Appender routingAppender = RoutingAppender.newBuilder().setName("routingAppender").setConfiguration(config)
.withRoutes(routes).build();
return routingAppender;
}
}
I have referenced below links also but I could not find the accurate way of RoutingAppender programmatically.
Is there a way to Route logs based on Marker with the RoutingAppender in Log4j2