Why Log4j2 doesn't write logs to a file? - java

This is my configuration log4j2.xml with path to file - src/com/tarasiuk/task_01/log/dataLogger.log:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="FORMAT_MESSAGE">
%d{YYYY-MM-dd HH:mm:ss} [%t] Level:%-7p Class:%c{1}:%-5L - %msg%n
</Property>
<Property name="LOG_FILE">
src/com/tarasiuk/task_01/log/dataLogger.log
</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${FORMAT_MESSAGE}" />
</Console>
<File name="File" fileName="${LOG_FILE}" append="false">
<PatternLayout pattern="${FORMAT_MESSAGE}" />
</File>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<AppenderRef ref="File" />
</Logger>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Structure of my project:
What I do:
change path to log file from src/com/tarasiuk/task_01/log/dataLogger.log to com/tarasiuk/task_01/log/dataLogger.log - no result.
change level in <Logger> from debug to info - no result.
Logs are output to the console - that ok. But why Log4j2 doesn't write logs to a file?

Try with below appender.
May be in your case it is not able to get path from property, so i had provided only name.
So automatically it will create file on same path as your application is.
<Appenders>
<File name="dataLogger" fileName="dataLogger.log" append="false">
<PatternLayout pattern="%level - %m%n"/>
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%level - %m%n"/>
</Console>
</Appenders>
This will help you.

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 custom Filter xml to property file

Created the custom filter by extending AbstractFilter.
Created log4j2.xml as per below code
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30"
packages="com.smp.marker">
<Properties>
<Property name="DEFAULT_LOG_PATTERN">%d %-5p %m%n [:%L]</Property>
</Properties>
<Appenders>
<Console name="CLOG" target="SYSTEM_OUT">
<PatternLayout alwaysWriteExceptions="false" pattern="%d %-5p
[%c{5}.%M():%L] %m%n" />
<Filters>
<SmpClogAppenderFilter level="ALL" onMatch="ACCEPT"
onMismatch="DENY"/>
</Filters>
</Console>
<Console name="DEFAULT" target="SYSTEM_OUT">
<PatternLayout alwaysWriteExceptions="false"
pattern="${DEFAULT_LOG_PATTERN}" />
<Filters>
<SmpClogAppenderFilter level="ALL" onMatch="DENY"
onMismatch="ACCEPT"/>
</Filters>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="CLOG" />
<AppenderRef ref="DEFAULT" />
</Root>
</Loggers>
</Configuration>
This is working as expetced.
But in our project we need log4j2.properties.
Unable to create the property file with custom filter.Mainly need propety value for filter section.
<Filters>
<SmpClogAppenderFilter level="ALL" onMatch="ACCEPT"
onMismatch="DENY"/>
Could some one please help me to resolve this issue.

how to overwrite log file name in specified in log4j2.xml with new one?

I created separate simple log class: log.java)
e.g.,
import org.apache.log4j.LogManager;
public class Logs {
private static final org.apache.log4j.Logger logger= LogManager.getLogger(Logs.class);
public static org.apache.log4j.Logger Log() {
return logger;
}
}
and using following log4j2.xml file
<Configuration status="INFO">
<Properties>
<Property name="log-path">logs</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="MyFile" fileName="${log-path}/Log${date:yyyy-MM-dd-HH-mm-ss}.log" immediateFlush="false" append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
<AppenderRef ref="MyFile" />
</Root>
</Loggers>
</Configuration>
Question: I want to pass log file name say testbest.log to my log class so that when log is created the log file name would be testbest.log instead of Log${date:yyyy-MM-dd-HH-mm-ss}.log
How can I achieve this?
log4j.xml
<Configuration status="INFO">
<Properties>
<Property name="log-path">logs</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="MyFile" fileName="${log-path}/${sys:log-file-name}" immediateFlush="false" append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
<AppenderRef ref="MyFile" />
</Root>
</Loggers>
</Configuration>
You can specify file name as VM argument when starting
java -Dlog-file-name="testbest.log"
Or you can define it programmatically as system property
System.setProperty("log-file-name", "testbest.log");

log4j2 - Automatic reload and composite configuration

The automatic reload was working up until I added a second file to the log4j.configurationFile property. I now get this error when updating the log4j2.xml file, or rather I get the same error message twice...
2017-10-02 12:06:44,461 Log4j2-TF-2-ConfiguratonFileWatcher-2 ERROR No logging configuration
2017-10-02 12:06:44,462 Log4j2-TF-2-ConfiguratonFileWatcher-2 ERROR No logging configuration
Here's the problematic property...
-Dlog4j.configurationFile=log4j2.xml,c:\tmp\override-log4j2.xml
Note, this only affects reload. Initially, the composite configuration works fine.
This is a maven project, ran in eclipse using jetty:run and log4j2 2.9.0.
Is this a bug? Is there a workaround?
Here's the log4j2.xml...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration monitorInterval="5">
<appenders>
<console name="console" target="SYSTEM_OUT">
<patternLayout pattern="%d %5p [%t] [%X{users}] (%F:%L) - %m%n" />
</console>
<rollingFile name="rollingFile" fileName="myApp.log" filePattern="myApp.log">
<patternLayout pattern="%d %5p [%t] [%X{users}] (%F:%L) - %m%n" />
<policies>
<SizeBasedTriggeringPolicy size="10mb" />
</policies>
<defaultRolloverStrategy max="10" />
</rollingFile>
</appenders>
<loggers>
<root level="warn">
<appenderRef ref="console" />
<appenderRef ref="rollingFile" />
</root>
<logger name="com.mycompany" level="info" />
</loggers>
</configuration>
Here's override-log4j2.xml...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<loggers>
<root level="warn" />
</loggers>
</configuration>
Thanks for the update #gaurav.
Apparently, (I've not tested) the ticket was resolved in 2.10.0.

How to define a global PatternLayout for log4j2?

Is it possible to define a (named) PatternLayout within a log4j2.xml configuration file?
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="ERROR">
<appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p %C{2} (%F:%L) - %m%n" />
</Console>
<File name="DEBUG_FILE" fileName="debug.txt">
<PatternLayout pattern="%d %-5p %C{2} (%F:%L) - %m%n" />
</File>
</appenders>
<loggers>
<root level="trace">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
</root>
</loggers>
</configuration>
In this example the PatternLayout is repeated. Could I define it somehow globally with a name, and then just use the name reference to set the pattern for each appender?
According to the official documentation, you can define a "property" and reuse its value.
In this case, I am defining the appenderPatternLayout property.
Here the full code (tested with Log4J 2.3) :
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="appenderPatternLayout">%d %-5p %C{2} (%F:%L) - %m%n</Property>
</Properties>
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="${appenderPatternLayout}" />
</Console>
<File name="DEBUG_FILE" fileName="debug.txt">
<PatternLayout pattern="${appenderPatternLayout}" />
</File>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="CONSOLE" />
<AppenderRef ref="DEBUG_FILE" />
</Root>
</Loggers>
</Configuration>
Found it:
define:
<Properties>
<property name="path">c:/logs/</property>
</Properties>
use:
<RollingFile fileName="${path}mylog.log"

Categories