springboot工程,想要记录dubbo服务provider和consumer的日志。
1.首先在application.properties添加配置
dubbo.provider.filter=dubboProviderLogFilter
dubbo.consumer.filter=dubboConsumerLogFilter
2.新增文件com.alibaba.dubbo.rpc.Filter
dubboProviderLogFilter=com.test.DubboProviderLogFilter
dubboConsumerLogFilter=com.test.DubboConsumerLogFilter
3.新增拦截类,记录日志,其中traceid的设置,是为了追踪dubbo服务调用链
@Activate(group = Constants.PROVIDER, value = "dubboProviderLogFilter") public class DubboProviderLogFilter implements Filter { private static final Logger PROVIDER_LOG = LoggerFactory.getLogger("provider"); private static final Logger TIME_LOG = LoggerFactory.getLogger("time"); private static final Logger COMMON_LOG = LoggerFactory.getLogger(DubboProviderLogFilter.class); @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { setTraceId(); Result result = null; long start = System.currentTimeMillis(); String args = JSON.toJSONString(invocation.getArguments()); try { result = invoker.invoke(invocation); } finally { try { long costTime = System.currentTimeMillis() - start; String interfaceName = invoker.getInterface().getCanonicalName(); String method = interfaceName + "." + invocation.getMethodName(); if (null != result && null != result.getException()) { PROVIDER_LOG.error("invoke: {} ,param:{},spend:{}ms,exception:", method, args, costTime, result .getException()); } else { String resultStr = null == result ? "" : JSON.toJSONString(result.getValue()); PROVIDER_LOG.info("invoke: {} ,param:{}, result:{},spend: {} ms", method, args, resultStr,costTime); } if (costTime > 200) { TIME_LOG.warn("invoke: {} ,param:{}, spend: {} ms", method, args, costTime); } } catch (Exception e) { COMMON_LOG.error("dubbo log exception:", e); } finally {
MDC.remove(SysConstants.TRACE_ID);//调用链结束,需要移除traceid } } return result; } /** * Logback全局traceId添加 */ private void setTraceId() { try {
//获取dubbo隐式参数,由dubbo调用链上之前的服务设置,值为traceId(比如订单系统,调用支付系统的dubbo服务,订单系统设置好隐式参数traceId,支付系统此时可由此方法获取) String traceId = RpcContext.getContext().getAttachment(SysConstants.TRACE_ID);
//如果调用方未设置traceid,在自己生成,将之设置到logback上下文中 if (StringUtils.isBlank(traceId)) { traceId = TraceIDGenerator.generate();
//将traceid设置到logback上下文中 MDC.put(SysConstants.TRACE_ID, traceId); } else {
//如果调用方已经设置过traceID,取出并设置到logback上下文中 MDC.put(SysConstants.TRACE_ID, traceId); } } catch (Exception e) { COMMON_LOG.warn("set traceId fail"); }
@Activate(group = Constants.CONSUMER, value = "dubboConsumerLogFilter") public class DubboConsumerLogFilter implements Filter { private static final Logger CONSUMER_LOG = LoggerFactory.getLogger("consumer"); private static final Logger TIME_LOG = LoggerFactory.getLogger("time"); private static final Logger COMMON_LOG = LoggerFactory.getLogger(DubboConsumerLogFilter.class); @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { Result result = null; long start = System.currentTimeMillis(); try { setTraceId(); result = invoker.invoke(invocation); } finally { try { long costTime = System.currentTimeMillis() - start; String interfaceName = invoker.getInterface().getCanonicalName(); String method = interfaceName + "." + invocation.getMethodName(); String args = JSON.toJSONString(invocation.getArguments()); if (null != result && null != result.getException()) { CONSUMER_LOG.error("invoke: {} ,param:{},spend:{}ms,exception:", method, args, costTime, result .getException()); } else { String resultStr = null == result ? "" : JSON.toJSONString(result.getValue()); CONSUMER_LOG.info("invoke: {} ,param:{}, result:{},spend: {} ms", method, args, resultStr, costTime); } if (costTime > 200) { TIME_LOG.warn("invoke: {} ,param:{}, spend: {} ms", method, args, costTime); } } catch (Exception e) { COMMON_LOG.error("dubbo log exception:", e); } } return result; } /** * Dubbo链隐式参数增加traceId */ private void setTraceId() { try {
//consumer日志中traceid肯定已经被设置过(在provider中被设置过) String traceId = MDC.get(SysConstants.TRACE_ID); if (StringUtils.isNotBlank(traceId)) {
RpcContext.getContext().setAttachment(SysConstants.TRACE_ID, traceId);//设置隐式参数,给下游记录日志使用 } } catch (Exception e) { COMMON_LOG.warn("set traceId fail"); } } }