Log4j.properties in Spring boot - 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.

Related

spring boot tomcat access logs log4j2 elastic common schema

Configuring spring boot to use log4j2 and the ECS was simple enough. All we needed to do was include the following dependencies in our 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>
<dependency>
<groupId>co.elastic.logging</groupId>
<artifactId>log4j2-ecs-layout</artifactId>
<version>1.0.1</version>
</dependency>
Then in the log4j2.xml file we just needed to include something like this:
<Console name="prod" target="SYSTEM_OUT">
<EcsLayout serviceName="${service-name}" stackTraceAsArray="true" includeOrigin="true" includeMarkers="true" />
</Console>
However, when we configure spring boot to log the application access logs in application.yml we do this:
server:
tomcat:
accesslog:
enabled: true
encoding: UTF-8
directory: /dev
prefix: stdout
buffered: false
suffix:
file-date-format:
pattern: "ACCESS_LOG: %h %l %u \"%{yyyy-MM-dd HH:mm:ss.SSS}t\" \"%r\" status=%s size=%b \"user-agent=%{User-Agent}i\""
The access logs are not logged as json with the EcsLayout.
How can I configure a spring boot application to log tomcat access logs as json to the console using the elastic common schema (json) format?

Spring Boot SLF4j Logback

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>

Why is my Log4j logging not displaying to the console?

I have a web app built in Eclipse/STS with Spring MVC and Maven.
I want to add logging, so I added SLF4 and Log4J to the pom.xml like this ..
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>
I have a simple log4j.properties file in the project/src/main/resources folder, like this ...
# Root logger option
log4j.rootLogger=DEBUG, stdout, file
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
I created a Logger class in my main WebController, like this ...
private static Logger logger = LoggerFactory.getLogger(WebController.class);
And in my "showMain" method I'm doing some logging stuff, like this ...
#RequestMapping(value={"", "/", "showhome"}, method={RequestMethod.POST,RequestMethod.GET})
public ModelAndView showHome(Model model) {
logger.info("########### TEST LOG INFO");
logger.error("########### TEST LOG ERROR");
logger.warn("########### TEST LOG WARN");
logger.debug("########### TEST LOG DEBUG");
/* ... */
}
But when I run the application, I don't see any logging output in the console.
I also don't see anything in the console output to indicate that it is even using the logging framework. And there's no "can't find log4j.properties" message or anything.
I tried putting the log4j.properties in different places in the project, but nothing.
I must be missing something simple? What have I missed?
In your pom.xml is missing the logging engine, you could use log4j2.
Please Consider to use the latest version of log4j2 instead of log4j (1.2.x) because you could take advance of:
Lazy log: log4j(1.2.x) build a string also if a level is not activated
lambda in order to avoid evaluation of expensive methods
A lot of appenders for modern platform
More easy way to configure a lot of parameters (reload configuration, appenders, ...)
pom.xml
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
</dependencies>
You stated that you added log4j in your pom.xml but I do not see it, are you sure this is your newest version of pom.xml?
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

Spring Boot with log4j2 not working when change default properties file name

I have Spring Boot application and I want to use log4j2 instead of logback. I've already done all the necessary steps to exclude spring-boot-starter-logging from spring-boot-starter-web and added spring-boot-starter-log4j2 dependency.
When I add log4j2.properties file under resources folder it works correct and I can see logs.
But when I change file name to, lets say log4j2-demo.properties and set logging.config=classpath:log4j2-demo.properties nothing prints to console. For testing purpose I've set different name for lo4gj2 file in logging.config and it gives error with file not found and I think logging.config property actually working and reading my properties file.
application.properties file:
spring.profiles.active=dev
application-dev.properties file:
logging.config=classpath:log4j2-demo.properties
log4j2 properties file:
status=debug
name=PropertiesConfig
#
filters=threshold
#
filter.threshold.type=ThresholdFilter
filter.threshold.level=debug
#
appenders=console
#
appender.console.type=Console
appender.console.name=STDOUT
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
#
rootLogger.level=info
rootLogger.appenderRefs=stdout
rootLogger.appenderRef.stdout.ref=STDOUT
my application structure:
src
main
java
resources
application.properties
application-dev.properties
log4j2-demo.properties
pom.xml :
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.graylog2.log4j2</groupId>
<artifactId>log4j2-gelf</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.zalando/logbook-spring-boot-starter -->
<dependency>
<groupId>org.zalando</groupId>
<artifactId>logbook-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
...
If you use log4j 2.13.0 you can use profiles to define log4j 2 system properties in your spring configuration. So you could have:
application-dev.properties
log4j2.configurationFile=log4j2-demo.properties.
Log4j 2.13.0 also supports placing the log4j 2 configuration file in Spring Cloud Config.
I'm not sure if this answer applies to this question, but in my case, I added the resource to the build configuration on my pom.xml, e.g.
...
<build>
...
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include> <!-- or **/*.properties -->
</includes>
</resource>
</resources>
...
</build>
...
Of course, I excluded spring-boot-starter-logging from spring-boot-starter-web and spring-boot-starter-actuator
...
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
...
Although, I used the default log4j2 file name log4j2.xml and the step configuration on the application.yml was not required, I mean this configuration logging.config=classpath:log4j2-demo.properties

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