I am using log4j 2. I am trying to determine why my log file is not being written to, but my console is. This is the output I have to the console:
2016-04-25 12:26:07,142 INFO [main] helperCode.LogPlus (LogPlus.java:50) -
----------------------------------------------------------------------------
------------ The test is starting now at 2016-04-25-12-26-07-135 -----------
----------------------------------------------------------------------------
2016-04-25 12:26:07,151 INFO [main] helperCode.LogPlus (LogPlus.java:50) -
--------------------------------------------------------------------------
------------ METHOD loginBadPasswordGoodUsername_3 starting: ------------
--------------------------------------------------------------------------
The issues I've considered already:
The output is not repeating itself, so the log output being redirected is not an issue.
I am NOT using java.util.logging.Logger anywhere in my project;
The output of the log file is formatted in log4j style rather than JUL style, so I know that JUL is not overriding it;
Here is my XML config file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="FileLogger" fileName="${sys:logFilePath}" append="false">
<PatternLayout pattern="%d %t %-5p %c{2} - %m%n" />
</File>
<Async name="Async">
<AppenderRef ref="FileLogger" />
</Async>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="automationFramework" level="trace">
<AppenderRef ref="FileLogger" />
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
I am directing the output to the file located at the system variable "logFilePath".
I am not sure what is going on, and the config files shown on answers for similar questions are not in XML format, so I am not sure how to commute the config file code to XML.
In your case as mentioned in the comment you do not have the package called applicatiionFramework. So change the name attribute by the package name of the classes where you want to record log events.
<Logger name="your package" level="trace">
<AppenderRef ref="FileLogger" />
<Root level="trace">
<AppenderRef ref="STDOUT" />
</Root>
</Logger>
For more information visit log4j-manual-configuration
Glad the other answer helped. Do you need the named logger though? Why not just have the root logger? Also, you declared an Async Appender but are not using it. Is that on purpose? This is what I would suggest:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="FileLogger" fileName="${sys:logFilePath}" append="false">
<PatternLayout pattern="%d %t %-5p %c{2} - %m%n" />
</File>
<Async name="Async">
<AppenderRef ref="FileLogger" />
</Async>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n" />
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="STDOUT" level="info" />
<AppenderRef ref="Async" />
</Root>
</Loggers>
</Configuration>
Note that you can also specify a level on the AppenderRef. I made the Console Appender level INFO to illustrate this point.
If you want the log to show location information and use Async loggers or appenders then you need to specify includeLocation="true" on the Async Appender.
For the complete noob, like myself, this line in Unknown's answer above:
<Logger name="your package" level="trace">
is the key. When it says "your package" it really means the "package foo.bar" you declared at the top of the .java file where you created the Logger, not the class name you passed to create the Logger, like:
LOGGER = LogManager.getLogger(MyClass.class.getName());
It took me a ridiculous amount of time today to get my log4j2 output going to a file, playing with various "name" values until the light bulb went on.
Related
According to log4j documentation, if I define a logger config for package com.a.b.c with level ERROR with root logger level set to DEBUG, only ERROR logs should come from classes in com.a.b.c while other classes should print DEBUG logs. Therefore I have the below log4j2-test.xml.
However, in my case INFO level logs from classes in com.a.b.c are still being printed. Did I misunderstand anything? What should I do to make classes in com.a.b.c print ERROR logs while all other classes print INFO logs?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="PropertiesConfig" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="basePath">target/</Property>
</Properties>
<ThresholdFilter level="trace"/>
<Appenders>
<Console name="consoleLogger" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd-MM-yyyy HH:mm:ss.SSS} %style{[%t]}{magenta} %highlight{%-5level}{TRACE=cyan, DEBUG=green, INFO=yellow, WARN=blue, ERROR=red} [%-60.60c] : %m%n" />
</Console>
<File name="fileLogger" fileName="${basePath}app.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%c] [%M] [%l] : %msg%n" />
</File>
</Appenders>
<Loggers>
<Root level="INFO" >
<AppenderRef ref="consoleLogger" />
<AppenderRef ref="fileLogger" />
</Root>
<Logger name="com.a.b.c" level="ERROR" additivity="false">
<AppenderRef ref="consoleLogger" />
<AppenderRef ref="fileLogger" />
</Logger>
</Loggers>
</Configuration>
I figured this out. The class in question is (weirdly) not using its own class name when getting the logger. Typically it is LoggerFactory.getLogger(com.a.b.c) but in my case the class is doing LoggerFactory.getLogger(java.io.Console), thus our logger config <Logger name="com.a.b.c" level="ERROR" additivity="false"> will not apply to logs coming from this class. I had to add a logger config for the class java.io.Console.
I have 2 appenders I'm using - Console and custom appender called MyAppender which should ignore all messages with levels lower than ERROR (meaning - it should only support ERROR and FATAL). The Console should be able to support all levels.
I've tried several ways to define it but it seems that the filter doesn't work for the root level appenders. How can this be achieved? My current log4j2 definition:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="com.mysample.logging.appenders" status="DEBUG">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<MyAppender name="MyAppender">
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</MyAppender>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="Console"/>
<AppenderRef ref="MyAppender" />
</Root>
</Loggers>
</Configuration>
The loggers are one hierarchy starting with the root logger.
There are no two root loggers within one working setup of Log4j.
What you want to achieve is to have different thresholds on the appenders. Check the link that Piotr suggested:
Using log4j2, is it possible to assign a specific level to a appender?
I have a maven web project which requires logging.
I decided to use log4j2 for that purpose and added the required entries in the pom.xml file
Then I created the log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<RollingFile name="RollingFile" fileName="${logs.path}/text.log"
filePattern="${logs.path}/%d{YYYYMMdd}-text.%i.log">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" />
<Policies>
<SizeBasedTriggeringPolicy size="100 MB" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} %-5p %c{1}:%L - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="root" level="info" additivity="false">
<appender-ref ref="RollingFile" level="info" />
<appender-ref ref="Console" level="info" />
</Logger>
<Root level="info" additivity="false">
<AppenderRef ref="RollingFile" />
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
I'm starting tomcat with -Dlogs.path="C:\mylogs", where C:\mylogs exists and has public read/write access.
The console logger is working fine, I can see the correct output in my console, the issue is that the file isn't being created, so I have no logfile, everything gets logged to catalina.out only, and the tomcat startup logs don't show errors for log4j.
What am I missing? is there some additional configuration I need to do in order to log to file?
I went through the documentation. You must refer to system properties with sys:, and it seems that tomcat properties are seen as system properties, so I replaced ${logs.path} with ${sys:logs.path} and it worked.
To create a log file with the log4j2 config you first need to define your appender. Here's an example:
<RollingFile name="MGMT"
fileName="${logdir}/mgmt.log"
filePattern="${logdir}/mgmt.%d{yyyy-MM-dd}.log">
<PatternLayout pattern="${layout}"/>
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${logdir}" maxDepth="1">
<IfFileName glob="mgmt.*.log" />
<IfAccumulatedFileCount exceeds="10" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
Afterwards you just need to define a logger that will use it:
<Logger name="the package or name that is displayed in the log line"
level="ALL"
additivity="false">
<AppenderRef ref="MGMT"/>
</Logger>
If you have a log that has com.company.test as package set that package as name for the logger. It's important that they match.
The field additivity will define if you want to pass the catched log to its parent ( true ) or just let this logger handle it ( false )
EDIT:
your config file might need this:
<Configuration status="info">
<Properties>
<Property name="logdir">${sys:catalina.base}/logs</Property>
<Property name="layout">%d [%t] %-5p %c- %m%n</Property>
</Properties>
<Appenders>
If you don't want to use this you have to define the path static like <RollingFile name="MGMT"
fileName="C:\path\file.log"
Why does log4j prints a new line break in stdout appender?
my log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
<Appenders>
<File name="FILE" fileName="<<FILEPATH>>\logfile.log"
append="true">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} | %-5p | %l - %m%n" />
</File>
<File name="UIFILE" fileName="<<FILEPATH>>\uilogfile.log"
append="true">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} | %m%n" />
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout>
<pattern>[%-5p] %C{2} - %m%n</pattern>
</PatternLayout>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="INFO"/>
<Logger name="com.foo" level="DEBUG" />
<Logger name="com.foo.services.web.controllers.FOOLoggingController"
level="INFO">
<AppenderRef ref="UIFILE" />
</Logger>
<Root>
<AppenderRef ref="STDOUT" />
<AppenderRef ref="FILE" />
</Root>
</Loggers>
</Configuration>
everything works fine but I get a new line between outputs, don't know why!
I tried few things like removing %n from the pattern layout but when i do this, the log itself stops coming. The file output is good. It doesn't prints new line in between. Has someone faced a similar issue?
I solved this issue by replacing %n with \n inside the Console's pattern string. So the Console appender would look like:
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern ="[%-5p] %C{2} - %m \n" />
</Console>
Replacing with \n is not a good solution.
You should make sure if there is another logging framework wrapping your logs to standard output.
This happening in case of application servers, where deployed applications use a logging framework to send formatted messages to standard output, and server uses its own active logging framework to wrap the message around with its own format, before sending it to standard output.
This causes double formatting & therefore double newlines. Check your runtime, if there is an active logger wrapping your messages.
I am working on logging with log4j 2.0.2. I am trying to use the ContextMapLookup into the fileName and filePattern attribute of a RollingFileAppender but I can't make it work.
Here is my (simplified) Map initialization in a REST facade :
#GET
public Response logSomething(#QueryParam("param") String param) {
ThreadContext.put("someName", "default");
LOGGER.info("Param from query: {}", param);
ThreadContext.clearMap();
return Response.ok().build();
}
And here is my (simplified to) configuration file :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n" />
</Console>
<RollingFile name="Rolling"
fileName="logs/${ctx:someName}-webapps-metrics.log"
filePattern="logs/archives/${ctx:someName}-webapps-metrics-%i.log" >
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %m%n"/>
<SizeBasedTriggeringPolicy size="5 KB"/>
</RollingFile>
</Appenders>
<Loggers>
<!-- My Logger using rollingFile -->
<Logger name="com.ipanematech.rest.MyRESTFacade" level="info" additivity="false">
<AppenderRef ref="Rolling" />
</Logger>
<Root level="warn">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
A file named "{ctx" is created in the directory. It seems that the expression to get the context does not work in these attributes.
I tried to use the context in the PatternLayout of my appender and it worked well.
In fileName and filePattern, I tried different syntaxes but not one worked:
${ctx:someName} (like in the example above)
$${ctx:someName}
%X{someName}
The RoutingAppender does what you want. See the log4j2 FAQ page for a detailed example.