From b3c5115b578fc9255900d40f45b142569e19059d Mon Sep 17 00:00:00 2001 From: Rainer Bieniek Date: Wed, 29 Jun 2022 14:01:13 +0200 Subject: [PATCH] cli: Replace log4j2 with logback The log4j2 logging framework recently gained some bad publicity for being the root cause for a couple of security issues / CVEs. A permanent solution to the security issues related to Log4j2 is a replacement with the well-known and battle-tested logback framework. The usage of the command-line tools remains unchanged, no additional options are introduced. Adding the capability to pass a pathname to a configuration file is left for future action. Signed-off-by: Rainer Bieniek --- cli/build.gradle.kts | 6 ++-- cli/src/main/kotlin/OrtMain.kt | 36 +++++++++++++++++++++--- gradle/libs.versions.toml | 8 ++++-- helper-cli/build.gradle.kts | 6 ++-- helper-cli/src/main/kotlin/HelperMain.kt | 36 +++++++++++++++++++++--- utils/test/build.gradle.kts | 5 +++- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/cli/build.gradle.kts b/cli/build.gradle.kts index 897819c0c44fb..c029df3cb4b62 100644 --- a/cli/build.gradle.kts +++ b/cli/build.gradle.kts @@ -155,10 +155,12 @@ dependencies { implementation(libs.jacksonDatabind) implementation(libs.jacksonModuleKotlin) implementation(libs.kotlinxCoroutines) - implementation(libs.log4jCore) - implementation(libs.log4jImplSlf4j) + implementation(libs.logbackClassic) implementation(libs.postgres) implementation(libs.reflections) + implementation(libs.slf4jApi) + implementation(libs.slf4jJcl) + implementation(libs.slf4jJul) implementation(libs.sw360Client) testImplementation(project(":utils:test-utils")) diff --git a/cli/src/main/kotlin/OrtMain.kt b/cli/src/main/kotlin/OrtMain.kt index 3f340ffda7502..ef62350dc812a 100644 --- a/cli/src/main/kotlin/OrtMain.kt +++ b/cli/src/main/kotlin/OrtMain.kt @@ -20,6 +20,13 @@ package org.ossreviewtoolkit.cli +import ch.qos.logback.classic.Level +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.ConsoleAppender + import com.github.ajalt.clikt.completion.completionOption import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.context @@ -39,9 +46,6 @@ import java.io.File import kotlin.system.exitProcess -import org.apache.logging.log4j.Level -import org.apache.logging.log4j.core.config.Configurator - import org.ossreviewtoolkit.cli.commands.* import org.ossreviewtoolkit.model.config.LicenseFilenamePatterns import org.ossreviewtoolkit.model.config.OrtConfiguration @@ -57,6 +61,8 @@ import org.ossreviewtoolkit.utils.ort.ortConfigDirectory import org.ossreviewtoolkit.utils.ort.ortDataDirectory import org.ossreviewtoolkit.utils.ort.printStackTrace +import org.slf4j.LoggerFactory + /** * Helper class for mutually exclusive command line options of different types. */ @@ -171,7 +177,7 @@ class OrtMain : CliktCommand(name = ORT_NAME, invokeWithoutSubcommand = true) { } override fun run() { - Configurator.setRootLevel(logLevel) + initLogging() log.debug { "Used command line arguments: ${currentContext.originalArgv}" } @@ -222,4 +228,26 @@ class OrtMain : CliktCommand(name = ORT_NAME, invokeWithoutSubcommand = true) { return header.joinToString("\n", postfix = "\n") } + + private fun initLogging() { + val logCtx: LoggerContext = LoggerFactory.getILoggerFactory() as LoggerContext + + val logEncoder = PatternLayoutEncoder() + + logEncoder.setContext(logCtx) + logEncoder.setPattern("%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level – %msg%n") + logEncoder.start() + + val logConsoleAppender = ConsoleAppender() + + logConsoleAppender.setContext(logCtx) + logConsoleAppender.setName("console") + logConsoleAppender.setEncoder(logEncoder) + logConsoleAppender.start() + + val rootLogger: Logger = logCtx.getLogger(Logger.ROOT_LOGGER_NAME) + + rootLogger.level = logLevel as Level + rootLogger.addAppender(logConsoleAppender) + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8fe09c9387fed..339a8cc7d6e50 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,6 +47,7 @@ kotlinxSerialization = "1.3.3" ktor = "1.6.8" log4j = "2.17.2" log4jApiKotlin = "1.1.0" +logbackClassic = "1.2.11" maven = "3.8.6" # @pin this version as it needs to be aligned with "maven". mavenResolver = "1.7.3" @@ -61,6 +62,7 @@ retrofitConverterKotlinxSerialization = "0.8.0" saxonHe = "11.3" scanoss = "1.1.6" semver4j = "3.1.0" +slf4j = "1.7.36" springCore = "5.3.21" svnkit = "1.10.6" # @pin this version as there are only newer weekly releases. @@ -135,8 +137,7 @@ ktorClientOkHttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" # @keep this library which is only being used via force(). log4jApi = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j" } log4jApiKotlin = { module = "org.apache.logging.log4j:log4j-api-kotlin", version.ref = "log4jApiKotlin" } -log4jCore = { module = "org.apache.logging.log4j:log4j-core", version.ref = "log4j" } -log4jImplSlf4j = { module = "org.apache.logging.log4j:log4j-slf4j-impl", version.ref = "log4j" } +logbackClassic = { module = "ch.qos.logback:logback-classic", version.ref = "logbackClassic" } mavenCompat = { module = "org.apache.maven:maven-compat", version.ref = "maven" } mavenCore = { module = "org.apache.maven:maven-core", version.ref = "maven" } mavenResolverConnectorBasic = { module = "org.apache.maven.resolver:maven-resolver-connector-basic", version.ref = "mavenResolver" } @@ -156,6 +157,9 @@ retrofitConverterScalars = { module = "com.squareup.retrofit2:converter-scalars" saxonHe = { module = "net.sf.saxon:Saxon-HE", version.ref = "saxonHe" } scanoss = { module = "com.scanoss:scanner", version.ref = "scanoss" } semver4j = { module = "com.vdurmont:semver4j", version.ref = "semver4j" } +slf4jApi = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } +slf4jJcl = { module = "org.slf4j:jcl-over-slf4j", version.ref = "slf4j" } +slf4jJul = { module = "org.slf4j:jul-to-slf4j", version.ref = "slf4j" } springCore = { module = "org.springframework:spring-core", version.ref = "springCore" } svnkit = { module = "org.tmatesoft.svnkit:svnkit", version.ref = "svnkit" } sw360Client = { module = "org.eclipse.sw360:client", version.ref = "sw360Client" } diff --git a/helper-cli/build.gradle.kts b/helper-cli/build.gradle.kts index 8a7acd91afff3..5ec3c11a96b24 100644 --- a/helper-cli/build.gradle.kts +++ b/helper-cli/build.gradle.kts @@ -96,6 +96,8 @@ dependencies { implementation(libs.exposedCore) implementation(libs.hikari) implementation(libs.jslt) - implementation(libs.log4jCore) - implementation(libs.log4jImplSlf4j) + implementation(libs.logbackClassic) + implementation(libs.slf4jApi) + implementation(libs.slf4jJcl) + implementation(libs.slf4jJul) } diff --git a/helper-cli/src/main/kotlin/HelperMain.kt b/helper-cli/src/main/kotlin/HelperMain.kt index b69042cd61879..18a21dd433be6 100644 --- a/helper-cli/src/main/kotlin/HelperMain.kt +++ b/helper-cli/src/main/kotlin/HelperMain.kt @@ -19,6 +19,13 @@ package org.ossreviewtoolkit.helper +import ch.qos.logback.classic.Level +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.classic.spi.ILoggingEvent +import ch.qos.logback.core.ConsoleAppender + import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.context import com.github.ajalt.clikt.core.subcommands @@ -28,9 +35,6 @@ import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.switch -import org.apache.logging.log4j.Level -import org.apache.logging.log4j.core.config.Configurator - import org.ossreviewtoolkit.helper.commands.CreateAnalyzerResultCommand import org.ossreviewtoolkit.helper.commands.DownloadResultsFromPostgresCommand import org.ossreviewtoolkit.helper.commands.ExtractRepositoryConfigurationCommand @@ -57,6 +61,8 @@ import org.ossreviewtoolkit.helper.commands.scanstorage.ScanStorageCommand import org.ossreviewtoolkit.helper.common.ORTH_NAME import org.ossreviewtoolkit.utils.ort.printStackTrace +import org.slf4j.LoggerFactory + /** * The entry point for the application with [args] being the list of arguments. */ @@ -106,9 +112,31 @@ internal class HelperMain : CliktCommand(name = ORTH_NAME, epilog = "* denotes r } override fun run() { - Configurator.setRootLevel(logLevel) + initLogging() // Make the parameter globally available. printStackTrace = stacktrace } + + private fun initLogging() { + val logCtx: LoggerContext = LoggerFactory.getILoggerFactory() as LoggerContext + + val logEncoder = PatternLayoutEncoder() + + logEncoder.setContext(logCtx) + logEncoder.setPattern("%-12date{YYYY-MM-dd HH:mm:ss.SSS} %-5level – %msg%n") + logEncoder.start() + + val logConsoleAppender = ConsoleAppender() + + logConsoleAppender.setContext(logCtx) + logConsoleAppender.setName("console") + logConsoleAppender.setEncoder(logEncoder) + logConsoleAppender.start() + + val rootLogger: Logger = logCtx.getLogger(Logger.ROOT_LOGGER_NAME) + + rootLogger.level = logLevel as Level + rootLogger.addAppender(logConsoleAppender) + } } diff --git a/utils/test/build.gradle.kts b/utils/test/build.gradle.kts index 2f06995284daf..8d8cef4cbe37e 100644 --- a/utils/test/build.gradle.kts +++ b/utils/test/build.gradle.kts @@ -33,6 +33,9 @@ dependencies { implementation(libs.jacksonModuleKotlin) implementation(libs.kotestExtensionsJunitXml) implementation(libs.kotestFrameworkEngine) - implementation(libs.log4jImplSlf4j) + implementation(libs.logbackClassic) + implementation(libs.slf4jApi) + implementation(libs.slf4jJcl) + implementation(libs.slf4jJul) implementation(libs.postgresEmbedded) }