diff --git a/bin/hbase b/bin/hbase index 689d4265e85f..59c48712b672 100755 --- a/bin/hbase +++ b/bin/hbase @@ -306,6 +306,8 @@ for f in "${HBASE_HOME}"/lib/client-facing-thirdparty/*.jar; do CLASSPATH="${CLASSPATH}:${f}" fi done +# redirect java.util.logging to slf4j +HBASE_OPTS="$HBASE_OPTS -Djava.util.logging.config.class=org.apache.hadoop.hbase.logging.JulToSlf4jInitializer" # default log directory & file if [ "$HBASE_LOG_DIR" = "" ]; then diff --git a/bin/hbase.cmd b/bin/hbase.cmd index a927227aa9fb..3b569099090f 100644 --- a/bin/hbase.cmd +++ b/bin/hbase.cmd @@ -326,6 +326,9 @@ set HBASE_OPTS=%HBASE_OPTS% -Dhbase.home.dir="%HBASE_HOME%" set HBASE_OPTS=%HBASE_OPTS% -Dhbase.id.str="%HBASE_IDENT_STRING%" set HBASE_OPTS=%HBASE_OPTS% -XX:OnOutOfMemoryError="taskkill /F /PID %p" +@rem redirect java.util.logging to slf4j +set HBASE_OPTS=%HBASE_OPTS% -Djava.util.logging.config.class="org.apache.hadoop.hbase.logging.JulToSlf4jInitializer" + if not defined HBASE_ROOT_LOGGER ( set HBASE_ROOT_LOGGER=INFO,console ) diff --git a/hbase-archetypes/hbase-client-project/pom.xml b/hbase-archetypes/hbase-client-project/pom.xml index ad22dad6b2c8..7662e73fe482 100644 --- a/hbase-archetypes/hbase-client-project/pom.xml +++ b/hbase-archetypes/hbase-client-project/pom.xml @@ -53,6 +53,16 @@ org.apache.hbase hbase-client + + org.slf4j + jcl-over-slf4j + runtime + + + org.slf4j + jul-to-slf4j + runtime + org.slf4j slf4j-log4j12 diff --git a/hbase-archetypes/hbase-shaded-client-project/pom.xml b/hbase-archetypes/hbase-shaded-client-project/pom.xml index 2269bb1527a4..dd35fedbb8e3 100644 --- a/hbase-archetypes/hbase-shaded-client-project/pom.xml +++ b/hbase-archetypes/hbase-shaded-client-project/pom.xml @@ -59,6 +59,16 @@ org.apache.hbase hbase-shaded-client + + org.slf4j + jcl-over-slf4j + runtime + + + org.slf4j + jul-to-slf4j + runtime + org.slf4j slf4j-log4j12 diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/logging/TestJul2Slf4j.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/logging/TestJul2Slf4j.java new file mode 100644 index 000000000000..cf654f583b89 --- /dev/null +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/logging/TestJul2Slf4j.java @@ -0,0 +1,82 @@ +/** + * 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.hadoop.hbase.logging; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.io.IOException; +import org.apache.hadoop.hbase.HBaseClassTestRule; +import org.apache.hadoop.hbase.testclassification.MiscTests; +import org.apache.hadoop.hbase.testclassification.SmallTests; +import org.apache.log4j.Appender; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.apache.log4j.spi.LoggingEvent; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mockito.ArgumentCaptor; + +/** + * This should be in the hbase-logging module but the {@link HBaseClassTestRule} is in hbase-common + * so we can only put the class in hbase-common module for now... + */ +@Category({ MiscTests.class, SmallTests.class }) +public class TestJul2Slf4j { + + @ClassRule + public static final HBaseClassTestRule CLASS_RULE = + HBaseClassTestRule.forClass(TestJul2Slf4j.class); + + static { + System.setProperty("java.util.logging.config.class", JulToSlf4jInitializer.class.getName()); + } + + private String loggerName = getClass().getName(); + + private Appender mockAppender; + + @Before + public void setUp() { + mockAppender = mock(Appender.class); + LogManager.getRootLogger().addAppender(mockAppender); + } + + @After + public void tearDown() { + LogManager.getRootLogger().removeAppender(mockAppender); + } + + @Test + public void test() throws IOException { + java.util.logging.Logger logger = java.util.logging.Logger.getLogger(loggerName); + logger.info(loggerName); + ArgumentCaptor captor = ArgumentCaptor.forClass(LoggingEvent.class); + verify(mockAppender, times(1)).doAppend(captor.capture()); + LoggingEvent loggingEvent = captor.getValue(); + assertThat(loggingEvent.getLevel(), is(Level.INFO)); + assertEquals(loggerName, loggingEvent.getRenderedMessage()); + } +} diff --git a/hbase-logging/pom.xml b/hbase-logging/pom.xml index c7c0cf589705..858b46091cfa 100644 --- a/hbase-logging/pom.xml +++ b/hbase-logging/pom.xml @@ -83,6 +83,11 @@ slf4j-log4j12 test + + org.slf4j + jul-to-slf4j + provided + log4j log4j diff --git a/hbase-logging/src/main/java/org/apache/hadoop/hbase/logging/JulToSlf4jInitializer.java b/hbase-logging/src/main/java/org/apache/hadoop/hbase/logging/JulToSlf4jInitializer.java new file mode 100644 index 000000000000..e7b5fdd39356 --- /dev/null +++ b/hbase-logging/src/main/java/org/apache/hadoop/hbase/logging/JulToSlf4jInitializer.java @@ -0,0 +1,42 @@ +/** + * 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.hadoop.hbase.logging; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.logging.LogManager; +import org.apache.yetus.audience.InterfaceAudience; +import org.slf4j.bridge.SLF4JBridgeHandler; + +/** + * Setup {@link SLF4JBridgeHandler}. + *

+ * Set the system property {@code java.util.logging.config.class} to this class to initialize the + * direction for java.util.logging to slf4j. + */ +@InterfaceAudience.Private +public class JulToSlf4jInitializer { + + private static final String PROPERTIES = "handlers=" + SLF4JBridgeHandler.class.getName(); + + public JulToSlf4jInitializer() throws IOException { + LogManager.getLogManager() + .readConfiguration(new ByteArrayInputStream(PROPERTIES.getBytes(StandardCharsets.UTF_8))); + } +} diff --git a/hbase-shaded/hbase-shaded-testing-util-tester/pom.xml b/hbase-shaded/hbase-shaded-testing-util-tester/pom.xml index a3f366d10545..a46381f7423b 100644 --- a/hbase-shaded/hbase-shaded-testing-util-tester/pom.xml +++ b/hbase-shaded/hbase-shaded-testing-util-tester/pom.xml @@ -1,6 +1,6 @@ + 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"> - 4.0.0 + 4.0.0 - - org.apache.hbase - hbase-build-configuration - 2.5.0-SNAPSHOT - ../../hbase-build-configuration - + + org.apache.hbase + hbase-build-configuration + 2.5.0-SNAPSHOT + ../../hbase-build-configuration + - hbase-shaded-testing-util-tester - Apache HBase - Shaded - Testing Util Tester - Ensures that hbase-shaded-testing-util works with hbase-shaded-client. + hbase-shaded-testing-util-tester + Apache HBase - Shaded - Testing Util Tester + Ensures that hbase-shaded-testing-util works with hbase-shaded-client. - - - junit - junit - test - - - - org.slf4j - slf4j-log4j12 - test - - - - org.apache.hbase - hbase-shaded-client - ${project.version} - - - org.apache.hbase - hbase-shaded-testing-util - ${project.version} - test - - - org.codehaus.jackson - jackson-mapper-asl - 1.9.13 - test - - + + + junit + junit + test + + + org.slf4j + jcl-over-slf4j + test + + + org.slf4j + jul-to-slf4j + test + + + org.slf4j + slf4j-log4j12 + test + + + org.apache.hbase + hbase-shaded-client + + + org.apache.hbase + hbase-shaded-testing-util + ${project.version} + test + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.13 + test + + diff --git a/pom.xml b/pom.xml index 92cb517d872a..aa70b8dc5bdc 100755 --- a/pom.xml +++ b/pom.xml @@ -595,6 +595,7 @@ ${test.build.classes} ${test.tmp.dir} + org.apache.hadoop.hbase.logging.JulToSlf4jInitializer