This app works fine in IntelliJ and creates the log files as per configurations, however when launched the app from command line its not using logback-spring.xml file and instead goes on to create *tmp/spring.log file which seems to coming from spring *logback/base.xml.
I have spent couple of days to troubleshoot this issue but nothing seems to work so far and other questions do not address the underlying issue, your help is appreciated.
I am launching the app as -
java -jar abc.jar -Dspring.profiles.active=test
I can see that logback-spring.xml is present inside abc.jar as
BOOT-INF/classes/ logback-spring.xml
Here you can find how to configure logback with spring-boot howto.logging.logback
With src/main/resources/logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<!-- include spring boot file-appender -->
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" /> <!-- add file-appender -->
</root>
<logger name="com.example" level="DEBUG"/>
</configuration>
And providing a logging file-name in src/main/resources/application.properties
logging.file.name=application.log
You should see a file application.log in the same directory as you launched your application with
java -jar your-app.jar --spring.profiles.active=test
Related
I am implementing logging in a Spring Boot project with logback library. I want to load different logging configuration files according to my Spring profiles (property spring.pofiles.active). I have 3 files:
logback-dev.xml
logback-inte.xml
logback-prod.xml
I am using Spring Boot version 1.2.2.RELEASE.
As you can read in Spring Boot documentation:
The various logging systems can be activated by including the appropriate libraries on the classpath, and further customized by providing a suitable configuration file in the root of the classpath, or in a location specified by the Spring Environment property logging.config. (Note however that since logging is initialized before the ApplicationContext is created, it isn’t possible to control logging from #PropertySources in Spring #Configuration files. System properties and the conventional Spring Boot external configuration files work just fine.)
So I tried to set logging.config property in my application.properties file:
logging.config=classpath:/logback-${spring.profiles.active}.xml
But when i start my application, my logback-{profile}.xml is not loaded.
I think logging is a common problem that all projects using Spring Boot have encountered. Am I on the right track with the above approach?
I have other solutions that work, but I find them not as elegant (conditional parsing with Janino in logback.xml file or command line property).
I found a solution and I understood why Spring doesn't use my logging.config property defined in the application.properties file.
Solution and explanation
When initializing logging, Spring Boot only looks in classpath or environment variables.
The solution I used was to include a parent logback.xml file that included the right logging config file according to the Spring profile.
logback.xml
<configuration>
<include resource="logback-${spring.profiles.active}.xml"/>
</configuration>
logback-[profile].xml (in this case, logback-dev.xml) :
<included>
<!-- put your appenders -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{ISO8601} %p %t %c{0}.%M - %m%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- put your loggers here -->
<logger name="org.springframework.web" additivity="false" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
<!-- put your root here -->
<root level="warn">
<appender-ref ref="CONSOLE" />
</root>
</included>
Note
spring.profiles.active has to be set in command line arguments when starting the app.
Example for JVM properties: -Dspring.profiles.active=dev
Reference documentation
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
http://docs.spring.io/spring-boot/docs/0.5.0.M3/api/org/springframework/boot/context/initializer/LoggingApplicationContextInitializer.html
Edit (multiple active profiles)
In order to avoid multiple files, we could use conditional processing which requires Janino dependency (setup here), see conditional documentation.
With this method, we can also check for multiple active profiles at the same time. E.g (I did not test this solution, so please comment if it does not work):
<configuration>
<if condition='"${spring.profiles.active}".contains("profile1")'>
<then>
<!-- do whatever you want for profile1 -->
</then>
</if>
<if condition='"${spring.profiles.active}".contains("profile2")'>
<then>
<!-- do whatever you want for profile2 -->
</then>
</if>
<!-- common config -->
</configuration>
See #javasenior answer for another example of a conditional processing.
Another approach that could handle multiple profiles is to create a separate properties file for each environment.
application-prod.properties
logging.config=classpath:logback-prod.xml
application-dev.properties
logging.config=classpath:logback-dev.xml
application-local.properties
logging.config=classpath:logback-local.xml
BE AWARE
If you aren't careful you could end up logging somewhere unexpected
-Dspring.profiles.active=local,dev //will use logback-dev.xml
-Dspring.profiles.active=dev,local //will use logback-local.xml
Instead of adding separate logback xmls for each profile or having the IF condition , I would suggest the following (If you have less difference in the xmls') for easy conditional processing
Documentation link here:
<springProfile name="dev">
<logger name="org.sample" level="DEBUG" />
</springProfile>
<springProfile name="prod">
<logger name="org.sample" level="TRACE" />
</springProfile>
Conditional processing with logback will be a solution without many logback files. Here is a link and a sample logback configuration with spring profiles.
<configuration>
<property name="LOG_LEVEL" value="INFO"/>
<if condition='"product".equals("${spring.profiles.active}")'>
<then>
<property name="LOG_LEVEL" value="INFO"/>
</then>
<else>
<property name="LOG_LEVEL" value="ERROR"/>
</else>
</if>
.
.
appender, logger tags etc.
.
.
<root level="${LOG_LEVEL}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Also, you might have to add this to your pom.xml
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.6</version>
</dependency>
Spring has support of next tag <springProperty/> inside Logback XML file, this tag described here . It means that you can easily add variable from Spring property file, even this variable value resolves from environment/system variable by Spring.
You can specific different logback.xml for different profile, only 3 steps:
1, Specify actived profile in application.properties or application.yml:
spring.profiles.active: test
2, Config logback to include different configuration by profile:
<!DOCTYPE configuration>
<configuration scan="true" scanPeriod="30 seconds">
<springProperty scope="context" name="profile" source="spring.profiles.active"/>
<include resource="logback.${profile}.xml"/>
</configuration>
3, Create configuration file logback.test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<included>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<root level="INFO"/>
</included>
It's very simple, don't need do anything else.
I'm using the default logging configuration of spring-boot.
How can I prevent the console output, while keeping the logging into a logfile configured with logging.file=myfile.log?
My goal is to not having console windows output, but only logging to that file.
Without having to create a specific logback.xml configuration. Because I'm using spring-boot for not having to configure the logging myself.
It turned out if I set the following property empty, the console logging is disabled:
logging.pattern.console=
Or commenting in xml if you use it
<!--<root level="error">-->
<!--<appender-ref ref="console"/>-->
<!--</root>-->
I created a file called logback.xml with the content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework" level="ERROR"/>
<logger name="org.hibernate" level="ERROR"/>
</configuration>
See this link for more information: https://www.mkyong.com/spring-boot/spring-boot-test-how-to-stop-debug-logs/
Create a file logback-spring.xml in /resources/ folder of your application.
Copy the below content in logback-spring.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<configuration>
<appender name = "STDOUT" class = "ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%m%n</pattern>
</encoder>
</appender>
<root level = "INFO">
<appender-ref ref = "STDOUT"/>
</root>
</configuration>
All the supported logging systems can have the logger levels set in the Spring Environment using ‘logging.level.*=LEVEL’ where ‘LEVEL’ is one of TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. The root logger can be configured using logging.level.root. Example application.properties:
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
Check this information: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
You could also overwrite the logback configuration and provide the value OFF to it.
<configuration>
<!-- turn OFF all logging (children can override) -->
<root level="OFF">
<appender-ref ref="STDOUT" />
</root>
</configuration>
You can find more information at the following link: https://logback.qos.ch/manual/configuration.html#rootElement
I am facing this trouble for a long time now without accessing the debug logs of the managed Threads in my Spring boot application when run on Tomcat. All the logs appear when run on the Eclipse/STS.
In Tomcat logs, I can only see the main Tread Logs.
I am connection to a database through JDBC and this is happening in a separate thread. I tried to follow the log configuration documentation but none of them helps to get the debug logs of these threads. So I do not actually see the exact problem of what is causing the connection to fail.
Here is what I tried so far:
I tried with the following logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p
%c{1}:%L - %m%n</pattern> </encoder> </appender> <logger name="com.biscoind"
additivity="false" level="TRACE"> <appender-ref ref="stdout" /> </logger>
<root level="debug"> <appender-ref ref="stdout" /> </root> -->
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework.web" level="DEBUG" />
</configuration>
When that did not resolve the issue I removed this file and see if by default, if it logs all the treads. But it did not.
So, I added the following configurations to the application.properties
logging.level.org.springframework.web:TRACE
logging.level.org.hibernate:ERROR
Then It seemed to me that this is only logging out the above namespaces, I again added
debug=true
logging.level.org.springframework.web:DEBUG
logging.level.org.hibernate:DEBUG
Tried and it did not work.
I added my namespaces also and tried as follwing,
debug=true
logging.level.com.mydomain:DEBUG
logging.level.org.springframework.web:DEBUG
logging.level.org.hibernate:DEBUG
That did not work also, I am now confused on the what should I do with the config relative to logging to make the logs to appear for the tread executions.
Irrespective of the treads, because of the property spring.jpa.show-sql=true it logs the queries that are made.
It was not a problem with the threads at all. The application was working correctly in the development environment. The problem was in the deployment environment.
It turned out to be a Java version miss-match with the jar files and the JVM version. The jars were build using Java 8 and it was running on Java 7 JVM.
When the JMV was changed to Java-8. It worked fine. So Next time I will be more careful with the version mismatch.
I am implementing logging in a Spring Boot project with logback library. I want to load different logging configuration files according to my Spring profiles (property spring.pofiles.active). I have 3 files:
logback-dev.xml
logback-inte.xml
logback-prod.xml
I am using Spring Boot version 1.2.2.RELEASE.
As you can read in Spring Boot documentation:
The various logging systems can be activated by including the appropriate libraries on the classpath, and further customized by providing a suitable configuration file in the root of the classpath, or in a location specified by the Spring Environment property logging.config. (Note however that since logging is initialized before the ApplicationContext is created, it isn’t possible to control logging from #PropertySources in Spring #Configuration files. System properties and the conventional Spring Boot external configuration files work just fine.)
So I tried to set logging.config property in my application.properties file:
logging.config=classpath:/logback-${spring.profiles.active}.xml
But when i start my application, my logback-{profile}.xml is not loaded.
I think logging is a common problem that all projects using Spring Boot have encountered. Am I on the right track with the above approach?
I have other solutions that work, but I find them not as elegant (conditional parsing with Janino in logback.xml file or command line property).
I found a solution and I understood why Spring doesn't use my logging.config property defined in the application.properties file.
Solution and explanation
When initializing logging, Spring Boot only looks in classpath or environment variables.
The solution I used was to include a parent logback.xml file that included the right logging config file according to the Spring profile.
logback.xml
<configuration>
<include resource="logback-${spring.profiles.active}.xml"/>
</configuration>
logback-[profile].xml (in this case, logback-dev.xml) :
<included>
<!-- put your appenders -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{ISO8601} %p %t %c{0}.%M - %m%n</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<!-- put your loggers here -->
<logger name="org.springframework.web" additivity="false" level="INFO">
<appender-ref ref="CONSOLE" />
</logger>
<!-- put your root here -->
<root level="warn">
<appender-ref ref="CONSOLE" />
</root>
</included>
Note
spring.profiles.active has to be set in command line arguments when starting the app.
Example for JVM properties: -Dspring.profiles.active=dev
Reference documentation
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
http://docs.spring.io/spring-boot/docs/0.5.0.M3/api/org/springframework/boot/context/initializer/LoggingApplicationContextInitializer.html
Edit (multiple active profiles)
In order to avoid multiple files, we could use conditional processing which requires Janino dependency (setup here), see conditional documentation.
With this method, we can also check for multiple active profiles at the same time. E.g (I did not test this solution, so please comment if it does not work):
<configuration>
<if condition='"${spring.profiles.active}".contains("profile1")'>
<then>
<!-- do whatever you want for profile1 -->
</then>
</if>
<if condition='"${spring.profiles.active}".contains("profile2")'>
<then>
<!-- do whatever you want for profile2 -->
</then>
</if>
<!-- common config -->
</configuration>
See #javasenior answer for another example of a conditional processing.
Another approach that could handle multiple profiles is to create a separate properties file for each environment.
application-prod.properties
logging.config=classpath:logback-prod.xml
application-dev.properties
logging.config=classpath:logback-dev.xml
application-local.properties
logging.config=classpath:logback-local.xml
BE AWARE
If you aren't careful you could end up logging somewhere unexpected
-Dspring.profiles.active=local,dev //will use logback-dev.xml
-Dspring.profiles.active=dev,local //will use logback-local.xml
Instead of adding separate logback xmls for each profile or having the IF condition , I would suggest the following (If you have less difference in the xmls') for easy conditional processing
Documentation link here:
<springProfile name="dev">
<logger name="org.sample" level="DEBUG" />
</springProfile>
<springProfile name="prod">
<logger name="org.sample" level="TRACE" />
</springProfile>
Conditional processing with logback will be a solution without many logback files. Here is a link and a sample logback configuration with spring profiles.
<configuration>
<property name="LOG_LEVEL" value="INFO"/>
<if condition='"product".equals("${spring.profiles.active}")'>
<then>
<property name="LOG_LEVEL" value="INFO"/>
</then>
<else>
<property name="LOG_LEVEL" value="ERROR"/>
</else>
</if>
.
.
appender, logger tags etc.
.
.
<root level="${LOG_LEVEL}">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
Also, you might have to add this to your pom.xml
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.0.6</version>
</dependency>
Spring has support of next tag <springProperty/> inside Logback XML file, this tag described here . It means that you can easily add variable from Spring property file, even this variable value resolves from environment/system variable by Spring.
You can specific different logback.xml for different profile, only 3 steps:
1, Specify actived profile in application.properties or application.yml:
spring.profiles.active: test
2, Config logback to include different configuration by profile:
<!DOCTYPE configuration>
<configuration scan="true" scanPeriod="30 seconds">
<springProperty scope="context" name="profile" source="spring.profiles.active"/>
<include resource="logback.${profile}.xml"/>
</configuration>
3, Create configuration file logback.test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<included>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<root level="INFO"/>
</included>
It's very simple, don't need do anything else.
I am using Spring Boot to build a simple webapp, however, I am not using the embedded Tomcat container. Instead, I am building a .war file and deploying manually to a Tomcat 7 instance.
I am using Logback with the following configuration:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_FILE" value="./logs/jcme.log" />
<include resource="org/springframework/boot/logging/logback/base.xml" />
<!-- 3rd Party Loggers -->
<logger name="org.springframework.web" level="INFO" />
<logger name="org.springframework.boot" level="INFO" />
<logger name="org.hibernate" level="INFO" />
<logger name="org.quartz" level="INFO" />
</configuration>
When running the .war file inside Tomcat running in Eclipse, the log appends properly to both STDOUT and FILE appenders as configured in "../logback/base.xml".
However, when deploying this to an external Tomcat container, the "jcme.log" file is created, but is empty.
What am I missing?
Please have a look on this. I had the same issue and created a setenv.bat file in my /bin with following code and it worked:
set logging.config=classpath:/logback.xml