Logging data to different log files using log4j2? - java

I am currently working on an application which will generate 2 different log files for different purposes. Since I am new to log4j2, I am unable to achieve it. Here is my configuration file (log4j2.xml) :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="log-path">C:/Users/460681/Desktop/SourceFiles</Property>
</Properties>
<Appenders>
<Console name="console-log" target="SYSTEM_OUT">
<PatternLayout
pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
</Console>
<RollingFile name="info-log" fileName="${log-path}/SplunkOADC.log"
filePattern="${log-path}/SplunkOADC-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
</Policies>
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="trace" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</RollingFile>
<RollingFile name="error-log" fileName="${log-path}/SplunkOADC-error.log"
filePattern="${log-path}/SplunkOADC-error-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
</Policies>
<Filters>
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="trace" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
</RollingFile>
<RollingFile name="trace-log" fileName="${log-path}/SplunkOADC-trace.log"
filePattern="${log-path}/SplunkOADC-trace-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
</Policies>
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
</RollingFile>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="info-log" level="info"/>
<AppenderRef ref="trace-log" level="trace"/>
</Root>
</Loggers>
</Configuration>
I have tried filters but I'm not sure if it is the correct way. Here is my java method which is trying to log using log4j2
logger.entry("Enter The app");
String report_index_data =
"select REPORT_MODE, INDEX_ID from TABLE_NAME";
ResultSet rs = db.selectQuery(report_index_data, conn);
while(rs.next()){
logger.info("report_index_data =" +rs.getString("report_index_data"));
}
logger.exit();
Thanks!

Add a new logger to configuration.
<root level="debug">
<appender-ref ref="info-log" level="info"/>
</root>
<logger name="logger2">
<AppenderRef ref="trace-log" level="trace"/>
</logger>

First, note that if your root logger level is debug, then it will not send trace-level log events to any of its appenders; it will only debug level or higher log events to its appenders.
Second, your code uses logger.entry() and logger.exit(). For these methods to be useful you need to use a pattern layout with location patterns like %location or %method in the pattern. (E.g. [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n). This will display the name of the method you entered/exited. Be aware that calculating location information has some performance impact.

Related

log4j - write to file name as the logger name

I am trying to write my log into different files depending on the logger name...
is it even possible?
how I can use the logger name in the target file name?
this is the XML file I use:
<Configuration status="info">
<Properties>
<Property name="log-path" value="logs/"/>
<Property name="file-name" value="server"/>
<Property name="file-type" value=".log"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<RollingFile name="File" fileName="${log-path}${file-name}${file-type}"
filePattern="${file-name}-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
i have tried to use: <Property name="file-name" value="%logger"/> like in the use in PatternLayout and <Property name="file-name" value="%c{10}"/> witout secssus...
You can't do it like that with the RollingFileAppender. The appender receives log events as configured by your <Loggers> block, if log4j sends it log events with different LoggerNames they will be appended to whatever file is open. A RollingFileAppender writes to one file at a time and rolls when the configured policy tells it to.
You could write to different files by setting up multiple Loggers that target different appenders. Like this:
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<RollingFile name="FileA"
filePattern="/tmp/A-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
<RollingFile name="FileB"
filePattern="/tmp/B-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.example.App" level="info" additivity="false">
<AppenderRef ref="FileA"/>
</Logger>
<Logger name="org.example.App2" level="info" additivity="false">
<AppenderRef ref="FileB"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
To route each event to a different RollingFileAppender based on some pattern you can use a RoutingAppender.
The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. The RoutingAppender should be configured after any Appenders it references to allow it to shut down properly.
You can also configure a RoutingAppender with scripts: you can run a script when the appender starts and when a route is chosen for an log event.
Here is how you could route based on LoggerName:
<Configuration status="info">
<Properties>
<Property name="log-path" value="logs/"/>
<Property name="file-name" value="server"/>
<Property name="file-type" value=".log"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<Routing name="Routing">
<Routes pattern="$${event:Logger}">
<Route>
<RollingFile name="Rolling-${event:Logger}" fileName="${log-path}${file-name}-${event:Logger}${file-type}"
filePattern="${file-name}-%d{yyyy.MM.dd_HH.mm.ss}-%i-${event:Logger}.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</RollingFile>
</Route>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Routing"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Also, out of interest, if you really want to you can implement your own Appender that does whatever you want with the LogEvent.
Here's a very rough start. It's an Appender that creates a RollingFileAppender per LoggerName. It only works if you use a SizeBasedTriggeringPolicy. You should be able to drop a class like that into your project and use XML like:
<Configuration status="info">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
</Console>
<FilePerLoggerNameAppender name="File"
filePattern="/tmp/log-%d{yyyy.MM.dd_HH.mm.ss}-%i-$LOGGER$.log">
<PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
<SizeBasedTriggeringPolicy size="1 MB"/>
</FilePerLoggerNameAppender>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
and see log files created with $LOGGER$ replaced with your logger names.

log4j2 in Java project - Can't find output

Im new here, Please help me to understand my new project's log4j2 configuration.
My question is:
How to get all Log outputs?
From where should I search log files?
Also how to save tomcat console outputs in the txt file?
I really appreciate your help and support, Today I want to learn something new from you guys! Thanks!
This is the log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error" monitorInterval="1800">
<Properties>
<Property name="LOG_HOME">\Workspaces\logs\paymentweb</Property>
<Property name="LOG_DEBUG">${LOG_HOME}\app\debug.log</Property>
<Property name="LOG_INFO">${LOG_HOME}\app\info.log</Property>
<Property name="LOG_ERROR">${LOG_HOME}\app\error.log</Property>
</Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
(onMismatch)-->
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy.MM.dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
</Console>
<RollingRandomAccessFile name="app_debug" fileName="${LOG_DEBUG}" append="false" filePattern="${LOG_HOME}\$${date:yyyy-MM}\debug-%d{MM-dd-yyyy}-%i.log.gz">
<Filters>
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
</Filters>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="50 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
</RollingRandomAccessFile>
<CustomRollingRandomAccessFile name="app_info" fileName="${LOG_INFO}" append="false" filePattern="${LOG_HOME}\$${date:yyyy-MM}\info-%d{MM-dd-yyyy}-%i.log.gz">
<Filters>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="50 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
</CustomRollingRandomAccessFile>
<CustomRollingRandomAccessFile name="app_error" fileName="${LOG_ERROR}" append="false" filePattern="${LOG_HOME}\$${date:yyyy-MM}\error-%d{MM-dd-yyyy}-%i.log.gz">
<Filters>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss z} %-5level %class{36}.%M()/%L - %msg%xEx%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="50 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
</CustomRollingRandomAccessFile>
</appenders>
<loggers>
<root level="trace" additivity="false">
<appender-ref ref="Console"/>
<appender-ref ref="app_debug"/>
<appender-ref ref="app_info"/>
<appender-ref ref="app_error"/>
</root>
</loggers>
</configuration>
all your logs are in \Workspaces\logs\paymentweb\app*.log
You can find out details about how your appenders are configured by enabling internal Log4j2 "status" logging.
At the top of your configuration file, change it to TRACE <configuration status="trace" monitorInterval="1800">. I believe this will show the full path of the file appenders on the console. (No guarantees for the custom appender CustomRollingRandomAccessFile.)
Also, you have a non-XML compliant snippet inside the <Console> appender configuration. This looks bad and should be removed:
(onMismatch)-->

log4j vs log4j2: log to different file

Using log4j I can log to different files invoking this method:
Logger.getLogger("test")
where test is an appender defined in log4j.properties. How can I log to different files with log4j2? This is my configuration file and I would choose programmatically where to log:
<Properties>
<Property name="log-path">C:/logs</Property>
</Properties>
<Loggers>
<Logger name="it.mypackage" level="debug" additivity="false">
<appender-ref ref="file" level="debug" />
<appender-ref ref="file2" level="error" />
</Logger>
</Loggers>
<Appenders>
<!-- file.log -->
<RollingFile name="file" fileName="${log-path}/file.log" filePattern="${log-path}/file-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<!-- file2.log -->
<RollingFile name="file2" fileName="${log-path}/file2.log" filePattern="${log-path}/file2-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
</Appenders>
[SOLUTION]
Oh Yes, I'm missing a logger:
<Properties>
<Property name="log-path">C:/logs</Property>
</Properties>
<Loggers>
<Logger name="logger1" level="debug" additivity="false">
<appender-ref ref="file" level="debug" />
</Logger>
<Logger name="logger2" level="debug" additivity="false">
<appender-ref ref="file" level="debug" />
<appender-ref ref="file2" level="error" />
</Logger>
</Loggers>
<Appenders>
<!-- file.log -->
<RollingFile name="file" fileName="${log-path}/file.log" filePattern="${log-path}/file-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<!-- file2.log -->
<RollingFile name="file2" fileName="${log-path}/file2.log" filePattern="${log-path}/file2-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
</Appenders>
I can choose logger in this way:
private static Logger logger = LogManager.getLogger("logger1");
If you keep the rest of the configuration the same, but modify the Loggers section:
<Loggers>
<Logger name="logger1" level="debug" additivity="false">
<appender-ref ref="file" level="debug" />
</Logger>
<Logger name="logger2" level="debug" additivity="false">
<appender-ref ref="file2" level="error" />
</Logger>
</Loggers>
Now, you can select the appender in your code by getting the logger by name:
Logger logger1 = LogManager.getLogger("logger1");

Log4j2 in a Unix environment

I have made a project in which I am creating logs with log4j2.xml. My configuration file works perfectly when I am running it in the eclipse of my windows system. Here is the configuration file which I have used to create the log files.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><Configuration status="WARN">
<Properties>
<Property name="log-path">/home/apps/ora_fin/IGL75D/Disco/splunk/log</Property>
</Properties>
<Appenders>
<RollingFile fileName="${log-path}/SplunkOADC.log" filePattern="${log-path}/SplunkOADC-%d{yyyy-MM-dd}.log" name="info-log">
<Filters>
<ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
<RollingFile fileName="${log-path}/SplunkOADC-trace.log" filePattern="${log-path}/SplunkOADC-trace-%d{yyyy-MM-dd}.log" name="trace-log">
<Filters>
<ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="fatal" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<ThresholdFilter level="FATAL" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger level="all" name="com.aviva.uk.gi.NUProcessOSBReportDataParserPkg">
<AppenderRef ref="info-log"/>
<AppenderRef ref="trace-log"/>
</Logger>
<Root>
</Root>
</Loggers>
</Configuration>
This configuration file I have put under the src folder in my project and is picked up without any issues. However I need to deploy the application in the Unix environment, where should I put the configuration file in unix environment so that it is picked up by the java class to log ??
Thanks!
How about using a jvm argument always
-Dlog4j.configuration={path to file}
This should work irrespective of the environment you deploy in.
The simplest thing to do is to just add the config file to the classpath of your application.
For a web app that means putting it in WEB-INF/classes/.
Alternatively you can use the system property suggested in the other answer.

How does RollingFileAppender work with log4j2?

I'm use to RollingFileAppender on normal log4j. Now I'm switching to log4j2, and cannot get the appender to work.
The File appender below works as expected. But the logging file for RollingFile is never created. Why?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="FILE" fileName="c:/logs.log">
<PatternLayout pattern="%d %p %c: %m%n" />
</File>
<RollingFile name="ROLLING" fileName="c:/logsroll.log">
<PatternLayout pattern="%d %p %c: %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="0.001 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="FILE" />
<AppenderRef ref="ROLLING" />
</Root>
</Loggers>
</Configuration>
The RollingFile tag is missing a filePattern attribute.
<RollingFile name="ROLLING"
fileName="c:/logsroll.log"
filePattern="c:/logsroll-%i.log">
I used log4j2 version 2.0, in some cases it throws error if you do not set any date in file pattern, in this case you can use some thing like below:
<RollingFile name="MyFile" fileName="d:/log/bsi/admin/total/totalLog.log"
filePattern="d:/log/totalLog-%d{MM-dd-yyyy}-%i.log">
<PatternLayout>
<Pattern>%d %p %c [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="2000"/>
</RollingFile>

Categories