Created
December 31, 2022 13:55
-
-
Save libetl/4d9f7805a9035a8fb35cfd08886dca6b to your computer and use it in GitHub Desktop.
Custom logback Joran Configuration in spring boot 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.company.myservice.tool | |
import ch.qos.logback.classic.Level | |
import ch.qos.logback.classic.Logger | |
import ch.qos.logback.classic.LoggerContext | |
import ch.qos.logback.classic.joran.JoranConfigurator | |
import ch.qos.logback.classic.turbo.TurboFilter | |
import ch.qos.logback.core.spi.FilterReply | |
import ch.qos.logback.core.status.Status | |
import ch.qos.logback.core.status.StatusUtil | |
import ch.qos.logback.core.util.StatusPrinter | |
import org.slf4j.LoggerFactory | |
import org.slf4j.Marker | |
import org.springframework.boot.logging.LogFile | |
import org.springframework.boot.logging.LoggingInitializationContext | |
import org.springframework.boot.logging.LoggingSystem | |
import org.springframework.boot.logging.LoggingSystemFactory | |
import org.springframework.boot.logging.LoggingSystemProperties | |
import org.springframework.boot.logging.logback.CustomLogbackJoranConfigurator | |
import org.springframework.boot.logging.logback.LogbackLoggingSystem | |
import org.springframework.util.ResourceUtils | |
internal class CustomLogbackSystemFactory : LoggingSystemFactory { | |
override fun getLoggingSystem(classLoader: ClassLoader?): LoggingSystem { | |
return object : LogbackLoggingSystem(classLoader) { | |
private val denyFilter: TurboFilter = object : TurboFilter() { | |
override fun decide( | |
marker: Marker, | |
logger: Logger, | |
level: Level, | |
format: String, | |
params: Array<Any>, | |
t: Throwable | |
): FilterReply { | |
return FilterReply.DENY | |
} | |
} | |
override fun initialize( | |
initializationContext: LoggingInitializationContext?, | |
configLocation: String?, | |
logFile: LogFile? | |
) { | |
val loggerContext = LoggerFactory.getILoggerFactory() as? LoggerContext ?: return | |
if (loggerContext.getObject(LoggingSystem::class.java.name) != null) { | |
return | |
} | |
if (initializationContext != null) { | |
LoggingSystemProperties(initializationContext.environment).apply(logFile) | |
} | |
loggerContext.stop() | |
loggerContext.reset() | |
val configurator = CustomLogbackJoranConfigurator( | |
initializationContext!!, | |
classLoader!! | |
) | |
configurator.context = loggerContext | |
configurator.configureUsingAotGeneratedArtifacts() | |
initializeWithConventions(initializationContext, logFile) | |
loggerContext.turboFilterList?.remove(denyFilter) | |
loggerContext.putObject(LoggingSystem::class.java.name, Any()) | |
} | |
fun initializeWithConventions(initializationContext: LoggingInitializationContext, logFile: LogFile?) { | |
var config: String? = selfInitializationConfig | |
if (config != null && logFile == null) { | |
// self initialization has occurred, reinitialize in case of property changes | |
reinitialize(initializationContext) | |
return | |
} | |
if (config == null) { | |
config = springInitializationConfig | |
} | |
if (config != null) { | |
loadConfiguration(initializationContext, config, logFile) | |
return | |
} | |
loadDefaults(initializationContext, logFile) | |
} | |
override fun loadConfiguration( | |
initializationContext: LoggingInitializationContext?, | |
location: String, | |
logFile: LogFile? | |
) { | |
if (initializationContext != null) { | |
applySystemProperties(initializationContext.environment, logFile) | |
} | |
val loggerContext = LoggerFactory.getILoggerFactory() as LoggerContext | |
loggerContext.stop() | |
loggerContext.reset() | |
val configurator: JoranConfigurator = | |
CustomLogbackJoranConfigurator(initializationContext!!, classLoader!!) | |
configurator.context = loggerContext | |
configurator.doConfigure(ResourceUtils.getURL(location)) | |
val statuses = loggerContext.statusManager.copyOfStatusList | |
val errors = StringBuilder() | |
for (status in statuses) { | |
if (status.level == Status.ERROR) { | |
errors.append(if (errors.isNotEmpty()) String.format("%n") else "") | |
errors.append(status.toString()) | |
} | |
} | |
check(errors.isEmpty()) { String.format("Logback configuration error detected: %n%s", errors) } | |
if (!StatusUtil.contextHasStatusListener(loggerContext)) { | |
StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext) | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment