Externalize logback-spring.xml programmatically - java

My application.properties are loaded programmatically
using PropertyPlaceholderConfigurer. So setting logging.config in application.properties (eg: logging.config=file:/home/dev-01/conf/logback.xml)
in the application.properties won't work since logging occurs early in the lifecycle and therefore cannot read values from application.properties.
I need to externalize the logback.xml as there are property values that needs to be configured depending on the environment. If I can externalize it, it can be manage by support/operations without developer intervention. Also, it is easy to maintain without redirection from application.properties. Meaning I can set property values in the logback.xml file itself.
I saw solution of adding the VM options during startup. I have not tried it but I am just wondering if I can load the logback.xml programmatically (similar to my application.properties).

i use a configuration like this to achieve that:
<configuration scan="true" scanPeriod="10 seconds" debug="false">
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<include file="${CONFDIR}/config/logback-config.xml" />
</configuration>
and then you place another logback config in that location and changes to that file will be refreshed every 10 seconds

Loading logback.xml programmatically does not seem to be a viable solution. My scenario is application.properties is loaded programmatically (from an external path) so setting logging.config property in application.properties file will not work. Note, it works using the default application.properties in classpath. I think the most pragmatic approach is passing -Dlogging.config=/[some-path]/logback.xml. This option works for me and updating logging levels (for debugging purpose) without redeploying the jar file.
Setting the logback.xml configuration scan to true will refresh the settings if logback.xml is updated.
<configuration debug="true" scan="true">
...
</configuration>

Related

Logback Spring - Change log levels during runtime using an external yaml file outside of the jar

Inside of my logback-spring.xml file, I am able to change the log levels, and it's able to autodetect changes when I include auto scan. Looks like this:
<configuration debug="true" scan="true" scanPeriod="10 seconds">
However, I want to keep all of my log levels in an external yaml configuration file and I don't want to have to restart the server to detect those changes. Is there a way to use an external yaml file to define log levels and use logback autoscan? Or should I be looking at a completely different way of going about it?
You can do that in application.yml, try adding the following settings
spring:
logging:
level:
org.springframework.web: DEBUG
com.company.package: DEBUG
You can also specify pattern if you like.

How can I see where the properties in application.properties file refer to?

I have some lines inside my application.properties like
logging.level.com.website.project.mapper=INFO
I want to see where this value is actually used to understand everything about it. Can IntelliJ somehow bring me to where it is used? Or does the programmer have to know all about the properties by himself?
Press CTRL+SHIFT+F in your IntelliJ, switch to Scope directory and set All Places. After that, you can paste a property name in search box. After that, you can see all usage of property.
Sometimes properties name are assigned to variables, so after when you find it, you need to also check this variable usage.
Spring Boot allows you to define log level in your properties. So logging.level.com.website.project.mapper=INFO is equivalent to the following Logback config :
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="com.website.project.mapper" level="INFO"/>
</configuration>
IntelliJ will offer you completion for package names after logging.level..
So it's used internally, you have to look into Spring Boot code to find where it's used. Have a look at the doc to understand better how it works : https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html.

How do I change log level in runtime without restarting Vert.x application

I know that we can change log level by putting it in vertx-default-jul-logging.properties file.
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level=FINER
java.util.logging.FileHandler.limit=10000000
java.util.logging.FileHandler.count=10
java.util.logging.FileHandler.level=FINER
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
But I need to restart the application when we change log level in this file as it gets built with application. Is there any way to change the log level without restarting the application like we can do in jboss by jboss cli.
This file doesn't have to be built with the application. It just has to be on the classpath.
But anyway, I don't believe JDK logging supports hot reload of a configuration file. There are other logging tools which do though. Like Logback-classic.
Logback-classic can scan for changes in its configuration file and automatically reconfigure itself when the configuration file changes.
For example, to reload every five seconds:
<configuration scan="true" scanPeriod="5 seconds" >
...
</configuration>
Vert.x can be configured to use different logging frameworks. To do so, you must set the vertx.logger-delegate-factory-class-name system property. As Logback-classic is an slf4j implementation, you need:
-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory

Change logging level dynamically in spring boot app

I have a spring boot app where I provide logging configuration using
-Dlog4j.configuration=file:E:\workspace\log4j.properties
I am using slf4j for logging. Is there any way in which I can just change "log4j.rootLogger" property and log level can be changed dynamically. If not then what should be the best approach to do that in which I can have minimal change in code. Thanks in advance
You can configure monitorInterval in your log4j configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
...
</Configuration>
https://logging.apache.org/log4j/2.x/manual/configuration.html
Log4j will automatically detect changes to the configuration file and reconfigure itself.

Log4J2 - How to disable logging in unit test?

I am using Log4J v2.0 Beta3 in my application for logging and I am getting log messages generated when I run my unit tests. I checked the API for some way to set the log level to something like CRITICAL but I could not find any way to change the logger configuration.
In fact, I read this on the log4j2 website:
Note that unlike Log4j 1.x, the public Log4j 2 API does not expose
methods to add, modify or remove appenders and filters or manipulate
the configuration in any way.
So with that said. What is the correct way to disable logging from within unit tests?
I found my answer on the log4j2 website under 'Testing in Maven'. The recommended way seems to be to place a log4j2-test.xml file in src/test/resources. Placing the xml file into this directory will cause it to be used instead of a log4j2.xml.
You can disable logging with setting root level to off (<Root level="off"/>).
So place log4j2.xml file into src/test/resources with following content:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Loggers>
<Root level="off"/>
</Loggers>
</Configuration>
EDIT:
Removed <!DOCTYPE xml> (based on suggestion from sprynter) to make xml valid.
Both the answers from #Jbug and #Dove work as long as you are placing the file in src/test/resources of the current module. If your app depends on a library to include log4j2.xml it won't work for test runs since library jar won't included test classes and resources.

Categories