How to set logback file path with spring? - 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

Related

Disable features into Spring Boot/Cloud

I'm interested is it possible to disable features into Spring Boot/Cloud which are not used?
If there is no way to remove a lot of the necessary features? Do you know some guide how I can make a custom build?
I'm interested how Spring Boot can be optimized for read-time processing.
You can exclude features as tomcat from starter's dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-core</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-websocket</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
</exclusions>
</dependency>
Or similar for Logback by removing from build or classpath:
Spring Boot tries to work with whatever is in the classpath, so if you don't want logback, take it off the classpath.
Add exclusion to both the spring-boot-starter and spring-boot-starter-web to resolve the conflict.
Or cloud config/discovery:
#Disable discovery
spring.cloud.discovery.enabled = false
#Disable cloud config and config discovery
spring.cloud.config.discovery.enabled = false
spring.cloud.config.enabled = false
What are the features are you expecting to disable ?
If you feel any dependency is not used try tag in your pom.xml. So that you can cut down some dependency and make you application lightweight.

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.

Can't use hbase-shaded-client jar because of its internal dependency to log4j-1.2.17(CVE-2019-1757)

Is there a way to exclude it.I did give it a try but got ClassNotFoundException: org.apache.log4j.Level
I do see that hbase-shaded-client do have slf4j dependency so there might be a way to exclude log4j and use slf4j but I'm not able to.
Yes, you can exclude log4j, but you must add back in log4j-over-slf4j.
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>[some version]</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>[some version]</version>
</dependency>

Externalize logback.xml in Spring MVC

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

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>

Resources