Log4j 2 not logging to file - log4j2

I am trying to use log4j 2 for the first time but having trouble getting my code to log to a file.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.3</version>
</dependency>
My code is not logging to my File Appender or Console Appender:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout>
<Pattern pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</PatternLayout>
</Console>
<File name="File" fileName="resources/app-log.log">
<PatternLayout>
<Pattern pattern="%d{MM.dd.yyyy HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="x.y" level="ALL" additivity="true">
<AppenderRef ref="File"/>
<AppenderRef ref="Console"/>
</Logger>
</Loggers>
</Configuration>
Here is my Java code doping the logging:
package x.y;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Foo {
private static Logger logger = LogManager.getLogger(Foo.class.getName());
public static void main(String[] args) {
Foo foo = new Foo;
logger.info("Application starting");
}
}
Edit: My app is logging to the console but not using the pattern layout I specified. My app is a Maven app and I have put log4j2.xml in src/main/resources. I know my configuration xml is being read because when I put in something invalid I get an exception.

Figured it out. Changed to:
<PatternLayout pattern="%d{MM.dd.yyyy HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
Now it logging to my file.

Related

log4j2 DynamicThresholdFilter not picking up property value

Trying to set different printing levels for console and file.
Goal is: when debug=true, print debug level (console & file), else only print error level (console).
Change it programatically like this:
#Override
public void contextInitialized(ServletContextEvent sce) {
ThreadContext.put("debugMode", "true");
}
This is my log4j2 configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Properties>
<Property name="logPath">${sys:catalina.home}</Property>
<Property name="rollingFileName">vsTenant</Property>
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<filters>>
<DynamicThresholdFilter key="debugMode" defaultThreshold="ERROR" onMatch="ACCEPT" onMismatch="NEUTRAL">
<KeyValuePair key="true" value="DEBUG"/>
<KeyValuePair key="false" value="ERROR"/>
</DynamicThresholdFilter>
</filters>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level [vsTenant] %logger{36} - %msg\n%n" />
</Console>
<RollingFile name="rollingFile" fileName="${logPath}/logs/vsTenant.log" filePattern="${logPath}/logs/vsTenant_%d{dd-MM-yyyy}.log">
<filters>>
<DynamicThresholdFilter key="debugMode" onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="true" value="DEBUG"/>
</DynamicThresholdFilter>
</filters>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level [vsTenant] %logger{36} - %msg\n%n" />
<Policies>
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="ERROR" additivity="false">
<AppenderRef ref="console" />
<AppenderRef ref="rollingFile" />
</Root>
</Loggers>
</Configuration>
It is always printing ERROR level. Help is appreciated.
You were close, only a few small changes are needed to achieve what you want.
Change the first onMismatch from NEUTRAL to DENY
Add a second KeyValuePair to the second filter: <KeyValuePair key="false" value="OFF"/>
Change the Root log level from ERROR to TRACE
Here's the modified configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="logPath">${sys:catalina.home}</Property>
<Property name="rollingFileName">vsTenant</Property>
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<filters>
<DynamicThresholdFilter key="debugMode" defaultThreshold="ERROR" onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="true" value="DEBUG"/>
<KeyValuePair key="false" value="ERROR"/>
</DynamicThresholdFilter>
</filters>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level [vsTenant] %logger{36} - %msg\n%n" />
</Console>
<RollingFile name="rollingFile" fileName="${logPath}/logs/vsTenant.log" filePattern="${logPath}/logs/vsTenant_%d{dd-MM-yyyy}.log">
<filters>
<DynamicThresholdFilter key="debugMode" onMatch="ACCEPT" onMismatch="DENY">
<KeyValuePair key="true" value="DEBUG"/>
<KeyValuePair key="false" value="OFF"/>
</DynamicThresholdFilter>
</filters>
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level [vsTenant] %logger{36} - %msg\n%n" />
<Policies>
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="TRACE" additivity="false">
<AppenderRef ref="console" />
<AppenderRef ref="rollingFile" />
</Root>
</Loggers>
</Configuration>
Here is some java code to test it with:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
public class SomeClass {
private static final Logger log = LogManager.getLogger();
public static void main(String[] args){
ThreadContext.put("debugMode", "false");
log.info("Info should not show anywhere");
log.debug("This shouldn't show anywhere");
ThreadContext.put("debugMode", "true");
log.debug("This should show in the log and console");
log.info("This should also show in both");
ThreadContext.put("debugMode", "false");
log.info("This should not show anywhere");
log.error("This error should show only in console.");
}
}
Running the above will output the following to console:
21:16:40.716 [main] DEBUG [vsTenant] example.SomeClass - This should show in the log and console
21:16:40.718 [main] INFO [vsTenant] example.SomeClass - This should also show in both
21:16:40.718 [main] ERROR [vsTenant] example.SomeClass - This error should show only in console.
and output the following to the log file:
21:16:40.716 [main] DEBUG [vsTenant] example.SomeClass - This should show in the log and console
21:16:40.718 [main] INFO [vsTenant] example.SomeClass - This should also show in both

Log4j2 disable console on production

I'm developing a Web app and I'm using log4j2. In developing mode, I'm logging using RollingFile and Console appenders.
Everything is working properly, but I'd want to disable the Console appender when my project will be released and it will be in production mode.
Here's a slice of my log4j2.xml code:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="PropertiesConfig" packages="com.project.application">
<!-- PROPERTIES -->
<Properties>
<Property name="webName">Project</Property>
<Property name="logBaseDir">${sys:catalina.base}/logs/</Property>
<Property name="consolePattern">%highlight{[%-5level] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%c{1}] - %msg%n}</Property>
<Property name="rollingFilePattern">[%-5level] [%d{yyyy-MM-dd HH:mm:ss,SSS}] [%c{1}] - %msg%n</Property>
</Properties>
<!-- APPENDERS -->
<Appenders>
<!-- Console -->
<Console name="Console"
target="SYSTEM_OUT"
immediateFlush="true">
<PatternLayout>
<pattern>${consolePattern}</pattern>
</PatternLayout>
</Console>
<!-- RollingFile -->
<RollingFile name="RollingFile"
fileName="${sys:logBaseDir}${webName}/${webName}.log"
filePattern="${sys:logBaseDir}${webName}.%d{yyyy-MM-dd}.log"
immediateFlush="true">
<PatternLayout>
<pattern>${rollingFilePattern}</pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<!-- LOGGERS -->
<Loggers>
<Logger name="com.project.application" additivity="true" level="warn">
<AppenderRef ref="RollingFile" />
</Logger>
<Root level="info"> <!-- #TODO disable in production -->
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Thank you!
Use a filter, e.g. ThreadContextMapFilter:
<Console name="Console" target="SYSTEM_OUT" immediateFlush="true">
<ThreadContextMapFilter onMatch="DENY" onMismatch="NEUTRAL">
<KeyValuePair key="is-production" value="1"/><!-- skip on production -->
</ThreadContextMapFilter>
<PatternLayout>
<pattern>${consolePattern}</pattern>
</PatternLayout>
</Console>
The initialization of the ThreadContext entry can be perfomed in a ServletContextListener, e.g.:
#WebListener
public class Log4jThreadContextInitializer implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
String isProduction = isProduction() ? "1" : "0";
sce.getServletContext().log("Setting 'is-production' flag for Log4j to " + isProduction);
org.apache.logging.log4j.ThreadContext.put("is-production", isProduction);
}
private boolean isProduction() {
// TODO: production detection
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Spring-lookup made my life easier. My appender is like this:
<Appenders>
<Console name="console-local" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss:SSS} [%thread] %-5level %logger{2}:%L - %msg%n" />
</Console>
</Appenders>
I have added a property like this:
<Properties>
<Property name="console-appender">console-${spring:profiles.active}</Property>
</Properties>
And the logger is like this:
<Loggers>
<root level="info">
<appender-ref ref="${console-appender}"/>
</root>
</Loggers>
If my active profile is local, thus console-appender will be set to console-local, and the log will be shown in the console, as ref will find console-local.
Again, suppose, my active profile is prod, then console-appender will be set to console-prod, and the log will not be shown in the console, as ref will not find console-prod. Because Console's appender name is still console-local.
My log4j version is 2.14.1

log4j 2 - collor logs for intelij console

I try to config log4j to appends loggs in diffrent color per log type (INFO, ERROR, DEBUG etc.)
Here is my log4j2.xml:
<Configuration monitorInterval="60">
<Properties>
<Property name="log-path">applogs</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%highlight{%d{HH:mm:ss.SSS} %-5level %logger{36}.%M() [%L] - %msg%n}{FATAL=red, ERROR=red, WARN=yellow, INFO=green}
</pattern>
</PatternLayout>
</Console>
<someMoreAppenders>
</Appenders>
<Loggers>
<Logger name="RepositoriesController" level="info" additivity="false">
<AppenderRef ref="Console-Appender"/>
</Logger>
<Root level="error" additivity="false">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>
And in class RepositoriesController, i create logger in this way:
private static final Logger logger = LogManager.getLogger("RepositoriesController");
logger.info("Hello, World!");
My log4j.properties are empty. Output seems to be formatted used by my pattern but font color is still white:
Intelij console
i tried to add this properties:
spring.main.banner-mode=off
spring.output.ansi.enabled=ALWAYS
and modify pattern but without succesed, any advices?
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t]
%highlight{%level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green, DEBUG=blue} - %msg%n" />
</Console>
%highlight{%level} - using this you can highlight colors for different levels of logs.
This will generate output as:

log4j2 Logs not writing to file when running as jar

I have configured log4j2.xml within eclipse and all logs write correctly to a file.
When I export maven project as a jar and run from command promt the logs are displayed on the console instead of writing to a file.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="file_all" fileName="C:/log/logsALL.log" immediateFlush="true" append="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="ERROR">
<AppenderRef ref="file_all"/>
</Root>
<Logger name="com.api.main" level="INFO">
<AppenderRef ref="file_all"/>
</Logger>
</Loggers>
</Configuration>
When log4j starts up, it shows internal logging on the console (because status=trace in the configuration).
This internal log should show the location of the config file that is being used. Double-check that this is the correct location: I suspect that an old config file is being loaded that logs to the console...

log4j2 RollingFile Appender requires date pattern

I have defined a RollingFile Appender in log4j2
<RollingFile name="Locserver" append="true" fileName="locserver.log" filePattern="locserver-%i.log">
<PatternLayout>
<pattern>%d{ISO8601} [%t] %p %c %L - %m%n</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50 MB"></SizeBasedTriggeringPolicy>
<DefaultRolloverStrategy>10</DefaultRolloverStrategy>
</Policies>
</RollingFile>
However when I try to run this I get an error
IllegalStateException : Pattern does not contain a date at
org.apache.logging.log4j.core.appender.rolling.PatternProcessor.getNExtTime(PatternProcessor.java:91)
This goes away as soon as I put a date pattern in filePattern for example, locserver-%d{MM-dd-yyyy}-%i.log. But I dont want the date in the log names. Is a bug or something wrong with my config?
In RollingFile appender,TimeBasedTrigerringPolicy checks for datepattern in filepattern attribute of tag. Specifing datepattern is then mandatory when using TimeBasedTrigerringPolicy.
Place %d{...} containing a SimpleDate Pattern in filePattern, e.g.:
<Appenders>
<RollingFile name="RollingFile" fileName="logs/rpi_gpio_latest.log"
filePattern="logs/**%d{yyyy-MM-dd_HH}**_rpi_gpio_%i.log">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="4 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="max"/>
</RollingFile>
</Appenders>
Thanks Joe.
I finally figured it out.
I had an empty TimeBasedTriggeringPolicy tag within my Policies list which was forcing the date check in the filePattern. Once I removed it, it started working fine.
For me, that works like described here (using log4j 2.0-beta9 & Java 1.7).
My log4j.xml (size-policy set to 1kB just for testing):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<RollingFile name="Logfile"
fileName="Log/App.log"
filePattern="Log/App-%i.log">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1 KB"/>
</Policies>
<DefaultRolloverStrategy max="4"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="Logfile"/>
</Root>
</Loggers>
</Configuration>
And it also works when using your config fragment (I'd just corrected the DefaultRolloverStrategy-setting):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<RollingFile name="Locserver"
append="true"
fileName="locserver.log"
filePattern="locserver-%i.log">
<PatternLayout>
<pattern>%d{ISO8601} [%t] %p %c %L - %m%n</pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="50 MB"></SizeBasedTriggeringPolicy>
</Policies>
<DefaultRolloverStrategy max="4"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="eeo.tts" level="debug"/>
<Root level="info">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="Locserver"/>
</Root>
</Loggers>
</Configuration>
Which Version of log4j2 are you using?

Resources