Disabling Spring log, to have readable logs - spring

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.

Related

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>

Direct Spring DEBUG logging to Console

I have a Maven project and I want to direct DEBUG Spring logging to the console.
My log interface is slf4j and I'm binding to Log4j2.
In my pom.xml I have excluded commons-logging in favour or Slf4j:
<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>
I believe slf4j is wired up correctly because I have this in my log4j2.xml:
<Logger name="com.myApp" level="info" additivity="false">
<AppenderRef ref="Console" />
</Logger>
This in my test class constructor:
logger.info("constructor");
logger.debug("constructor");
and if i flip the log level in log4j2.xml from info/debug I get one or two log lines in the console.
I also have this in my log4j2.xml:
<Logger name="org.springframework" level="all" additivity="false">
<AppenderRef ref="Console" />
</Logger>
But it has zero effect. What am I missing? Why doesn't Spring log detailed debug lines to the console?
Found it if it helps anyone else. This dependency was missing:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.1</version>
</dependency>
So logging looks like its working, but Spring logging is not.

How to avoid C3P0 logging framework from generation lots of String objects

During a performance test with c3p0, I found that com.mchange.v2.resourcepool.BasicResourcePool.trace() is creating a lots of string objects. Although the strings output are suppressed by the slf4j log instance (as the log level is warn), this contributed significantly on the object allocation rate. Do we have any configuration of avoiding this? Thanks in advance.
logback.xml
<logger name="com.mchange" level="WARN" additivity="false">
<appender-ref ref="ROLLING" />
</logger>
pom.xml
<logback.version>1.1.3</logback.version>
<slf4j.version>1.7.12</slf4j.version>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
So BasicResourcePool.trace() is properly guarded to test the logger for FINEST (which should map to TRACE before allocating Strings. The question then is why, given your config, are the Strings being allocated?
The answer turns out to be... I screwed up. The guard methods in the bridge library to slf4j logging improperly reported that loggers were logging at levels that they were not (in the mchange-commons-java library on which c3p0 depends). Pretty bad. I'll try to publish a fix tonight (and notify you with a comment).

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.

Resources