Logging using log4j2 - maven

I'm trying to change from log4j1 to log4j2. What I did:
deleted old configuration file log4j.xml
created new config file log4j2.xml
created jboss-deployment-structure.xml
edited pom
Environment:
Wildfly 10
1 EAR
4 WAR
The web.xml isn't being used in the file. The previous log4j config log was in the EAR (only)
Log4j2 config file
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<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="all.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="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
Jboss deployment structure
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<!--Use log4j.xml file instaead of using the loggin subsystem configuration -->
<exclusions>
<module name="org.apache.log4j" />
</exclusions>
</deployment>
</jboss-deployment-structure>
new maven dependencies
<!-- Apache Log4j API -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<!-- Apache Log4j SLF4J Binding -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.8.2</version>
</dependency>
<!-- Apache Log4j Core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
Has I said earlier I was using log4j1 with SLF4j has facade. These are the changes I've made (I'm trying to start with a simple configuration file I've found online). The file is not even created, but the console log is working just fine.
Thanks,

I got it to work with a webapp in JBoss 7.1.1 using the below config.
/src/main/resources/log4j2.xml
... above unchanged ...
<File name="MyFile" fileName="/Users/tima/Desktop/all.log" immediateFlush="true" append="true">
... below unchanged ...
WEB-INF/jboss-deployment-structure.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<exclusions>
<module name="org.apache.log4j" />
</exclusions>
</deployment>
</jboss-deployment-structure>
The pom file is the same as yours.
Test controller
#Controller
#RequestMapping("/test1")
public class HelloWorldController {
private static final Logger logger = LogManager.getLogger(HelloWorldController.class);
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Map<String, Object>> printHello() {
logger.info("entered printHello()");
System.out.println("entered printHello() 2");
Map<String, Object> resultMap = new HashMap<String, Object>();
return new ResponseEntity<>(resultMap, HttpStatus.OK);
}
}
Results
$: cat ~/Desktop/all.log
2017-05-11 15:13:35.918 [http--0.0.0.0-8080-2] INFO com.tima.controller.HelloWorldController - entered printHello()
Also in the server.log I can see the following:
15:13:35,937 INFO [stdout] (http--0.0.0.0-8080-2) entered printHello() 2
EDIT
If you want to use the org.slf4j.Logger logger, you have to add the lines below to the jboss-deployment-structure.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<deployment>
<exclusions>
<module name="org.slf4j" />
<module name="org.slf4j.impl" />
</exclusions>
</deployment>
</jboss-deployment-structure>
EDIT 2
If you are using an EAR file, you can set up logging by using a common JAR that is shared across other modules / WARs in the EAR file.
In the common JAR have:
The log4j-api, log4j-core, log4j-slf4j-impl as dependencies in the pom.xml.
The log4j2.xml under src/main/resources
Have the common jar as a dependency in the WAR files. And you can remove the jboss-deployment-structure.xml file from all WAR files.
The jboss-deployment-structure.xml file will now be located in the EAR file under src/main/application/META-INF/, and contain:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
<sub-deployment name="war-1.war">
<exclusions>
<module name="org.slf4j" />
<module name="org.slf4j.impl" />
</exclusions>
</sub-deployment>
<sub-deployment name="war-2.war">
<exclusions>
<module name="org.slf4j" />
<module name="org.slf4j.impl" />
</exclusions>
</sub-deployment>
...other wars here...
</jboss-deployment-structure>
The above configuration will print from all WAR files to the same file. But you can configure the log4j2.xml file to print to different files based on the package name. That approach is explained in this question

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">C:\\logs</Property>
</Properties>
<Appenders>
<RollingFile name="fileLogger" fileName="${basePath}/app-info.log" filePattern="${basePath}/app-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" />
</Policies>
</RollingFile>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.howtodoinjava" level="debug" additivity="true">
<appender-ref ref="fileLogger" level="debug" />
</Logger>
<Root level="debug" additivity="false">
<appender-ref ref="console" />
</Root>
</Loggers>
for morw you can follow this link : -
http://howtodoinjava.com/log4j2/log4j-2-xml-configuration-example/

You'll probably fair better to exclude the logging subsystem in your jboss-deployment-structure.xml. I would have done this as a comment, but pasting the xml wouldn't have been pretty.
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="logging" />
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>

Related

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" />

Spring output console dissapeared after removing logback dependency

I am trying to use log4j2 as logger, for that i have included
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
and used
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
in every dependency that used logback due to conflict, however after doing this, the spring upon running prints only its Logo and nothing.
DO i need to configure somehow spring for log4j2 or how to solve this?
Yes offcourse. You need to create log4j2.xml in src/main/resources path.
In that Xml file you need to configure your application logging level in ConsoleAppender.
Please add this xml configuration in log4j2.xml.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="ConsoleAppender"></AppenderRef>
</Root>
</Loggers>
</Configuration>

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.

Tomcat logs are being written to syslog instead to the application log in Spring Boot and Log4j

It's a Spring Boot application with Log4j for logging.
All logs from org.apache.catalina.* are being sent to syslog, and it includes also uncaught exceptions.
Our app uses Log4j (v1) since it uses legacy code dependencies that use Log4j.
Spring Boot version is 1.5.2.RELEASE.
I believe that with correct set-up, also tomcat logs will be written to the same file that is configured in the log4j.xml, but i couldn't find any answer to that problem.
pom.xml (relevant parts):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Logging -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
log4j.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} [%t] %5p %c{1} - %m%n" />
</layout>
</appender>
<!-- File appender -->
<appender name="logFileAppender" class="org.apache.log4j.FileAppender">
<param name="File" value="/tmp/myappname.log"/>
<param name="Append" value="true" />
<param name="BufferedIO" value="false" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ISO8601} [%t] %5p %c{1} - %m%n" />
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="consoleAppender" />
<appender-ref ref="logFileAppender" />
</root>
</log4j:configuration>
Could you try excluding it in the actuator artifact?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Based on your comment:
If I understood correctly, the application is logging fine, it's the servlet container the logging to syslog when exceptions bubble up, isn't?
Could you also try adding:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-log4j</artifactId>
</dependency>
and / or passing where log4j config file is located:
-Dlog4j.configuration=<path to file>
If these don't work, the only thing I could think of is that you are using Spring Boot 1.5.x doesn't get along with Log4j and likely requires to uplift it to Log4j2

Can't get a RollingFile working with log4j2

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?

Resources