This is an automated email from the ASF dual-hosted git repository. grossws pushed a commit to branch logging-refactoring in repository https://gitbox.apache.org/repos/asf/tika.git
commit 6b95dd2f36c1c5c49732e20f33049ad1a56c251a Author: Konstantin Gribov <[email protected]> AuthorDate: Thu Nov 10 03:54:54 2022 +0300 Implement tika-logging-* * `tika-logging-common` provides simple API and SPI to configure underlying logging backend * `tika-logging-slf4j-bridges` brings slf4j bridges for java.util.logging, Apache Commons Logging (JCL) and Apache Log4j 1.2 * `tika-logging-log4j2-impl` implements SPI to configure Apache Log4j 2.x and brings slf4j-api 2.x --- pom.xml | 1 + tika-bom/pom.xml | 17 +++++ tika-logging/pom.xml | 42 ++++++++++++ tika-logging/tika-logging-common/pom.xml | 42 ++++++++++++ .../tika/logging/api/LoggerLevelChangeContext.java | 32 +++++++++ .../tika/logging/api/LoggingConfigurator.java | 66 +++++++++++++++++++ .../logging/spi/LoggingConfiguratorProvider.java | 76 ++++++++++++++++++++++ tika-logging/tika-logging-log4j2-impl/pom.xml | 52 +++++++++++++++ .../logging/log4j2/Log4j2LoggingConfigurator.java | 38 +++++++++++ ...he.tika.logging.spi.LoggingConfiguratorProvider | 1 + .../log4j2/Log4j2LoggingConfiguratorTest.java | 73 +++++++++++++++++++++ tika-logging/tika-logging-slf4j-bridges/pom.xml | 50 ++++++++++++++ tika-parent/pom.xml | 10 +++ 13 files changed, 500 insertions(+) diff --git a/pom.xml b/pom.xml index f0d0e3627..9637ddb02 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ <module>tika-example</module> <module>tika-java7</module> <module>tika-detectors</module> + <module>tika-logging</module> </modules> <properties> diff --git a/tika-bom/pom.xml b/tika-bom/pom.xml index 95f378b69..5c3b87be3 100644 --- a/tika-bom/pom.xml +++ b/tika-bom/pom.xml @@ -424,6 +424,23 @@ <artifactId>tika-httpclient-commons</artifactId> <version>2.6.1-SNAPSHOT</version> </dependency> + + <!-- Tika logging modules --> + <dependency> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging-common</artifactId> + <version>2.6.1-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging-slf4j-bridges</artifactId> + <version>2.6.1-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging-log4j2-impl</artifactId> + <version>2.6.1-SNAPSHOT</version> + </dependency> </dependencies> </dependencyManagement> </project> diff --git a/tika-logging/pom.xml b/tika-logging/pom.xml new file mode 100644 index 000000000..16ce07719 --- /dev/null +++ b/tika-logging/pom.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tika</groupId> + <artifactId>tika</artifactId> + <version>2.6.1-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tika-logging</artifactId> + <packaging>pom</packaging> + + <name>Apache Tika logging modules</name> + + <modules> + <module>tika-logging-common</module> + <module>tika-logging-slf4j-bridges</module> + <module>tika-logging-log4j2-impl</module> + </modules> +</project> diff --git a/tika-logging/tika-logging-common/pom.xml b/tika-logging/tika-logging-common/pom.xml new file mode 100644 index 000000000..dce030798 --- /dev/null +++ b/tika-logging/tika-logging-common/pom.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging</artifactId> + <version>2.6.1-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tika-logging-common</artifactId> + + <name>Apache Tika logging API and SPI</name> + + <dependencies> + <dependency> + <groupId>org.apache.tika</groupId> + <artifactId>tika-core</artifactId> + </dependency> + </dependencies> +</project> diff --git a/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/api/LoggerLevelChangeContext.java b/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/api/LoggerLevelChangeContext.java new file mode 100644 index 000000000..717a99c60 --- /dev/null +++ b/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/api/LoggerLevelChangeContext.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.logging.api; + +public class LoggerLevelChangeContext implements AutoCloseable { + private final String loggerName; + private final String originalLevel; + + public LoggerLevelChangeContext(String loggerName, String currentLevel) { + this.loggerName = loggerName; + this.originalLevel = LoggingConfigurator.setLoggerLevel(loggerName, currentLevel); + } + + @Override + public void close() throws Exception { + LoggingConfigurator.setLoggerLevel(loggerName, originalLevel); + } +} diff --git a/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/api/LoggingConfigurator.java b/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/api/LoggingConfigurator.java new file mode 100644 index 000000000..1b12b25a4 --- /dev/null +++ b/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/api/LoggingConfigurator.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.logging.api; + +import org.apache.tika.logging.spi.LoggingConfiguratorProvider; + +public class LoggingConfigurator { + private static final LoggingConfiguratorProvider INSTANCE = LoggingConfiguratorProvider.Holder.INSTANCE; + + private static final String ROOT_LOGGER_NAME = INSTANCE.getRootLoggerName(); + + private LoggingConfigurator() { + } + + public static String getLoggerLevel(String loggerName) { + return INSTANCE.getLoggerLevel(loggerName); + } + + public static String getLoggerLevel(Class<?> clazz) { + return getLoggerLevel(clazz.getCanonicalName()); + } + + public static String getRootLoggerLevel() { + return getLoggerLevel(ROOT_LOGGER_NAME); + } + + public static String setLoggerLevel(String loggerName, String level) { + String originalLevel = INSTANCE.getLoggerLevel(loggerName); + INSTANCE.setLoggerLevel(loggerName, level); + return originalLevel; + } + + public static String setLoggerLevel(Class<?> clazz, String level) { + return setLoggerLevel(clazz.getCanonicalName(), level); + } + + public static String setRootLoggerLevel(String level) { + return setLoggerLevel(ROOT_LOGGER_NAME, level); + } + + public static LoggerLevelChangeContext withLoggerLevel(String loggerName, String level) { + return new LoggerLevelChangeContext(loggerName, level); + } + + public static LoggerLevelChangeContext withLoggerLevel(Class<?> clazz, String level) { + return new LoggerLevelChangeContext(clazz.getCanonicalName(), level); + } + + public static LoggerLevelChangeContext withRootLoggerLevel(String level) { + return new LoggerLevelChangeContext(ROOT_LOGGER_NAME, level); + } +} diff --git a/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/spi/LoggingConfiguratorProvider.java b/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/spi/LoggingConfiguratorProvider.java new file mode 100644 index 000000000..ec55a31e4 --- /dev/null +++ b/tika-logging/tika-logging-common/src/main/java/org/apache/tika/logging/spi/LoggingConfiguratorProvider.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.logging.spi; + +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.tika.config.ServiceLoader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public interface LoggingConfiguratorProvider { + String getRootLoggerName(); + + String getLoggerLevel(String loggerName); + + void setLoggerLevel(String loggerName, String level); + + class Holder { + private static final Logger LOG = LoggerFactory.getLogger(Holder.class); + + private static final ServiceLoader LOADER = new ServiceLoader(); + + public static final LoggingConfiguratorProvider INSTANCE; + + static { + List<LoggingConfiguratorProvider> configurators = LOADER.loadStaticServiceProviders(LoggingConfiguratorProvider.class); + if (configurators.isEmpty()) { + INSTANCE = NoOpLoggingConfiguratorProvider.INSTANCE; + } else { + INSTANCE = configurators.get(0); + } + + if (configurators.size() > 1) { + LOG.warn("Found several {} instances: {}", + LoggingConfiguratorProvider.class.getCanonicalName(), + configurators.stream().map(c -> c.getClass().getCanonicalName()).collect(Collectors.joining(", "))); + } + } + } + + class NoOpLoggingConfiguratorProvider implements LoggingConfiguratorProvider { + public static final LoggingConfiguratorProvider INSTANCE = new NoOpLoggingConfiguratorProvider(); + + private NoOpLoggingConfiguratorProvider() { + } + + @Override + public String getRootLoggerName() { + return ""; + } + + @Override + public String getLoggerLevel(String loggerName) { + return "INFO"; + } + + @Override + public void setLoggerLevel(String loggerName, String level) { + } + } +} diff --git a/tika-logging/tika-logging-log4j2-impl/pom.xml b/tika-logging/tika-logging-log4j2-impl/pom.xml new file mode 100644 index 000000000..f869dc917 --- /dev/null +++ b/tika-logging/tika-logging-log4j2-impl/pom.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging</artifactId> + <version>2.6.1-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tika-logging-log4j2-impl</artifactId> + + <name>Apache Tika logging implementation :: Log4j 2.x</name> + + <dependencies> + <dependency> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging-common</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j2-impl</artifactId> + </dependency> + </dependencies> +</project> diff --git a/tika-logging/tika-logging-log4j2-impl/src/main/java/org/apache/tika/logging/log4j2/Log4j2LoggingConfigurator.java b/tika-logging/tika-logging-log4j2-impl/src/main/java/org/apache/tika/logging/log4j2/Log4j2LoggingConfigurator.java new file mode 100644 index 000000000..50d094c1c --- /dev/null +++ b/tika-logging/tika-logging-log4j2-impl/src/main/java/org/apache/tika/logging/log4j2/Log4j2LoggingConfigurator.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.logging.log4j2; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.config.Configurator; +import org.apache.tika.logging.spi.LoggingConfiguratorProvider; + +public class Log4j2LoggingConfigurator implements LoggingConfiguratorProvider { + @Override + public String getRootLoggerName() { + return LogManager.ROOT_LOGGER_NAME; + } + + @Override + public String getLoggerLevel(String loggerName) { + return LogManager.getLogger(loggerName).getLevel().name(); + } + + @Override + public void setLoggerLevel(String loggerName, String level) { + Configurator.setLevel(loggerName, level); + } +} diff --git a/tika-logging/tika-logging-log4j2-impl/src/main/resources/META-INF/services/org.apache.tika.logging.spi.LoggingConfiguratorProvider b/tika-logging/tika-logging-log4j2-impl/src/main/resources/META-INF/services/org.apache.tika.logging.spi.LoggingConfiguratorProvider new file mode 100644 index 000000000..7e7a8904a --- /dev/null +++ b/tika-logging/tika-logging-log4j2-impl/src/main/resources/META-INF/services/org.apache.tika.logging.spi.LoggingConfiguratorProvider @@ -0,0 +1 @@ +org.apache.tika.logging.log4j2.Log4j2LoggingConfigurator \ No newline at end of file diff --git a/tika-logging/tika-logging-log4j2-impl/src/test/java/org/apache/tika/logging/log4j2/Log4j2LoggingConfiguratorTest.java b/tika-logging/tika-logging-log4j2-impl/src/test/java/org/apache/tika/logging/log4j2/Log4j2LoggingConfiguratorTest.java new file mode 100644 index 000000000..9df718689 --- /dev/null +++ b/tika-logging/tika-logging-log4j2-impl/src/test/java/org/apache/tika/logging/log4j2/Log4j2LoggingConfiguratorTest.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.logging.log4j2; + +import java.util.stream.Stream; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.config.Configurator; +import org.apache.tika.logging.api.LoggerLevelChangeContext; +import org.apache.tika.logging.api.LoggingConfigurator; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +class Log4j2LoggingConfiguratorTest { + @BeforeEach + void initClass() { + Configurator.setRootLevel(Level.INFO); + Configurator.setLevel(LoggingConfigurator.class, Level.WARN); + } + + @ParameterizedTest + @MethodSource("loggerLevelArgs") + void getLoggerLevelReturnsCorrectValue(Level expected, Level ignored, String loggerName) { + assertEquals(expected, LogManager.getLogger(loggerName).getLevel()); + assertEquals(expected.name(), LoggingConfigurator.getLoggerLevel(loggerName)); + } + + @ParameterizedTest + @MethodSource("loggerLevelArgs") + void setLoggerLevel(Level before, Level after, String loggerName) { + String originalLevel = LoggingConfigurator.setLoggerLevel(loggerName, after.name()); + assertEquals(before.name(), originalLevel); + assertEquals(after, LogManager.getLogger(loggerName).getLevel()); + assertEquals(after.name(), LoggingConfigurator.getLoggerLevel(loggerName)); + } + + @ParameterizedTest + @MethodSource("loggerLevelArgs") + void withLoggerLevel(Level before, Level after, String loggerName) throws Exception { + try (LoggerLevelChangeContext ignored = LoggingConfigurator.withLoggerLevel(loggerName, after.name())) { + assertEquals(after, LogManager.getLogger(loggerName).getLevel()); + } + assertEquals(before, LogManager.getLogger(loggerName).getLevel()); + } + + static Stream<Arguments> loggerLevelArgs() { + return Stream.of( + arguments(Level.INFO, Level.ERROR, LogManager.ROOT_LOGGER_NAME), + arguments(Level.WARN, Level.ERROR, LoggingConfigurator.class.getCanonicalName()), + arguments(Level.INFO, Level.ERROR, Log4j2LoggingConfigurator.class.getCanonicalName()) + ); + } +} diff --git a/tika-logging/tika-logging-slf4j-bridges/pom.xml b/tika-logging/tika-logging-slf4j-bridges/pom.xml new file mode 100644 index 000000000..d5172d53d --- /dev/null +++ b/tika-logging/tika-logging-slf4j-bridges/pom.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.tika</groupId> + <artifactId>tika-logging</artifactId> + <version>2.6.1-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tika-logging-slf4j-bridges</artifactId> + + <name>Apache Tika logging slf4j bridges</name> + + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jul-to-slf4j</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>log4j-over-slf4j</artifactId> + </dependency> + </dependencies> +</project> diff --git a/tika-parent/pom.xml b/tika-parent/pom.xml index b766c2224..0cae946fc 100644 --- a/tika-parent/pom.xml +++ b/tika-parent/pom.xml @@ -893,6 +893,16 @@ <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jul-to-slf4j</artifactId> + <version>${slf4j.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>log4j-over-slf4j</artifactId> + <version>${slf4j.version}</version> + </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId>
