Dubbo 日志组件

Dubbo 日志组件

common.logger 包下.

dubbo 可以配置选用哪种第三方日志框架.

实现

protected static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);

上面代码做了两件事情
1.第一次会触发 LoggerFactory 类的加载,触发 static 块 里的逻辑;
2.获取logger对象

LoggerFactory 静态代码块逻辑

1.加载 LoggerFactory 和 第三方 Logger
触发 LoggerFactory 加载, 执行静态代码块;
读取系统配置的 logger, 若没配置, 则按照顺序实例化 dubbo logger 的 adapter 类.
adapter 一定能实例化成功,因为构造方法里捕获了异常.
通过 LoggerAdapter 获取 对应的 Logger,此时若依赖的第三方 Logger 不存在,则会失败.
若失败,则再尝试加载其他的第三方 Logger.

static {
    String logger = System.getProperty("dubbo.application.logger", ""); // 获取配置的logger
    switch (logger) {
        case "slf4j":
            setLoggerAdapter(new Slf4jLoggerAdapter());
            break;
        case "jcl":
            setLoggerAdapter(new JclLoggerAdapter());
            break;
        case "log4j":
            setLoggerAdapter(new Log4jLoggerAdapter());
            break;
        case "jdk":
            setLoggerAdapter(new JdkLoggerAdapter());
            break;
        case "log4j2":
            setLoggerAdapter(new Log4j2LoggerAdapter());
            break;
        default: // 没配置的话走这里
            List<Class<? extends LoggerAdapter>> candidates = Arrays.asList( // dubbo的各个adapter实现类
                    Log4jLoggerAdapter.class,
                    Slf4jLoggerAdapter.class,
                    Log4j2LoggerAdapter.class,
                    JclLoggerAdapter.class,
                    JdkLoggerAdapter.class
            );
            for (Class<? extends LoggerAdapter> clazz : candidates) {
                try {
                    setLoggerAdapter(clazz.newInstance()); // 1.实例化LoggerAdapter;2.获取第三方Logger,可能会失败,失败尝试下一个
                    break;
                } catch (Throwable ignored) {
                }
            }
    }
}
public static void setLoggerAdapter(LoggerAdapter loggerAdapter) {
    if (loggerAdapter != null) {
        Logger logger = loggerAdapter.getLogger(LoggerFactory.class.getName()); // 通过 adapter 获取 dubbo logger 对象,里面封装了第三方 logger.若获取失败,调用的地方会尝试加载下一个第三方日志组件.
        logger.info("using logger: " + loggerAdapter.getClass().getName());
        LoggerFactory.LOGGER_ADAPTER = loggerAdapter; // 给 LOGGER_ADAPTER 赋值 
        for (Map.Entry<String, FailsafeLogger> entry : LOGGERS.entrySet()) {
            entry.getValue().setLogger(LOGGER_ADAPTER.getLogger(entry.getKey()));
        }
    }
}
获取 Logger 实例

2.获取Logger实例
先从缓存里获取,取到返回;
取不到,则通过 LoggerAdapter 获取 Logger 并缓存.

public static Logger getLogger(Class<?> key) {
    return LOGGERS.computeIfAbsent(key.getName(), name -> new FailsafeLogger(LOGGER_ADAPTER.getLogger(name))); // 根据类名获取Logger.若获取不到则创建并缓存
}
  • 相当于一个类对应一个Logger对象,如何保证打日志线程安全.

总结

类结构

每种日志框架都提供一个对应的 Logger 类和 LoggerApapter 类. 比如 Log4jLogger, Log4jLoggerAdapter.

Logger 类主要用于对接第三方的api,里面对info(),error()等打印日志的方法进行封装,调用第三方api实现.

Log4jLogger 通过 getLogger() 方法 获取 上面 dubbo 里的 Logger 类对象.

dubbo 日志框架 是什么

为什么需要 dubbo 日志框架

方便对接第三方日志框架,和应用日志保持一致.

dubbo 日志框架 怎么实现

当通过 LoggerFactory.getLogger(xxx.class) 获取日志对象时,做了两件事:
1.第一次会触发 LoggerFactory 类的加载,触发 static 块 里的逻辑;
2.获取logger对象

1.加载 LoggerFactory 和 第三方 Logger
触发 LoggerFactory 加载, 执行静态代码块;
读取系统配置的 logger, 若没配置, 则按照顺序实例化 dubbo logger 的 adapter 类.
adapter 一定能实例化成功,因为构造方法里捕获了异常.
通过 LoggerAdapter 获取 对应的 Logger,此时若依赖的第三方 Logger 不存在,则会失败.
若失败,则再尝试加载其他的第三方 Logger.

2.获取Logger实例
先从缓存里获取,取到返回;
取不到,则通过 LoggerAdapter 获取 Logger 并缓存.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FlyingZCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值