All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alipay.sofa.common.log.MultiAppLoggerSpaceManager Maven / Gradle / Ivy

There is a newer version: 2.1.1
Show newest version
/*
 * 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 com.alipay.sofa.common.log;

import com.alipay.sofa.common.log.adapter.level.AdapterLevel;
import com.alipay.sofa.common.log.env.LogEnvUtils;
import com.alipay.sofa.common.log.factory.*;
import com.alipay.sofa.common.log.proxy.TemporaryILoggerFactoryPool;
import com.alipay.sofa.common.utils.ClassLoaderUtil;
import com.alipay.sofa.common.utils.ReportUtil;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.alipay.sofa.common.log.Constants.*;

/**
 * Created by [email protected] on 2016/12/7.
 * Updated by [email protected] on 14/04/28.
 */
public class MultiAppLoggerSpaceManager {

    private static final AbstractLoggerSpaceFactory            NOP_LOGGER_FACTORY = new AbstractLoggerSpaceFactory(
                                                                                      "nop") {
                                                                                      @Override
                                                                                      public Logger getLogger(String name) {
                                                                                          return Constants.DEFAULT_LOG;
                                                                                      }
                                                                                  };

    private static final ConcurrentHashMap SPACES_MAP         = new ConcurrentHashMap();

    /**
     * 非必要初始化操作。(如果需要为某些space定义特殊的变量,则必须先初始化该方法)。
     * 

* "非必要",是因为:getLoggerBySpace默认也会执行init操作; *

* 使用 {@link MultiAppLoggerSpaceManager} API 建议一定要执行初始化操作即调用这个方法 * * @param props 替换log xml中占位符,如果与 System.props 重复定义,优先以 System.props 配置为准; */ public static void init(String spaceName, Map props) { init(new SpaceId(spaceName), props); } /** * 非必要初始化操作。(如果需要为某些space定义特殊的变量,则必须先初始化该方法)。 *

* "非必要",是因为:getLoggerBySpace默认也会执行init操作; *

* 使用 {@link MultiAppLoggerSpaceManager} API 建议一定要执行初始化操作即调用这个方法 */ public static void init(SpaceId spaceId, Map props) { if (isSpaceInitialized(spaceId)) { throw new IllegalStateException("Logger Space:" + spaceId.toString() + " is already initialized!"); } synchronized (MultiAppLoggerSpaceManager.class) { if (isSpaceInitialized(spaceId)) { throw new IllegalStateException("Logger Space:" + spaceId.toString() + " is already initialized!"); } doInit(spaceId, props); } ReportUtil.reportDebug("Logger Space:{" + spaceId.toString() + "} init ok."); } static void doInit(String spaceName, Map props) { doInit(new SpaceId(spaceName), props); } static void doInit(SpaceId spaceId, Map props) { SpaceInfo spaceInfo = new SpaceInfo(); //以首次的为准; SPACES_MAP.putIfAbsent(spaceId, spaceInfo); if (props != null) { spaceInfo.putAll(props); } } /** * 从 spaceName 的空间里寻找logger对象(而且这些 logger 是从该 spaceName 下的日志实现配置中解析而来) * * @param name loggerName * @param spaceName 独立的loggers空间,比如"com.alipay.sofa.rpc"; * @return org.slf4j.Logger; */ public static Logger getLoggerBySpace(String name, String spaceName) { ClassLoader callerClassLoader = ClassLoaderUtil.getCallerClassLoader(); return getLoggerBySpace(name, new SpaceId(spaceName), callerClassLoader); } /** * 从 spaceName 的空间里寻找logger对象(而且这些 logger 是从该 spaceName 下的日志实现配置中解析而来) * * @param name loggerName * @param spaceId 独立的loggers空间 * @return org.slf4j.Logger; */ public static Logger getLoggerBySpace(String name, SpaceId spaceId) { ClassLoader callerClassLoader = ClassLoaderUtil.getCallerClassLoader(); return getLoggerBySpace(name, spaceId, callerClassLoader); } /*** * 更新日志级别,屏蔽底层差异 * @param loggerName 要更新的日志名字 * @param spaceName 日志对应的空间名称 * @param adapterLevel 要更新的日志级别 * @return 更新级别后的日志, 与com.alipay.sofa.common.log.MultiAppLoggerSpaceManager#getLoggerBySpace(java.lang.String, java.lang.String) 返回的同一个日志 */ public static Logger setLoggerLevel(String loggerName, String spaceName, AdapterLevel adapterLevel) { return setLoggerLevel(loggerName, new SpaceId(spaceName), adapterLevel); } /*** * 更新日志级别,屏蔽底层差异 * @param loggerName 要更新的日志名字 * @param spaceId 日志对应的空间名称 * @param adapterLevel 要更新的日志级别 * @return 更新级别后的日志, 与com.alipay.sofa.common.log.MultiAppLoggerSpaceManager#getLoggerBySpace(java.lang.String, java.lang.String) 返回的同一个日志 */ public static Logger setLoggerLevel(String loggerName, SpaceId spaceId, AdapterLevel adapterLevel) { ClassLoader callerClassLoader = ClassLoaderUtil.getCallerClassLoader(); AbstractLoggerSpaceFactory abstractLoggerSpaceFactory = getILoggerFactoryBySpaceName( spaceId, callerClassLoader); try { abstractLoggerSpaceFactory.setLevel(loggerName, adapterLevel); } catch (Exception e) { ReportUtil.reportError("SetLoggerLevel Error : ", e); } return abstractLoggerSpaceFactory.getLogger(loggerName); } /** * 从 spaceName 的空间里寻找logger对象(而且这些 logger 是从该 spaceName 下的日志实现配置中解析而来) * * @param name loggerName * @param spaceName 独立的loggers空间,比如"com.alipay.sofa.rpc"; * @param spaceClassloader 该空间下独立的类加载器;(建议就是 APPClassloader 即可) * @return org.slf4j.Logger; */ public static Logger getLoggerBySpace(String name, String spaceName, ClassLoader spaceClassloader) { return getLoggerBySpace(name, new SpaceId(spaceName), spaceClassloader); } /** * 从 spaceName 的空间里寻找logger对象(而且这些 logger 是从该 spaceName 下的日志实现配置中解析而来) * * @param name loggerName * @param spaceId 独立的loggers空间 * @param spaceClassloader 该空间下独立的类加载器;(建议就是 APPClassloader 即可) * @return org.slf4j.Logger; */ public static Logger getLoggerBySpace(String name, SpaceId spaceId, ClassLoader spaceClassloader) { AbstractLoggerSpaceFactory abstractLoggerSpaceFactory = getILoggerFactoryBySpaceName( spaceId, spaceClassloader); return abstractLoggerSpaceFactory.getLogger(name); } /*** * 根据 spaceName 在日志空间里移除指定 spaceName 的 ILoggerFactory * * @param spaceName 指定的日志空间名称 * @return 被移除的 ILoggerFactory;不存在指定的 spaceName,则返回 null */ public static ILoggerFactory removeILoggerFactoryBySpaceName(String spaceName) { return removeILoggerFactoryBySpaceId(new SpaceId(spaceName)); } /*** * 根据 spaceId 在日志空间里移除指定 spaceName 的 ILoggerFactory * * @param spaceId 指定的日志空间名称 * @return 被移除的 ILoggerFactory;不存在指定的 spaceName,则返回 null */ public static ILoggerFactory removeILoggerFactoryBySpaceId(SpaceId spaceId) { if (spaceId == null) { return null; } SpaceInfo spaceInfo = SPACES_MAP.get(spaceId); if (isSpaceILoggerFactoryExisted(spaceId)) { AbstractLoggerSpaceFactory iLoggeriFactory = spaceInfo.getAbstractLoggerSpaceFactory(); spaceInfo.setAbstractLoggerSpaceFactory(null); Logger rootLogger = iLoggeriFactory.getLogger(Logger.ROOT_LOGGER_NAME); rootLogger.warn("Log Space Name[" + spaceId.toString() + "] is Removed from Current Log Space Manager!"); return iLoggeriFactory; } return null; } private static AbstractLoggerSpaceFactory getILoggerFactoryBySpaceName(SpaceId spaceId, ClassLoader spaceClassloader) { //该判断,线程安全不是必须的(最多产生个TemporaryILoggerFactory实例,而且[未初始化]应该基本只发生在启动场景,此时也就基本就是单一线程),以便减少同步开销 if (!isSpaceInitialized(spaceId)) { //temporary factory, and cache support return TemporaryILoggerFactoryPool.get(spaceId, spaceClassloader); } AbstractLoggerSpaceFactory iLoggerFactory = NOP_LOGGER_FACTORY; SpaceInfo spaceInfo = SPACES_MAP.get(spaceId); if (!isSpaceILoggerFactoryExisted(spaceId)) { synchronized (MultiAppLoggerSpaceManager.class) { if (!isSpaceILoggerFactoryExisted(spaceId)) { iLoggerFactory = createILoggerFactory(spaceId, spaceClassloader); spaceInfo.setAbstractLoggerSpaceFactory(iLoggerFactory); } } } else { iLoggerFactory = spaceInfo.getAbstractLoggerSpaceFactory(); } return iLoggerFactory; } /** * 用于并发场景非严格判断space是否init用;该场景中不和初始化场景锁同步,也就是不保证并发时严格判断正确; * * @param spaceName * @return */ public static boolean isSpaceInitialized(String spaceName) { return isSpaceInitialized(new SpaceId(spaceName)); } /** * 用于并发场景非严格判断space是否init用;该场景中不和初始化场景锁同步,也就是不保证并发时严格判断正确; * * @param spaceId * @return */ public static boolean isSpaceInitialized(SpaceId spaceId) { return SPACES_MAP.get(spaceId) != null; } /** * @param spaceName * @return * @NotThreadSafe 该场景中不要求线程安全; */ private static boolean isSpaceILoggerFactoryExisted(String spaceName) { return isSpaceILoggerFactoryExisted(new SpaceId(spaceName)); } /** * @param spaceId * @return * @NotThreadSafe 该场景中不要求线程安全; */ private static boolean isSpaceILoggerFactoryExisted(SpaceId spaceId) { return isSpaceInitialized(spaceId) && SPACES_MAP.get(spaceId).getAbstractLoggerSpaceFactory() != null; } private static AbstractLoggerSpaceFactory createILoggerFactory(SpaceId spaceId, ClassLoader spaceClassloader) { if (System.getProperty(SOFA_MIDDLEWARE_LOG_DISABLE_PROP_KEY) != null && Boolean.TRUE.toString().equalsIgnoreCase( System.getProperty(SOFA_MIDDLEWARE_LOG_DISABLE_PROP_KEY))) { ReportUtil.reportWarn("Sofa-Middleware-Log is disabled! -D" + SOFA_MIDDLEWARE_LOG_DISABLE_PROP_KEY + "=true"); return NOP_LOGGER_FACTORY; } SpaceInfo spaceInfo = SPACES_MAP.get(spaceId); // set global system properties spaceInfo.putAll(LogEnvUtils.processGlobalSystemLogProperties()); // do create try { if (LogEnvUtils.isLogbackUsable(spaceClassloader)) { String isLogbackDisable = System .getProperty(LOGBACK_MIDDLEWARE_LOG_DISABLE_PROP_KEY); if (Boolean.TRUE.toString().equalsIgnoreCase(isLogbackDisable)) { ReportUtil.reportWarn("Logback-Sofa-Middleware-Log is disabled! -D" + LOGBACK_MIDDLEWARE_LOG_DISABLE_PROP_KEY + "=true"); } else { ReportUtil.reportDebug("Actual binding is of type [ " + spaceId.toString() + " Logback ]"); LoggerSpaceFactoryBuilder loggerSpaceFactory4LogbackBuilder = new LoggerSpaceFactory4LogbackBuilder( spaceId, spaceInfo); return loggerSpaceFactory4LogbackBuilder.build(spaceId.getSpaceName(), spaceClassloader); } } if (LogEnvUtils.isLog4j2Usable(spaceClassloader)) { String isLog4j2Disable = System.getProperty(LOG4J2_MIDDLEWARE_LOG_DISABLE_PROP_KEY); if (Boolean.TRUE.toString().equalsIgnoreCase(isLog4j2Disable)) { ReportUtil.reportWarn("Log4j2-Sofa-Middleware-Log is disabled! -D" + LOG4J2_MIDDLEWARE_LOG_DISABLE_PROP_KEY + "=true"); } else { ReportUtil.reportDebug("Actual binding is of type [ " + spaceId.toString() + " Log4j2 ]"); LoggerSpaceFactoryBuilder loggerSpaceFactory4Log4j2Builder = new LoggerSpaceFactory4Log4j2Builder( spaceId, spaceInfo); return loggerSpaceFactory4Log4j2Builder.build(spaceId.getSpaceName(), spaceClassloader); } } if (LogEnvUtils.isLog4jUsable(spaceClassloader)) { String isLog4jDisable = System.getProperty(LOG4J_MIDDLEWARE_LOG_DISABLE_PROP_KEY); if (Boolean.TRUE.toString().equalsIgnoreCase(isLog4jDisable)) { ReportUtil.reportWarn("Log4j-Sofa-Middleware-Log is disabled! -D" + LOG4J_MIDDLEWARE_LOG_DISABLE_PROP_KEY + "=true"); } else { ReportUtil.reportDebug("Actual binding is of type [ " + spaceId.toString() + " Log4j ]"); LoggerSpaceFactoryBuilder loggerSpaceFactory4Log4jBuilder = new LoggerSpaceFactory4Log4jBuilder( spaceId, spaceInfo); return loggerSpaceFactory4Log4jBuilder.build(spaceId.getSpaceName(), spaceClassloader); } } if (LogEnvUtils.isCommonsLoggingUsable(spaceClassloader)) { //此种情形:commons-logging 桥接到 log4j 实现,默认日志实现仍然是 log4j String isLog4jDisable = System .getProperty(LOG4J_COMMONS_LOGGING_MIDDLEWARE_LOG_DISABLE_PROP_KEY); if (Boolean.TRUE.toString().equalsIgnoreCase(isLog4jDisable)) { ReportUtil .reportWarn("Log4j-Sofa-Middleware-Log(But adapter commons-logging to slf4j) is disabled! -D" + LOG4J_COMMONS_LOGGING_MIDDLEWARE_LOG_DISABLE_PROP_KEY + "=true"); } else { ReportUtil.reportDebug("Actual binding is of type [ " + spaceId.toString() + " Log4j (Adapter commons-logging to slf4j)]"); LoggerSpaceFactoryBuilder loggerSpaceFactory4Log4jBuilder = new LoggerSpaceFactory4CommonsLoggingBuilder( spaceId, spaceInfo); return loggerSpaceFactory4Log4jBuilder.build(spaceId.getSpaceName(), spaceClassloader); } } ReportUtil.reportWarn("No log util is usable, Default app logger will be used."); } catch (Throwable e) { ReportUtil.reportError("Build ILoggerFactory error! Default app logger will be used.", e); } return NOP_LOGGER_FACTORY; } public static Map getSpacesMap() { return Collections.unmodifiableMap(SPACES_MAP); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy