Externalize logback.xml in Spring MVC - maven

I use SL4J for logging in my Java Spring MVC Web Application. I have the logback.xml file under /src/main/resources. In my pom.xml file, I have the following related to logging:
<properties>
<org.slf4j-version>1.6.4</org.slf4j-version>
<logback.version>1.0.1</logback.version>
</properties>
And the following dependencies:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
Now logging is working fine for me. But now I am trying to move the logback.xml file outside the war file so that I do not have to change the war file to change the logging level. I was trying to move the file to ${catalina.base}/conf/. I was unable to find a way to specify the path of the file which would be ${catalina.base}/conf/logback.xml. I have found a couple of similar questions, but I couldint find a solution that I could use:
Externalized the location of logback.xml in Spring Boot using application.properties and
logback externalization. Is there any way I can move the file under the conf folder under tomcat and specify its path so that I can keep this logback.xml ouside the war file

It is not good idea to put logging properties in tomcat config folder. Better to put it inside application folder/war.
But there is a way to locate logback.xml from external directory by setting a property in your spring application properties file.
For example in application.properties add
logging.config=file:/home/user/tomcat/conf/logback.xml

Related

TinyLog v2 with multimodule maven project spring-boot

Hi I have a multimodule springboot based project and I would like to keep logging separate for each module.
I am using tiny log 2, but the issue I am facing is that, when there is a stack trace thrown, it is not getting captured in my rolling log file.
Here is the tinyLog configuration:
exception = strip: jdk.internal
writer = file
writer.format = {date} [{class}] {level}: {message}
writer.file = log.txt
In this way, when there is no error, I see proper logging. But purposefully I gave wrong mysql connection properties, and then I see whole bunch of error logs on console but on the log file I see only debug, info logs.
This is likely due to one of the following two causes:
1) The Maven Configuration is Incomplete
For using tinylog instead of Logback, which is the default logging back-end of Spring Boot, you have to exclude Spring Boot's logging dependencies and replace them with the corresponding tinylog artifacts:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-api</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>tinylog-impl</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>slf4j-tinylog</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>jcl-tinylog</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.tinylog</groupId>
<artifactId>log4j1.2-api</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
(Copied from https://github.com/pmwmedia/tinylog-spring-boot-example/blob/v2/pom.xml)
2) Exception is not Output via a Logger
Have you checked that the exception is logged via a logger (e.g. Logger.error(ex)) and not printed via ex.printStackTrace() directly to the console? tinylog (and any other logging framework) can only write log entries into files, if these log entries are issued via logging API.
If none of both suggestions fix the issue, it would be helpful to know which logging API is being used to log the missing exception.

Maven Spring boot dependency vs Maven Spring dependency

What is the difference between the way I declare the two dependency?
My project is a spring boot project...
This one I downloaded from Spring Initializer:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
This one is from mvnrepository.com:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
<version>3.1.0.RELEASE</version>
</dependency>
Update, this article shows a third way:
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
The first one is a Spring Boot starter. According to the documentation:
Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors.
The pom.xml of spring-boot-starter-data-ldap contains the following dependency definitions:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
The second one: spring-security-ldap is the artifact present in maven central, corresponding to the Spring LDAP project.

Debug log4j Configuration in a spring boot webapplication

I am developing a multimodule webapp with spring boot. My webapplication always takes the log4j config from the dependend submodule, which is not desired. Is there a way to show debug info, which logback or log4j file is used?
You need to exclude default by adding these to pom
<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>

where to put the log4j.properties file in a spring boot application

I have created a log4j.properties file, and I have put it in the resources folder as the application.properties file, in this file I have this line : logging.config=log4j.properties which indicated the name of my log4j properties file, but when I run my application I'm getting this error on my console :
Logging system failed to initialize using configuration from 'log4j.properties'
java.io.FileNotFoundException: C:\Users\***\Desktop\CapRecrute\log4j.properties (The system cannot find the file specified)
so I tried to change the logging.config property to src\\main\\resources\\log4j.properties, and then I got another error :
java.lang.IllegalStateException: Could not initialize Logback logging from src\main\resources\log4j.properties ... Caused by: ch.qos.logback.core.LogbackException: Unexpected filename extension of file [file:/C:/Users/Aimad%20MAJDOU/Desktop/CapRecrute/src/main/resources/log4j.properties]. Should be either .groovy or .xml
in my pom file I have this :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</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>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
How can I solve this ?
The simplest thing is to use Spring's Logback. You just need to add these 2 lines to application.properties
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
and make sure there are no other logging related lines.
If you instead want log4j, then configure so in your pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>
And then in your paplication.properties:
logging.path=/tmp/logs/
logging.file=/tmp/logs/myapplog.log
logging.config=log4j.properties
Also make sure log4j is in the root of your project (not under resources).
Spring boot is expecting a logback file by default and you have provided log4j configuration. If you add the log4j dependency you should find it works. If you are using maven you can do so like this:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
Two issues:
Is slf4j-log4j12 exclusion required?
I think that exclusion of spring-boot-starter-logging should be applied to spring-boot-starter.
That's not complete POM. I assume that spring-boot-starter is included, right?
If you remove slf4j-log4j12 exclusion and move spring-boot-starter-logging to spring-boot-starter your file should look like example from documentation.
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
<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-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

How to set logback file path with spring?

I have JavaEE application that uses Spring and Logback.
I want be able to set log file path in application.properties file (which stores Spring properties).
Setting property ${path.to.log.file} in logback.xml do not work (and it's understandable). What is good way to do it then?
Based on Spring reference documentation:
Make sure that you exclude commons-logging from Spring dependencies. Note that this exclusion may happen for more than one module of Spring.
Assuming that you're using SLF4J, make sure that you also include jcl-over-slf4j in your dependencies.
Include the proper Logback dependencies that you need.
Place logback.xml configuration in the root of your classpath.
Probably something like this finally:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${version.spring}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${version.slf4j}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${version.logback}</version>
</dependency>
One way to achieve this will be by setting a property for logpath in system variable.
Suppose you are using tomcat, then in your setenv.bat/setenv.sh file set the property as
-Dpath.to.log.file="/home/birendra/"
Now you can refer the path in your logback.xml

Resources