Spring Boot SLF4j Logback - spring

I have a small SpringBoot MvC app. with those dependencies:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot-starter-test.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
I put a logback-test.xml file in the /src/test/resources/ and when I run the test it works fine
<configuration debug="true" scan="true" scanPeriod="150 seconds">
<property name="LOG_DIR" value="logs-test" />
<appender name="FILE_INFO"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/app_info.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} -
%msg%n
</Pattern>
....
</configuration>
but when I add to the file /src/test/resources/application.properties:
# logging level
logging.level.root=error
logging.level.org.springframework=ERROR
logging.level.com.plats.bruts=ERROR
but it seems not to work, because I see the DEBUG level on the console when running the test:
10:16:08.039 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class eu.europa.ec.oib.kw.frontoffice.repository.autorisation.AutorisationPersonneRepositoryTest]
10:16:08.047 [main] DEBUG org.springframework.test.context.BootstrapUtils

Make sure to use #SpringBootTest annotation when testing spring boot apps for spring boot to load default logback logging.
For the most part you can configure without needing custom logback xml file and can be managed using application.properties.
For non spring boot test cases you've to provide your own logback xml file.
For custom configuration you should build your file based on base.xml default provided in the spring boot library ( has both file and console appender defined) so you can import the defaults and add specific configuration based on your need.
This way you still manage the default configuration attributes from application properties for spring boot tests. Also rename the file to end with spring extension so spring boot can take control of logging initialization.
Something like
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
!-- custom configuration goes here --!
</configuration>

Related

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>

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

Deploying spring-boot application to WildFly 8 causes container logs to be redirected

I'm trying to deploy a spring-boot application using logback to an existing WildFly 8 container, but as soon as the application has deployed all the container logs stop being written to server.log and end up being captured by the application logs.
The symptoms are similar to those described in WildFly not logging after deploying app with Logback. If I deploy an application which manually contains logback/slf4j dependencies, the application behaves as I'd expect (application logs go to application logfile, container logs go to server.log), so I'm assuming it's something to do with spring-boot? Can I configure this such that the container logging continues to be handled by Wildfly?
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.logging</groupId>
<artifactId>logger-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="path_base" value="d:/test-logger/" />
<property name="pattern"
value="%date{ISO8601} %level %class{30} %thread %msg %mdc %ex{full} %n" />
<!-- Simple File Appender -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${path_base}test-logger.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${path_base}/archive/%d{yyyy-MM,aux}/test-logger.log.%d.%i.gz
</fileNamePattern>
<maxHistory>90</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%date{ISO8601} %level %class{30} %thread %msg %mdc %ex{full} %n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="file" />
</root>
</configuration>
jboss-deployment.xml
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="logging" />
</exclude-subsystems>
</deployment>
</jboss-deployment-structure>
Spring boot initializer
package com.test;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
#SpringBootApplication
public class BootApp extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder builder) {
return builder.sources(BootApp.class);
}
}
I had similar problem when I deployed spring-boot application to websphere. After application prints banner all the log messages from websphere are logged into application log.
The problem occurred because spring-boot adds as one of its dependencies jul-to-slf4j.jar . This jar implements classes java.util.logging.* and websphere is also using java.util.logging hence by excluding jul-to-slf4j.jar from spring boot I was able to direct all websphere messages to container log and the application logs were written to application log.
I had a similar problem:
Running Spring-boot 1.5.8 on Wildfly 9.0.2Final
I had to exclude the following before the logging was handled by the container:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
spring-boot-starter-data-jpa has spring-boot-starter-logging which had the dependencies i excluded.

Log4j.properties in Spring boot

How to load Custom Log4j.properties file in Spring boot
My code in application.properties is here
logging.file=E:/Apps_Tek/apps-webservices-log/apps-webservices.log
logging.level.*=INFO
logging.config=log4j.properties
My code in log4j.properties is here
log4j.rootLogger=INFO,ConsoleAppender,FileAppender
log4j.appender.ConsoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.ConsoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.ConsoleAppender.layout.ConversionPattern=%-7p %d [%t] %c [%X{userName}] [%X{accessToken}] - %m%n
log4j.appender.FileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileAppender.File=E:/Apps_Tek/apps-webservices-log/apps-webservices.log
log4j.appender.FileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileAppender.layout.ConversionPattern=%-7p %d [%t] %c [%X{userName}] [%X{accessToken}] - %m%n
But i am not getting any expected output i.e., spring boot is not loading log4j.properties file. Spring boot is having its own default logging.
log4j.properties file is in src/main/resources
My question is how to map log4j.properties file with logging.config property in application.properties if it is in src/main/resources.
Please suggest all the required changes.
Thanks for any help in advance.
If you want spring boot to use log4j instead of its own default logging (logback) then you have to exclude default logging and include the log4j dependency for spring boot in your pom.xml:
<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-log4j</artifactId>
</dependency>
that way is going to look for your log4j.properties file located in src/main/resources.
Also if you wish to use properties defined in you application.properties inside the log4j.properties file
for example, you want to have log.file.path defined in your application.properties and use it on log4j.properties
Then you have to define filtering inside your pom.xml:
<filters>
<filter>src/main/resources/application.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>log4j.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
That way you can have:
log4j.appender.file.File=${log.file.path}/${project.artifactId}.log
in your log4j.properties file
To exclude default logging and include the log4j dependency for spring boot in your pom.xml:
<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>
if you wish to use log4j properties defined in you application.properties inside the log4j.properties file need to add below property in application.properties file.
logging.config = src/main/resources/log4j2.properties
Then spring boot will read the properties from log4j2.properties file
In log4j2.properties file add the below properties
name=PropertiesConfig
appenders = console, file
appender.console.type = Console
appender.console.name = ConsoleAppender
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n
appender.file.type = File
appender.file.name = FileAppender
appender.file.fileName=/home/ubuntu/application.log
appender.file.layout.type=PatternLayout
appender.file.layout.pattern= %d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n
loggers=file
logger.file.name=com.project
logger.file.level = debug
logger.file.appenderRefs = file
logger.file.appenderRef.file.ref = FileAppender
rootLogger.level = debug
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = ConsoleAppender
Is there any other work around which doesnot require to specify
'logging.config = src/main/resources/log4j2.properties' inside application.properties file..?
Note : Spring boot version i am using is 2.1.3.RELEASE
Reference : https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
My guess is that your pom.xml file is not set up to include the correct log4j dependency. If you do that it should automatically work. See their example at spring-boot-sample-actuator-log4j. Their project includes the artifact spring-boot-starter-log4j which should then allow your log4j.properties to be picked up from the current src/main/resources location and you should no longer need the logging.* entries in your properties. It may also be possible that you need to exclude their spring-boot-starter-logging as I see they are doing that as well. If this does not seem to resolve it please post your POM file in a location I can see it. Please let me know if this works for you.
In case someone faces the same problem, I did not have the spring-boot-starter dependency so I had to add the to the spring-boot-starter-web dependency, this is how it looked:
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Excluding logback dependencies to use l4j2 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Then you add the Log4j2 Dependency:
<!-- Add Log4j2 Dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Your log4j2.properties file will be used for logging configurations from now on.

Disabling Spring log, to have readable logs

How can I disable Spring logs to have log outputs that I can easily read or someone else can read.
An answer to a similar question at, how to disable spring bean loading log suggested to comment out all lines having org.springframework substring in log4j.properties file. In my case there no such lines.
Here is log4j.properties
# Define the root logger with appender file
log4j.rootLogger = DEBUG, stdout
# Define the file appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# Set the name of the logs destination
log4j.appender.stdout.target=System.out
# Set the immediate flush to true (default)
log4j.appender.stdout.ImmediateFlush=true
# Set the threshold to debug mode
log4j.appender.stdout.Threshold=debug
# Set the append to false, overwrite
log4j.appender.stdout.Append=false
# Define the layout for appender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.conversionPattern=%d{yyyy-MM-dd}:%m%n
Your default logging, for everything that isn't explictily specified, is DEBUG. So everything is logged at that level (judging from your configuration), basically you are flooding your logs. You should not remove loggers for org.springframework you should add them and set another level for them.
log4j.logger.org.springframework=INFO
or whatever log level level you like.
Before you do, you should have get some knowledge of :
1.How to add maven dependency
2.Where to put log4j configuration file
OK, return to the question.The top answer is not working for spring 4.x, if you are using spring4.x try following 3 steps:
remove common-logging from spring-core
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.4.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Without this step, no matter what you put in log4j configuration file is not working, cause spring is using common-logging my boy!
PS:Within lots of spring modules, spring-core is the the only module that explicitly depends on commons-logging.
Add SLF4J and log4j
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.8</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
configure log4j.properties(You can also use xml file)
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t
%c{2}:%L - %m%n
log4j.category.org.springframework.beans.factory=INFO
Now, the annoying spring debug log is going away.Enjoy coding!
The answer is from spring.io doc,for origin click here
All the answers gave examples with configuration in log4j.properties, which is what was asked. I had the same problem but I was using configuration in log4j2.xml and answers here lead me to a solution.
In case someone is on the same boat as me, here is what I did: I added a node Logger with name org.springframework and level WARN as shown in the following sample:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="WARN"/>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
I'm using Spring Boot and the exclusion I'm making is logback-classic as shown in the following snippet:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
You can specify the required package name as can be seen in the following example:
log4j.logger.com.foo=WARN
Now you can see only WARN, ERROR and FATAL logs in console.
I was also facing this same issue. Springframework logging was not getting removed even after log4j configuration. Then I found that its logging depends on commons-logging.
You have to disable commons-logging from the dependency in pom.xml file of the web app.
Even after removing commons-logging from pom.xml please check the dependency hierarchy available in Eclipse or STS IDE. This will help in knowing if somehow its getting added because of some other dependency management which we may not be knowing.
After removing dependency just add log4j.logger.org.springframework=ERROR to your log4j configuration. This will help.

Resources