Sometimes you need to change log-level for parts of your application at run-time. Most likely for debugging.
When researching this topic I found a useful trait that logs log-level. https://github.com/jfrosch/GrailsLoggingIssue
package no.prpr
trait LogHelper {
void log() {
String simpleName = this.class.simpleName
log.error ">>> ${simpleName} error message"
log.warn ">>> ${simpleName} warn message"
log.info ">>> ${simpleName} info message"
log.debug ">>> ${simpleName} debug message"
log.trace ">>> ${simpleName} trace message"
}
}
With this I created a LogLevel controller to visualize and manipulate log-levels:
package no.prpr
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.Logger
import ch.qos.logback.classic.LoggerContext
import org.slf4j.LoggerFactory
class LogLevelController implements LogHelper {
def index() {
log.debug("index")
log()
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
def loggerList = context.getLoggerList().findAll() { logger ->
logger.name.startsWith('no.prpr')
}
def loggerNames = loggerList*.name
def logLevels = new LinkedHashMap<>()
loggerList.each { logger ->
logLevels.put(logger.name, [level: logger.level, effectiveLevel: logger.effectiveLevel])
}
def logLevelList = []
respond logLevelList, model: [loggers: loggerNames, logLevels: logLevels]
}
def update() {
log.debug("update")
log.debug("logLevel: ${params['level']}")
log.debug("logger: ${params['logger']}")
Logger logger = LoggerFactory.getLogger(params['logger'])
logger.setLevel(Level.toLevel(params['level']))
redirect action: 'index'
}
}
The loggerList variable gets very long if not filtered.
Here’s the logLevel/index.gsp:
<!doctype html>
<html>
<head>
<meta name="layout" content="main"/>
<title>Welcome to Grails</title>
</head>
<body>
<div id="content" role="main">
<section class="row colset-2-its">
<h1>LogLevel controller</h1>
</section>
<div >
<br>
loggerList: ${loggers}
<br>
<br>
logLevels: ${logLevels}
<br>
</div>
<g:form action="update">
<br>
Logger: <g:select name="logger" from="${loggers}"></g:select>
<br>
LogLevel: <g:select name="level" from="['DEBUG', 'INFO', 'TRACE']"></g:select>
<br>
<input class="save" type="submit" value="Set loglevel" />
</g:form>
</div>
</body>
</html>
It seems to update immediately.
Beware that depending on other settings logback can update from configuration-file at interval.