diff --git a/client/src/main/java/org/apache/rocketmq/client/log/ClientLogger.java b/client/src/main/java/org/apache/rocketmq/client/log/ClientLogger.java index c3df9a63947..b3ff606b8e6 100644 --- a/client/src/main/java/org/apache/rocketmq/client/log/ClientLogger.java +++ b/client/src/main/java/org/apache/rocketmq/client/log/ClientLogger.java @@ -16,13 +16,12 @@ */ package org.apache.rocketmq.client.log; + import org.apache.rocketmq.common.constant.LoggerName; -import org.slf4j.ILoggerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.rocketmq.common.utils.LogUtils.loadLoggerConfig; -import java.lang.reflect.Method; -import java.net.URL; public class ClientLogger { public static final String CLIENT_LOG_ROOT = "rocketmq.client.logRoot"; @@ -54,50 +53,7 @@ private static Logger createLogger(final String loggerName) { if (isloadconfig) { try { - ILoggerFactory iLoggerFactory = LoggerFactory.getILoggerFactory(); - Class classType = iLoggerFactory.getClass(); - if (classType.getName().equals("org.slf4j.impl.Log4jLoggerFactory")) { - Class domconfigurator; - Object domconfiguratorobj; - domconfigurator = Class.forName("org.apache.log4j.xml.DOMConfigurator"); - domconfiguratorobj = domconfigurator.newInstance(); - if (null == logConfigFilePath) { - Method configure = domconfiguratorobj.getClass().getMethod("configure", URL.class); - URL url = ClientLogger.class.getClassLoader().getResource(log4JResourceFile); - configure.invoke(domconfiguratorobj, url); - } else { - Method configure = domconfiguratorobj.getClass().getMethod("configure", String.class); - configure.invoke(domconfiguratorobj, logConfigFilePath); - } - - } else if (classType.getName().equals("ch.qos.logback.classic.LoggerContext")) { - Class joranConfigurator; - Class context = Class.forName("ch.qos.logback.core.Context"); - Object joranConfiguratoroObj; - joranConfigurator = Class.forName("ch.qos.logback.classic.joran.JoranConfigurator"); - joranConfiguratoroObj = joranConfigurator.newInstance(); - Method setContext = joranConfiguratoroObj.getClass().getMethod("setContext", context); - setContext.invoke(joranConfiguratoroObj, iLoggerFactory); - if (null == logConfigFilePath) { - URL url = ClientLogger.class.getClassLoader().getResource(logbackResourceFile); - Method doConfigure = - joranConfiguratoroObj.getClass().getMethod("doConfigure", URL.class); - doConfigure.invoke(joranConfiguratoroObj, url); - } else { - Method doConfigure = - joranConfiguratoroObj.getClass().getMethod("doConfigure", String.class); - doConfigure.invoke(joranConfiguratoroObj, logConfigFilePath); - } - - } else if (classType.getName().equals("org.apache.logging.slf4j.Log4jLoggerFactory")) { - Class joranConfigurator = Class.forName("org.apache.logging.log4j.core.config.Configurator"); - Method initialize = joranConfigurator.getDeclaredMethod("initialize", String.class, String.class); - if (null == logConfigFilePath) { - initialize.invoke(joranConfigurator, "log4j2", log4J2ResourceFile); - } else { - initialize.invoke(joranConfigurator, "log4j2", logConfigFilePath); - } - } + loadLoggerConfig(logConfigFilePath, log4JResourceFile, log4J2ResourceFile, logbackResourceFile); } catch (Exception e) { System.err.println(e); } @@ -105,6 +61,7 @@ private static Logger createLogger(final String loggerName) { return LoggerFactory.getLogger(LoggerName.CLIENT_LOGGER_NAME); } + public static Logger getLog() { if (log == null) { log = createLogger(LoggerName.CLIENT_LOGGER_NAME); diff --git a/common/src/main/java/org/apache/rocketmq/common/utils/LogUtils.java b/common/src/main/java/org/apache/rocketmq/common/utils/LogUtils.java new file mode 100644 index 00000000000..9aae28f2d23 --- /dev/null +++ b/common/src/main/java/org/apache/rocketmq/common/utils/LogUtils.java @@ -0,0 +1,112 @@ +/* + * 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.rocketmq.common.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import org.slf4j.ILoggerFactory; +import org.slf4j.LoggerFactory; + +public class LogUtils { + + /** + * config logback dynamically from provided file path, otherwise try to config from resource file + * @param logConfigFilePath specified logback configuration file path + * @param logbackResourceFile specified logback configuration resource file, which will only be respected when logConfigFilePath is null + * @param iLoggerFactory + * @throws ClassNotFoundException + * @throws InstantiationException + * @throws IllegalAccessException + * @throws NoSuchMethodException + * @throws InvocationTargetException + */ + public static void configLogback(String logConfigFilePath, String logbackResourceFile, ILoggerFactory iLoggerFactory) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + Class joranConfigurator; + Class context = Class.forName("ch.qos.logback.core.Context"); + Object joranConfiguratoroObj; + joranConfigurator = Class.forName("ch.qos.logback.classic.joran.JoranConfigurator"); + joranConfiguratoroObj = joranConfigurator.newInstance(); + Method setContext = joranConfiguratoroObj.getClass().getMethod("setContext", context); + setContext.invoke(joranConfiguratoroObj, iLoggerFactory); + if (null == logConfigFilePath) { + if (logbackResourceFile != null) { + URL url = LogUtils.class.getClassLoader().getResource(logbackResourceFile); + Method doConfigure = joranConfiguratoroObj.getClass().getMethod("doConfigure", URL.class); + doConfigure.invoke(joranConfiguratoroObj, url); + } + } else { + Method doConfigure = joranConfiguratoroObj.getClass().getMethod("doConfigure", String.class); + doConfigure.invoke(joranConfiguratoroObj, logConfigFilePath); + } + } + + /** + * config log4j dynamically from provided file path, otherwise try to config from resource file. Notice that the log4j configuration file should be in xml format + * @param logConfigFilePath specified log4j configuration file path + * @param log4JResourceFile specified log4j configuration resource file, which will only be respected when logConfigFilePath is null + * @throws ClassNotFoundException + * @throws InstantiationException + * @throws IllegalAccessException + * @throws NoSuchMethodException + * @throws InvocationTargetException + */ + public static void configLog4j(String logConfigFilePath, String log4JResourceFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + Class domconfigurator; + Object domconfiguratorobj; + domconfigurator = Class.forName("org.apache.log4j.xml.DOMConfigurator"); + domconfiguratorobj = domconfigurator.newInstance(); + if (null == logConfigFilePath) { + if (log4JResourceFile != null) { + Method configure = domconfiguratorobj.getClass().getMethod("configure", URL.class); + URL url = LogUtils.class.getClassLoader().getResource(log4JResourceFile); + configure.invoke(domconfiguratorobj, url); + } + } else { + Method configure = domconfiguratorobj.getClass().getMethod("configure", String.class); + configure.invoke(domconfiguratorobj, logConfigFilePath); + } + } + + public static void configLog4j2(String logConfigFilePath, + String log4J2ResourceFile) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Class joranConfigurator = Class.forName("org.apache.logging.log4j.core.config.Configurator"); + Method initialize = joranConfigurator.getDeclaredMethod("initialize", String.class, String.class); + if (null == logConfigFilePath) { + initialize.invoke(joranConfigurator, "log4j2", log4J2ResourceFile); + } else { + initialize.invoke(joranConfigurator, "log4j2", logConfigFilePath); + } + } + + + public static void loadLoggerConfig(String logConfigFilePath, String log4JResourceFile, String log4J2ResourceFile, + String logbackResourceFile) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + ILoggerFactory iLoggerFactory = LoggerFactory.getILoggerFactory(); + Class classType = iLoggerFactory.getClass(); + if (classType.getName().equals("org.slf4j.impl.Log4jLoggerFactory")) { + configLog4j(logConfigFilePath, log4JResourceFile); + } else if (classType.getName().equals("ch.qos.logback.classic.LoggerContext")) { + configLogback(logConfigFilePath, logbackResourceFile, iLoggerFactory); + } + else if (classType.getName().equals("org.apache.logging.slf4j.Log4jLoggerFactory")) { + configLog4j2(logConfigFilePath, log4J2ResourceFile); + } + } + + +} diff --git a/distribution/conf/log4j_tools.xml b/distribution/conf/log4j_tools.xml new file mode 100644 index 00000000000..c21adeceb8a --- /dev/null +++ b/distribution/conf/log4j_tools.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/pom.xml b/tools/pom.xml index 97e5e9c5d00..0540c73a9a5 100644 --- a/tools/pom.xml +++ b/tools/pom.xml @@ -48,14 +48,6 @@ com.alibaba fastjson - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-core - org.apache.commons commons-lang3 diff --git a/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java b/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java index d3342e818dd..35c60ffc510 100644 --- a/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java +++ b/tools/src/main/java/org/apache/rocketmq/tools/command/MQAdminStartup.java @@ -16,10 +16,6 @@ */ package org.apache.rocketmq.tools.command; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.joran.JoranConfigurator; -import ch.qos.logback.core.joran.spi.JoranException; - import java.util.ArrayList; import java.util.List; @@ -28,6 +24,7 @@ import org.apache.commons.cli.PosixParser; import org.apache.rocketmq.common.MQVersion; import org.apache.rocketmq.common.MixAll; +import org.apache.rocketmq.common.utils.LogUtils; import org.apache.rocketmq.remoting.RPCHook; import org.apache.rocketmq.remoting.protocol.RemotingCommand; import org.apache.rocketmq.srvutil.ServerUtil; @@ -72,6 +69,7 @@ import org.apache.rocketmq.tools.command.topic.UpdateOrderConfCommand; import org.apache.rocketmq.tools.command.topic.UpdateTopicPermSubCommand; import org.apache.rocketmq.tools.command.topic.UpdateTopicSubCommand; +import org.slf4j.ILoggerFactory; import org.slf4j.LoggerFactory; public class MQAdminStartup { @@ -89,7 +87,7 @@ public static void main0(String[] args, RPCHook rpcHook) { initCommand(); try { - initLogback(); + initLog(); switch (args.length) { case 0: printHelp(); @@ -195,14 +193,23 @@ public static void initCommand() { initCommand(new QueryConsumeQueueCommand()); } - private static void initLogback() throws JoranException { - String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV)); - - LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); - JoranConfigurator configurator = new JoranConfigurator(); - configurator.setContext(lc); - lc.reset(); - configurator.doConfigure(rocketmqHome + "/conf/logback_tools.xml"); + private static void initLog() { + try { + String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV)); + ILoggerFactory iLoggerFactory = LoggerFactory.getILoggerFactory(); + Class classType = iLoggerFactory.getClass(); + if (classType.getName().equals("org.slf4j.impl.Log4jLoggerFactory")) { + final String logfjConfigPath = rocketmqHome + "/distribution/conf/log4j_tools.xml"; + LogUtils.configLog4j(logfjConfigPath, null); + } else if (classType.getName().equals("ch.qos.logback.classic.LoggerContext")) { + final String logbackConfigPath = rocketmqHome + "/distribution/conf/logback_tools.xml"; + LogUtils.configLogback(logbackConfigPath, null, iLoggerFactory); + } else { + System.out.printf("No Logback or Log4j implementations are detected, ignore dynamical logging config.%n"); + } + } catch (Exception e) { + System.err.println(e); + } } private static void printHelp() {