Grouping spring logback slf4j loggers - spring-boot

I am running a spring boot application. for logging purpose we have used spring logback.
there is spring-logback.xml file where we define log level more likely at package level.
is there a way to group logger (may be at feature level) and package names are not same as feature name , which can have common configuration. more like instead of changing each class log level of feature . changing log level at feature which changes log level of all linked/grouped loggers.

Spring support grouping in configuration properties rather than in logback-spring.xml
for more info
https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/html/boot-features-logging.html#boot-features-custom-log-groups

Related

Logback with Spring Boot - programatically change configuration at runtime to add Syslog Appender

I am building an application (Spring Boot 1.4.2) where i would like to offer an administrator the option to enable syslog but i want to avoid him/her having to manually edit any config files - in this case logstash-spring.xml.
Therefore i am trying to understand how i can achieve using a logback-spring.xml file as a baseline (e.g. define file based log options, levels etc. - settings i dont want the administrator to change) and on top of that provide a functionality at runtime where an administrator can add or change a syslog appender.
I have listed what i see as requirements:
The changes made to the Logger should be persisted after the Spring Boot application is restarted.
Ideally the syslog server info (name, port) are kept in my persistence layer (H2, hibernate) but i am not sure if that is possible as i guess the logging framework is being injected prior to my persistence layer?
The syslog appender that i want to add should be referenced by root logger so that all the packages i have configured logging for would go to syslog (not sure if this is just "how it works per default")
Also i dont know if i could simply treat logback-spring.xml as a regular XML object and use for example JAXB to manipulate that file and use the autoscan feature of Logback to simply read in the new changes?
I have played around with defining a Logger #Bean:
#Bean
public Logger logger() {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
// excluded implementation
}
This is being picked up by Spring Boot but that brings me to the 2 items i have listed above that i dont know how or where i would store the syslog server information the administrator would provide.
UPDATE:
I wrote the following which meets the 3 requirements above however i would appreciate any feedback on the actual implementation as i am very new to Spring and Java.
GitHub repository with implementation - spring-boot-logback-syslog
I managed to use the example i posted in my Github repo in my designated application and with that i am answering my own questions based on the implementation in that repo.
Please refer to the README for full details on how it was implemented.
UPDATE: As part of Spring Boot 1.5.1 there is an actuator that can set the logging level during runtime: Production Ready Loggers
Not necessarily 100% related to this topic but this was one of the requirements i had for the implementation as well as changing syslog related settings.

How to change logback log level dynamically in spring boot application

I have a Spring boot application which use logback.xml for logging configurations.I am looking for options to dynamically change log level.
For instance if I have deployed an app with loglevel as ERROR,Let say I want to change this to INFO but I don't want to redeploy/restart my JVM.
Is there any possibility we can configure logback.xml like config server to achieve this
You can configure Logback to Automatically reloading configuration file upon modification
Yes, this is quite possible. Expose a rest endpoint where you supply the className and log level. With slf4j you can get the LoggerContext and change the level.
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
context.getLogger(className).setLevel(Level.valueOf(level));
Apache Commons logging and others have similar features.
If you are using spring cloud then you can have this in your yml file
logging:
level:
root: INFO
Then you can change it and refresh the configuration using actuator refresh to fetch new configuration changes no need to restart the service.
Also if you need some sort of UI to do this stuff you can explore the Spring-cloud-dashboard It is pretty cool and uses the features from the actuator to do and show you a lot of stuff not only changing log levels.

Spring Boot Logging Configuration

Is there a way to disable Spring boot logs and print only the logs which i give in the program using logger.info or logger.debug statements. I mean i want only the log statements which i had given in the program to be logged and nothing else. I use the default logging system given by spring boot. If required i can change to log4j or log4j2 as well. Using spring-boot version 1.2.7.
In other way, putting forward , like logging.level.org.springframework can be used to log spring related logs ,is there a way like logging.level.applicationlevel to get application(Java logger statement) logs alone
You can configure your logging in your application.properties like below:
logging.level.com.myapp.packagename=INFO
logging.level.org.springframework=ERROR
INFO means it will print logging of classes in your package and all sub package at INFO/ERROR/WARN level, while for spring related classes only print if there are ERROR level logging.
You can configure logging properties as follows:
logging.level.* = ERROR
logging.level.package_name=DEBUG
Example:
logging.level.com.example.controller=DEBUG
So classes under com.example.controller package will be logged, others only on error will be logged.
I hope this helped!!

Spring Boot application log level

I want to change the log level of a Spring Boot application that is running.
Is it possible to change the log level at runtime? Right now I have the logger configuration in my jar itself.
Changing the log level while the application is running is part of the underlying logger implementation.
You did not specify the logger implementation you are using so I will assume you are using the default logback provided via the spring-boot-starter-logging or spring-boot-starter-web dependencies.
Comment out any logger related configurations from application.properties
e.g.
#logging.path=logs
#logging.level.org.springframework.web= INFO
#logging.level.=INFO
Add logback.xml in the root of your classpath with tag
See http://logback.qos.ch/manual/jmxConfig.html
Start the application and open JConsole and go to MBeans tab.
Select the package ch.qos.logback.classic.JMxConfigurator.Under default locate the setLoggerLevel operation
e.g. org.springframework.web, DEBUG
The change will be effective immediately.
For other logger libraries see the spring boot user guide
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html
And library specific information e.g. for log4j
http://www.sureshpw.com/2012/04/dynamic-logging-with-log4j.html
A different approach is to repeat the about steps without JMX and use configuration watcher
Logback Automatically reloading configuration file upon modification
Log4j configureAndWatch(java.lang.String, long)
If you want to change the logging level of an already running Spring Boot application you can take a look at spring-cloud-config. Refer to:
http://cloud.spring.io/spring-cloud-config/:
Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments.
You can centrally manage the properties in config server and in your current application - applications.properties file (check bootstrap.properties) create an entry for
spring.application.name=application name
Using #RefreshScope annotation in your client application you will be able to refresh your application runtime and see the updated logging level property.
With the release of Spring Boot 1.5, if you have actuator in your Boot application you can do this through an out of the box REST API.
1.5 actuator provides an endpoint called 'loggers' which you can GET to view the configuration, and POST to make runtime changes.
Ex.
curl -i -X POST -H 'Content-Type: application/json' -d '{"configuredLevel": "DEBUG"}' http://localhost:8080/loggers/org.springframwork

can logback use property defined in spring?

we put properties in a specific place(kept by zooKeeper, and already parsed into spring), not in classpath. Now in logback.xml, I need a DBAppender to log messages into mysql, I don't want to copy a properties into classpath, and I try to use placeholder ${url} directly without importing properties in logback.xml, it does not work.
So is there a way to use configuration in spring for logback?
No logback can only access system properties. And also logback tends to be intialised before spring, although you can cause it to be reconfigured.
Have a look at how spring-boot does it. It copies some (about 3 or 4) properties from spring config into system properties before re-initialising logback. In this way the log file path can be interpolated via spring properties and variable replacement.

Resources