项目使用spring+dubbo+zookeeper
因为需要跟踪dubbo服务调用方ip,使用在<dubbo:service />接口上加accesslog="true"的方法来记录访问log。
但是发现在使用log4j的项目中是可以的,在使用logback的项目中却不行。access日志的记录是通过AccessLogFilter来实现的,通过debug发现在使用logback的项目中记录log时的Logger对象是Log4jLogger对象。
public class LoggerFactory { private static volatile LoggerAdapter LOGGER_ADAPTER; private static final ConcurrentMap<String, FailsafeLogger> LOGGERS = new ConcurrentHashMap(); private LoggerFactory() { } public static void setLoggerAdapter(String loggerAdapter) { if(loggerAdapter != null && loggerAdapter.length() > 0) { setLoggerAdapter((LoggerAdapter)ExtensionLoader.getExtensionLoader(LoggerAdapter.class).getExtension(loggerAdapter)); } } public static void setLoggerAdapter(LoggerAdapter loggerAdapter) { if(loggerAdapter != null) { Logger logger = loggerAdapter.getLogger(LoggerFactory.class.getName()); logger.info("using logger: " + loggerAdapter.getClass().getName()); LOGGER_ADAPTER = loggerAdapter; Iterator i$ = LOGGERS.entrySet().iterator(); while(i$.hasNext()) { Entry entry = (Entry)i$.next(); ((FailsafeLogger)entry.getValue()).setLogger(LOGGER_ADAPTER.getLogger((String)entry.getKey())); } } } public static Logger getLogger(Class<?> key) { FailsafeLogger logger = (FailsafeLogger)LOGGERS.get(key.getName()); if(logger == null) { LOGGERS.putIfAbsent(key.getName(), new FailsafeLogger(LOGGER_ADAPTER.getLogger(key))); logger = (FailsafeLogger)LOGGERS.get(key.getName()); } return logger; } public static Logger getLogger(String key) { FailsafeLogger logger = (FailsafeLogger)LOGGERS.get(key); if(logger == null) { LOGGERS.putIfAbsent(key, new FailsafeLogger(LOGGER_ADAPTER.getLogger(key))); logger = (FailsafeLogger)LOGGERS.get(key); } return logger; } public static void setLevel(Level level) { LOGGER_ADAPTER.setLevel(level); } public static Level getLevel() { return LOGGER_ADAPTER.getLevel(); } public static File getFile() { return LOGGER_ADAPTER.getFile(); } static { String logger = System.getProperty("dubbo.application.logger"); if("slf4j".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new Slf4jLoggerAdapter())); } else if("jcl".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new JclLoggerAdapter())); } else if("log4j".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new Log4jLoggerAdapter())); } else if("jdk".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new JdkLoggerAdapter())); } else { try { setLoggerAdapter((LoggerAdapter)(new Log4jLoggerAdapter())); } catch (Throwable var6) { try { setLoggerAdapter((LoggerAdapter)(new Slf4jLoggerAdapter())); } catch (Throwable var5) { try { setLoggerAdapter((LoggerAdapter)(new JclLoggerAdapter())); } catch (Throwable var4) { setLoggerAdapter((LoggerAdapter)(new JdkLoggerAdapter())); } } } } } }
进一步了解dubbo的日志系统,dubbo内部的日志输出都是通过LoggerFactory来获取Logger然后进行输出。
Logger接口有JclLogger(commons.logging)、JdkLogger(java.util.logging.Logger)、Log4jLogger、Slf4jLogger几种实现。Logger对象又是通过LoggerAdapter和第三方日志框架进行对接并直接创建,于是又对应几种LoggerAdapter:JclLoggerAdapter、JDKLoggerAdapter、Log4jLoggerAdapter、SLF4JLoggerAdapter。
通过这段代码
static { String logger = System.getProperty("dubbo.application.logger"); if("slf4j".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new Slf4jLoggerAdapter())); } else if("jcl".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new JclLoggerAdapter())); } else if("log4j".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new Log4jLoggerAdapter())); } else if("jdk".equals(logger)) { setLoggerAdapter((LoggerAdapter)(new JdkLoggerAdapter())); } else { try { setLoggerAdapter((LoggerAdapter)(new Log4jLoggerAdapter())); } catch (Throwable var6) { try { setLoggerAdapter((LoggerAdapter)(new Slf4jLoggerAdapter())); } catch (Throwable var5) { try { setLoggerAdapter((LoggerAdapter)(new JclLoggerAdapter())); } catch (Throwable var4) { setLoggerAdapter((LoggerAdapter)(new JdkLoggerAdapter())); } } } } }
可以发现在未指定dubbo.application.logger,也就是默认情况下,dubbo会优先选用log4j,而logback是和slf4j集成的,这就说明了为何在使用logback时没有日志输出了。
解决的办法就是指定dubbo.application.logger参数为slf4j:
1、在jvm启动时添加此参数
-Ddubbo.application.logger=slf4j
2、在LoggerFactory被classloader加载之前通过编码方式指定
System.setProperty("dubbo.application.logger","slf4j");
相关推荐
dubbo资源 dubbo-admin dubbo demo
Dubbo是阿里巴巴开源的分布式服务化治理框架(微服务框架),久经阿里巴巴电商平台的大规模复杂业务的高并发考验,到目前为止Dubbo仍然是开源界中体系最完善的服务化治理框架,因此Dubbo被国内大量的的互联网公司和...
dubbo示例代码dubbo-sample
本套视频从分布式系统的基本概念出发,由浅入深,讲解了RPC原理,Dubbo基本使用,Dubbo高可用场景以及Dubbo原理,涉及了分布式系统中服务注册、服务发现、负载均衡、灰度发布、集群容错、服务降级等核心概念的讲解及...
前段时间排查某问题的时候,想要快速知道某些dubbo接口(三无)的响应结果,但不想启动项目(因为这些项目不是你负责的,不会部署而且超级笨重),也不想新建一个dubbo客户端项目(占地方),也不想开telnet客户端...
incubator-dubbo-dubbo-2.6.1
解决dubbo接口自定义异常的捕捉问题,dubbo消费者可以捕捉到提供者所抛出的自定义异常。
at com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.returnFromResponse(DefaultFuture.java:190) at com.alibaba.dubbo.remoting.exchange.support.DefaultFuture.get(DefaultFuture.java:110) at ...
构建dubbo项目的时候会遇到: Multiple annotations found at this line: - cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'dubbo:application'. - ...
dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.dubbo源码解析2.
【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题【BAT必备】dubbo面试题...
首先,从知识层面对Dubbo有一个了解和认识,请看《Dubbo培训与实战.pptx》,然后把Dubbo用到实际项目中来,请看实例代码《Dubbo实例代码(Sping+Dubbo+Maven).zip》,里面包括dubboDemoProvide和dubboDemoConsumer...
dubbo+zookeeper缓存方案 dubbo+zookeeper缓存方案dubbo+zookeeper缓存方案dubbo+zookeeper缓存方案
spring_dubbo spring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_dubbospring_...
Dubbo是Alibaba开源的分布式服务框架,我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配置就能够实现...
赠送jar包:dubbo-2.5.8.jar; 赠送原API文档:dubbo-2.5.8-javadoc.jar; 赠送源代码:dubbo-2.5.8-sources.jar; 赠送Maven依赖信息文件:dubbo-2.5.8.pom; 包含翻译后的API文档:dubbo-2.5.8-javadoc-API文档-...
dubbo资源包
使用 dubbo 时需要添加 dubbo 支持,否则会报错 。cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'dubbo:application'.
Spring Boot + Nacos + Dubbo + Dubbo Admin,详见:https://blog.csdn.net/z1353095373/article/details/121704570