I want to use default SLF4J + Logback configuration except setting org.springframework.data.document.mongodb
logging level to DEBUG
.
How can I do it with Java code?
I'm not using XML, and this decision made at runtime.
Loggers are the third main component of Logback, which developers can use to log messages at a certain level. The library defines 5 log levels: TRACE, DEBUG, INFO, WARN, ERROR; each of these has a corresponding logging method: trace(), debug(), info(), warn(), error().
To change log levels as a root user, perform the following: To enable debug logging, run the following command: /subsystem=logging/root-logger=ROOT:change-root-log-level(level=DEBUG) To disable debug logging, run the following command: /subsystem=logging/root-logger=ROOT:change-root-log-level(level=INFO)
The following works for me but generally this is not a good idea. Your code will depend on Logback (you can't choose another logging framework behind SLF4J).
final org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger("test.package");
if (!(logger instanceof ch.qos.logback.classic.Logger)) {
return;
}
ch.qos.logback.classic.Logger logbackLogger =
(ch.qos.logback.classic.Logger) logger;
logbackLogger.setLevel(ch.qos.logback.classic.Level.TRACE);
logger.trace("some log");
Depending to logback-classic
is not a good idea as @palacsint stated. You can achieve what you want using Java's Reflection API. Note that this approach puts some overhead to your program because of use of reflection.
LogbackUtils.setLogLevel("com.stackoverflow.sample", "DEBUG")
public static final String LOGBACK_CLASSIC = "ch.qos.logback.classic";
public static final String LOGBACK_CLASSIC_LOGGER = "ch.qos.logback.classic.Logger";
public static final String LOGBACK_CLASSIC_LEVEL = "ch.qos.logback.classic.Level";
private static final Logger logger = LoggerFactory.getLogger(LogbackUtils.class);
/**
* Dynamically sets the logback log level for the given class to the specified level.
*
* @param loggerName Name of the logger to set its log level. If blank, root logger will be used.
* @param logLevel One of the supported log levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL,
* OFF. {@code null} value is considered as 'OFF'.
*/
public static boolean setLogLevel(String loggerName, String logLevel)
{
String logLevelUpper = (logLevel == null) ? "OFF" : logLevel.toUpperCase();
try
{
Package logbackPackage = Package.getPackage(LOGBACK_CLASSIC);
if (logbackPackage == null)
{
logger.info("Logback is not in the classpath!");
return false;
}
// Use ROOT logger if given logger name is blank.
if ((loggerName == null) || loggerName.trim().isEmpty())
{
loggerName = (String) getFieldValue(LOGBACK_CLASSIC_LOGGER, "ROOT_LOGGER_NAME");
}
// Obtain logger by the name
Logger loggerObtained = LoggerFactory.getLogger(loggerName);
if (loggerObtained == null)
{
// I don't know if this case occurs
logger.warn("No logger for the name: {}", loggerName);
return false;
}
Object logLevelObj = getFieldValue(LOGBACK_CLASSIC_LEVEL, logLevelUpper);
if (logLevelObj == null)
{
logger.warn("No such log level: {}", logLevelUpper);
return false;
}
Class<?>[] paramTypes = { logLevelObj.getClass() };
Object[] params = { logLevelObj };
Class<?> clz = Class.forName(LOGBACK_CLASSIC_LOGGER);
Method method = clz.getMethod("setLevel", paramTypes);
method.invoke(loggerObtained, params);
logger.debug("Log level set to {} for the logger '{}'", logLevelUpper, loggerName);
return true;
}
catch (Exception e)
{
logger.warn("Couldn't set log level to {} for the logger '{}'", logLevelUpper, loggerName, e);
return false;
}
}
// getFieldValue() method omitted for bravity from here,
// but available at GitHub link below.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With