how to configure log4j2 webapplication - java

Am little new to web applications, recently I was in need to employ a logging mechanism and for that I choose Log4J2, I went through there guide, and downloaded required libraries. This is what so far I did.
1. Added following jars to web-inf/lib
-- log4j-core2.1.jar
-- log4j-api-2.1.jar
-- log4j-web-2.1.jar
2. Added below xml as, log4j2.xml in java/src directory
<?xml version="1.0" encoding="UTF-8"?>
<configuration name="NONPROD" status="OFF">
<Properties>
<Property name="log-path">logs</Property>
</Properties>
<Appenders>
<Console name="console-log" target="SYSTEM_OUT">
<!-- <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n -->
<!-- </pattern> -->
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<RollingFile name="info-log" fileName="${log-path}/web-info.log"
filePattern="${log-path}/web-info-%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" />
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
<RollingFile name="error-log" fileName="${log-path}/web-error.log"
filePattern="${log-path}/web-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" />
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
<RollingFile name="debug-log" fileName="${log-path}/web-debug.log"
filePattern="${log-path}/web-debug-%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" />
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
<RollingFile name="trace-log" fileName="${log-path}/web-trace.log"
filePattern="${log-path}/web-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" />
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.demo.web.log4j2.file" level="debug"
additivity="false">
<appender-ref ref="trace-log" level="trace" />
<appender-ref ref="error-log" level="error" />
<appender-ref ref="debug-log" level="debug" />
<appender-ref ref="info-log" level="info" />
</Logger>
<Logger name="com.demo.web.log4j2.console" level="all"
additivity="false">
<AppenderRef ref="console-log" />
</Logger>
<Root level="info" additivity="true">
<AppenderRef ref="console-log" />
</Root>
</Loggers>
</configuration>
3. third and last i wrote an small web service to test logging
#Path("/register")
public class Register {
private DataManager mManager;
private static final Logger LOG = LogManager.getLogger(Register.class);
public Register(){
mManager = DataManager.getInstance();
}
#GET
#Path("/{param}")
public Response getMsg(#PathParam("param") String msg) {
LOG.error("Not supported operations");
return Response.status(Response.Status.BAD_REQUEST)
.entity("Not supported").build();
}
But in console, upon trigger get request this is all i got printed.
INFO: Server startup in 35959 ms
Not supported operations // this is not in pattern i supplied in log4j2.xml
// this is my pattern
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
I figure out this is probably due to some thing gone wrong, and am struggling to find the actual cause, being totally new to web programming, please help me out to configure my logger.
Thanks,
Techfist

Your servlet container is using some other logging framework which logs to console. Figure out which logging framework that is and use one of log4j2's bridge libraries to redirect output to your log4j2 setup.

Alright, I found the cause behind this, Issue was primarily happening due to two reasons.
First I was suppose to exclude log4j* pattern from jarsToSkip attribute in catilina property
Second, i had kept two log4j2.xml one inside web-inf other inside java/src, it was supposed to be only present at java/src. two files were not required.
Third, but not mandatory, before deployment just check if log4j2.xml is included inside web-inf/classes or not, if not then simply add it.
that's it, after following this issue was resolved now am getting proper logs.

Related

Log4j does not print to console nor write to file

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AzulMain {
private static final Logger LOGGER = LogManager.getLogger(AzulMain.class.getName());
public static void main(String[] args){
LOGGER.info("Maybe my first Logger works?");
}
}
The imports work fine. I use these jar-files:
log4j-1.2-api-2.17.2.jar
log4j-api.2.17.2.jar
log4j-core-2.17.2.jar
And this is how my XML-file (log4j2.xml) looks. It is in the same folder as my AzulMain:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="log-path">log/${date:yyyy-MM-dd HH-mm-ss-SSS}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>
</PatternLayout>
</Console>
<File name="File-Appender-AzulMain" fileName="${log-path}/Azul.log">
<PatternLayout>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>
</PatternLayout>
</File>
<RollingFile name="RollingFile-Appender"
fileName="${log-path}/rollingfile.log"
filePattern="${archive}/rollingfile.log.%d{yyyy-MM-dd#HH-mm}.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="30 MB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="AzulMain" level="trace" additivity="false">
<AppenderRef ref="File-Appender-AzulMain" level="all"/>
<AppenderRef ref="Console-Appender" level="info"/>
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>
When I use JavaUtilLogger everything works quite fine so far, I can make it create a file and print to console, however, with log4j nothing works.
I tested deleting the XML file and adding BasicConfigurator.configure() into my main-method, but it still didn't work. If I start my main-method all I get is:
Process finished with exit code 0
What is strange to me is that when I use the command java -Dlog4j.debug -cp AzulMain, it does not show me my configuration as I would expect it, but just what seems to be a very generic help message.
It is my first time, I am using a logger. Does anyone know what the problem might be?
Update:
This helped me as a first step:
BasicConfigurator replacement in log4j2
I deleted the XML-file and used the new
Configurator.initialize(new DefaultConfiguration());
Configurator.setRootLevel(Level.INFO);
And now it works at least in so far as it prints to the console. However, I am still not able to make it use the log4j2.xml file. I tried naming it log4j2-test.xml, too. (Source) It did not make a difference.
Now it works. This is how I did it.
I set up a new project, with just a main-class and added a new xml-file with a file logger only at first, then added a logger to the console, too. I deleted cache in IntelliJ and deleted the Configurator-lines in the code.
This is the new XML-file log4j2.xml that made it work:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">log/${date:yyyy-MM-dd HH-mm-ss-SSS}</Property>
</Properties>
<!-- File Logger -->
<Appenders>
<!-- Console appender configuration -->
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>>
</PatternLayout>
</Console>
<RollingFile name="fileLogger"
fileName="${basePath}/Azul.log"
filePattern="${basePath}/app-%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" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<!-- Max 10 files will be created everyday -->
<DefaultRolloverStrategy max="10">
<Delete basePath="${basePath}" maxDepth="10">
<!-- Delete all files older than 30 days -->
<IfLastModified age="30d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<appender-ref ref="fileLogger" />
<appender-ref ref="Console-Appender" level="info"/>
</Root>
</Loggers>
</Configuration>
It seems to me to have been a mistake somewhere in the xml-file that I just couldn't figure out where it is.

ImmediateFlush not working in Log4j2

I am getting this error:
ERROR asyncRoot contains an invalid element or attribute "immediateFlush"
When I use immediateFlush attribute in appender in log4j2.xml.
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd-MM-yy HH:mm:ss} [$${ctx:instId} - $${ctx:userId}] %c.%M(%L)- %m%n" />
</Console>
<RollingFile name="csroot"
fileName="${cslogs}/cslog.log" filePattern="${cslogs}/$${date:yyyy-MM}/cslog-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{dd-MM-yy HH:mm:ss} [$${ctx:instId} - $${ctx:userId}] %c.%M(%L)- %m%n" immediateFlush="false"/>
<Policies>
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="1000">
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
Try with this modification:
<RollingFile name="csroot"
fileName="${cslogs}/cslog.log" filePattern="${cslogs}/$${date:yyyy-MM}/cslog-%d{yyyy-MM-dd}-%i.log" immediateFlush="false">
<PatternLayout pattern="%d{dd-MM-yy HH:mm:ss} [$${ctx:instId} - $${ctx:userId}] %c.%M(%L)- %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="1000">
</DefaultRolloverStrategy>
</RollingFile>
immediateFlush is not an attribute of PatternLayout.
I know its quite an old question but might help somebody.
RollingFile Appender Parameters points out the immediateFlush is the property of the appender. But you have it declared as an attribute for PatternLayout which is what is causing the error.
Sample RollingFile appender configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"
immediateFlush="false">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>

how to roll a new log file in routing appender everyday

My routing log4j2.xml should role log file based on user login.
Assume a user logs in the application for consecutive 3 days and do his stuff for around half an hour and then logs out. So as per requirement 3 log files should be created for the logged user (one file per day basis in separate file)
like e.g.
john-20-11-2015.log,
john-21-11-2015.log,
john-22-11-2015.log
below is the Log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Configuration status="WARN" name="MySite" monitorInterval="30">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout>
<pattern>[%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%c{1}] - %msg%n</pattern>
</PatternLayout>
</Console>
<RollingFile name="error-log"
fileName="D:/myLogs/error [${date:yyyy-MM-dd}].log" filePattern="D:/myLogs/error-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%c{1}] - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
<RollingFile name="trace-log"
fileName="D:/myLogs/trace [${date:yyyy-MM-dd}].log" filePattern="D:/myLogs/trace-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%c{1}] - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
<Routing name="RoutingAppender">
<Routes pattern="$${ctx:logFileName}">
<Route>
<RollingFile name="Rolling-${ctx:logFileName}" append="true"
fileName="D:/myLogs/${ctx:logFileName}~${date:yyyy-MM-dd}.log"
filePattern="D:/myLogs/%d{yyyy-MM-dd}-%i.log">
<PatternLayout
pattern="SERVER-LOG: [%-5level] [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%logger{1}] - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
</Route>
<Route ref="Console" key="$${ctx:logFileName}" />
</Routes>
</Routing>
</Appenders>
<Loggers>
<Root level="trace" additivity="false">
<Appender-Ref ref="Console"/>
<appender-ref ref="error-log" level="error"/>
<appender-ref ref="trace-log" level="trace"/>
<Appender-Ref ref="RoutingAppender" />
</Root>
</Loggers>
</Configuration>
I am calling
ThreadContext.put("logFileName", userName);
to append the log in the routing appender, the log were appending correctly in the respective logs
and I am clearing the threadcontext during logout method
ThreadContext.remove("logFileName");
ThreadContext.clearAll();
I hosted my application in tomcat. log files were generated based on logged user for every user based on the file name pattern, but log is not generated on daily basis, instead of that its appended the current day log of users in previous day log
eg: john-20-11-2015.log contains the log of of 21st and 22nd
its roles a new log file only when tomcat is stop started .
guys help me out.. is there anything wrong
I think you want DailyRollingFileAppender here is an example
Also please look at the similar question
example:
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
...
<param name="DatePattern" value="'.'yyyy-MM-dd" />
...
</appender>
The filename attribute is only evaluated when the appender is created. It does not change on each rollover. You should get a new file on each rollover that does have the correct date in it.
Is that not what you are seeing?

configure log4j with custom level of verbose

I want to configure my log4j.xml with custom level of verbose - say 350 - in order to print up to some verbose level and including new prints of telemetry that will be at this new level - 350.
What is wrong/missing in my file?
<!--print logs of telemetry, warning and above -->
<CustomLevels>
<CustomLevel name="telemetryLevel" intLevel="350"/>
</CustomLevels>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<RollingFile name="deviceTelemetry" fileName="/home/device/telemetry-${date:yyyy-MM-dd}.log" append="false"
filepattern="/home/device/telemetry-${date:yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10M"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="deviceTelemetry" level="telemetryLevel">
<AppenderRef ref="deviceTelemetry"/>
</Logger>
<Root>
<AppenderRef ref="Console" level="trace"/>
</Root>
</Loggers>
this way i get the logger in code:
Logger log = LogManager.getLogger("deviceTelemetry");
i don't know yet how to call the logger to append a message. there is a method log(Level level, String message) which gets a level so it might work - i cannot check it yet.

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