Can't get a RollingFile working with log4j2 - spring

I'm trying to configure log4j2 to write a rolling log file to disk, but I can't get it to work. No log file appears at the given path and the Glassfish server.log doesn't show any Spring logging at all. I've read a lot of similar questions on SO, but none of the proposed solutions have worked in this case. Can anyone help me? I'm using Spring 3.0 on a Glassfish 3.1 application server.
From my pom.xml:
<properties>
<junit.version>4.11</junit.version>
<tiles.version>3.0.3</tiles.version>
<slf4j.version>1.7.5</slf4j.version>
<log4j.version>2.0-beta9</log4j.version>
</properties>
<dependencies>
<dependency>
<artifactId>jcl-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
And here's my log4j.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="fileName" value="C:/temp/rolling-file.log"/>
<Property name="fileNamePattern" value="C:/temp/rolling-file-$d{dd-MM-yyyy}-%i.log"/>
<Property name="logPattern" value="%d{dd-MM-yyyy HH:mm:ss,SSS} [%t] %-5p %c - %m%n"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${logPattern}"/>
</Console>
<RollingFile name="RollingFile" fileName="${fileName}" filePattern="${fileNamePattern}">
<PatternLayout pattern="${logPattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="20MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="my.root.package" level="info" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>

Besides the excellent point made by M. Deinum, it turns out my log4j2.xml needed to be changed to the following:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Properties>
<Property name="fileName">C:/temp/rolling-file.log</Property>
<Property name="fileNamePattern">C:/temp/rolling-file-%d{dd-MM-yyyy}-%i.log</Property>
<Property name="logPattern">%d{dd-MM-yyyy HH:mm:ss,SSS} [%t] %-5p %c - %m%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${logPattern}"/>
</Console>
<RollingFile name="MyRollingFile" fileName="${fileName}" filePattern="${fileNamePattern}">
<PatternLayout pattern="${logPattern}"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="20MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="my.root.package" level="info" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="MyRollingFile"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Performed changes:
The value attributes of the Property elements were not parsed correctly. Specifying them as body of the Property element seems to solve this.
There was a mistake in the value of the fileNamePattern property. I used $d to denote the date, but it should be %d.
Apparently log4j2 doesn't like a RollingFile element with the name "RollingFile". After I changed it, logging started working.

You might need to include log4j-api to the pom dependencies (http://logging.apache.org/log4j/2.x/faq.html#which_jars ).
About the properties: if the problem goes away by putting the values in the config directly:
<RollingFile name="RollingFile" fileName="C:/temp/rolling-file.log"
filePattern="C:/temp/rolling-file-$d{dd-MM-yyyy}-%i.log">
<PatternLayout pattern="%d{dd-MM-yyyy HH:mm:ss,SSS} [%t] %-5p %c - %m%n"/>
then you may have found a bug. In that case, could your raise this issue in the log4j2 Jira issue tracker?

Related

Spring 5 Framework Logging with slf4j/log4j2

I have a application that I've put together to become familiar with Spring Framework 5, using Maven and Java 8. Once executed, it extracts some information from a PostgreSQL database table and logs it to the console (via slf4j/log4j2).
The actual application logic is working fine - I'm seeing the info retrieved from the database on the console as expected. However, I'm not seeing any of the expected Spring/DBCP2 logging. After the application finishes executing, there are only 15 lines printed on the console - all lines that I specifically logged via logger.debug("...").
The dependencies section of my pom.xml looks like this:
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.1</version>
</dependency>
</dependencies>
My log4j2.xml file looks like this...
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE Configuration>
<Configuration status="INFO" strict="true">
<Properties>
<Property name="CONSOLE_PATTERN">%-5level %c{1} %M - %m%n</Property>
</Properties>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="${CONSOLE_PATTERN}" />
</Console>
</Appenders>
<Loggers>
<Logger name="local.spring5" level="DEBUG" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<Logger name="org.apache.commons.dbcp2" level="DEBUG" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<Logger name="org.springframework" level="INFO" additivity="false">
<AppenderRef ref="STDOUT" />
</Logger>
<Root level="INFO">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
Note that if I change the org.springframework logging level to DEBUG or TRACE, I see spring logging appropriate for those levels. Setting the log level to INFO, WARN or ERROR results in no logging from spring at all. I'm sceptical, to say the least, that spring doesn't log anything at those levels.
Does anyone have any ideas on how to get the spring framework logging to appear?

Logback file (testlog.log) is not created

I was using slf4j for logging purposes and everything worked well (file was created on a path I specified and all my logs were there), however, due to my requirements I had to make logger use the JSON format. I decided to use Logback for that purpose but my log file is not created (even tho in the console I see logs written in the JSON format - but for some reason file is not created so I can see those logs only in the console)
Here is my setup:
application.properties
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
logging.file.path=./install/my-project/logs
logging.file.name=${logging.file.path}/testlog.log
POM.xml
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<version>${logback.contrib.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
<version>${logback.contrib.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
logback.xml
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
<timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="stdout"/>
</root>
</configuration>
So with this setup, I see my logs in the console formatted as JSON, however,log file is not created. If I remove these dependencies, and delete logback.xml file and then I restart my application, then my logging works perfectly (log file is created on a specified location) however it's not a JSON format.
I've tried a lot of different options but I cannot figure out why I'm having this strange problem.
Hope you guys can help me
As "Simon Martinelli" pointed out, I had to add file appender as well so my logback.xml file now looks like this:
<configuration>
<property name="HOME_LOG" value="./install/my-project/logs"/>
<appender name="FILE-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${HOME_LOG}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/archived/app.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<!-- each archived file, size max 10MB -->
<maxFileSize>10MB</maxFileSize>
<!-- total size of all archive files, if total size > 20GB, it will delete old archived file -->
<totalSizeCap>20GB</totalSizeCap>
<!-- 60 days to keep -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
<timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
</encoder>
</appender>
<logger name="com.mkyong" level="debug" additivity="false">
<appender-ref ref="FILE-ROLLING"/>
</logger>
<root level="error">
<appender-ref ref="FILE-ROLLING"/>
</root>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
<timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="stdout"/>
</root>
</configuration>
Thanks!

Log4j2.xml with springboot is not generating log file

I am upgrading log4j1 to logj42 in one of the springBoot porject (maven, Java 1.8) with log4j-core,log4j-api as maven dependency.
Log file mentioned in log4j2.xml as Rolling file appender is not creating log file, I am able to see the logs in console but no log file. Please reply if anyone has faced same issue.
By default spring boot contains an integration with logback logging library.
So you'll have to exclude the "default" and add a special starter that will handle the integration:
In the pom.xml make sure you have the following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Optional: If you want to use an asynchronous logging, add also the following dependency:
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.6</version> <!-- check the actual version it might be different -->
</dependency>
After this step you can start configuring the log4j2. There are plenty of sample configurations and tutorials about this, examples: here and here.
I won't dive into possible configurations of log4j2, but from the spring boot's standpoint I'll mention that you should place the log4j2's configurations into src/main/resources/log4j2.xml
You can try with the below log4j2.xml. This is working for me.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">
<Properties>
<Property name="basePath">/home/user/myapp/logs</Property>
</Properties>
<Appenders>
<!-- File Appender -->
<File name="FILE" fileName="${basePath}/my-app.log" append="true">
<PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n" />
</File>
<!-- Console Appender -->
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.abc.xyz" level="debug" />
<Root level="info">
<AppenderRef ref="STDOUT" />
<AppenderRef ref="FILE" />
</Root>
</Loggers>
</Configuration>
Change the log file name and path accordingly.
Also change the package for the logger. <Logger name="com.abc.xyz" level="debug" />

log4j2 not writing to log file specified in xml file

I'm running into an issue with log4j2 on my springboot api. We're using ubuntu on an EC2 instance and can't get the log4j2.xml to create a log file where we want it to, nor write to a log file that we manually create in that location.
We've checked the xml file multiple times, and as far as we can tell the issue isn't with the file itself. We've also messed around with permissions for writability of the log file and we don't think that's the problem either; we're both super new to linux though so we could be wrong.
<Configuration>
<Properties>
<Properties>
<Property name="filename">log/api.log</Property>
<Property name="LOG_PATTERN">%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ} %p %m%n</Property>
</Properties>
</Properties>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout
pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
</Console>
<File name="MyFile" fileName="log/api.log">
<PatternLayout
pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
</File>
<RollingFile name="appLog"
fileName="api.log"
filePattern="application-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${LOG_PATTERN}" />
<Policies>
<SizeBasedTriggeringPolicy size="19500KB" />
</Policies>
<DefaultRolloverStrategy max="1" />
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.hibernate.SQL" level="debug" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="MyFile"/>
<AppenderRef ref="appLog"/>
</Logger>
<Logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="MyFile"/>
<AppenderRef ref="appLog"/>
</Logger>
<Root level="info">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="MyFile"/>
<AppenderRef ref="appLog"/>
</Root>
</Loggers>
</Configuration>
Any thoughts?
You have two files specified; log/api.log and api.log. Log4j will create these in whatever the current working directory is when the application is started. Since you haven't stated where the files are actually being created not much more can be said.

log4j2 does not log in webapplication deployed on tomcat

I am upgrading the version of log4j for a web application running on Tomcat 8. I am upgrading from version 1.2.12 to the latest 2.11.1.
The application is using Maven. So I added the following dependencies to my application pom.xml (version is managed in parent pom):
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
I removed the old configuration file log4j.properties and replaced it by a new log4j2.xml file in the folder src/main/resources (find below my log4j2 file content).
When I am running directly a main function, the logs are correctly written in console and in a file. However when I deploy the application on Tomcat, and run it, no log is written.
I checked my application WAR, and both libraries are present in WEB-INF/lib folder.
I also tested by adding exclusions to log4j-1** to external libraries that have dependency on it, but nothing changed...
Did someone already had the same issue, and how did you correct it?
Regards,
Matthieu
PS: content of my log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status=WARN strict="true">
<Properties>
<Property name="pattern">%d [%t] (%F:%L) %x %-5p [%c{1}] %m%n</Property>
<Property name="filePath">C:/temp/logs/my_app/my_app.log</Property>
</Properties>
<Appenders>
<Appender type="Console" name="STDOUT">
<Layout type="PatternLayout" pattern="${pattern}"/>
</Appender>
<Appender type="RollingFile" name="FILE" fileName="${filePath}" filePattern="${filePath}.%i">
<Layout type="PatternLayout" pattern="${pattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="500KB"/>
</Policies>
<DefaultRolloverStrategy max="1"/>
</Appender>
</Appenders>
<Loggers>
<Logger name="my.package.debug" level="DEBUG" additivity="false">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="FILE"/>
</Logger>
<Root level="WARN">
<AppenderRef ref="STDOUT"/>
<AppenderRef ref="FILE"/>
</Root>
</Loggers>
</Configuration>
I finally found my issue, it was due to another library (infinispan-embeded) which was redefining Log4j classes, such as LogManager. I was loading thoses classes instead of those in log4j libraries, and they was in older version than what I wanted.
I just replaced the library, and logs are correctly written in file.

Resources