目前的项目,远程服务调用所有都是基于dubbo,有的是部门内部互相调用,有的是调用其余部门的服务。因为业务里面涉及到远程调用服务的地方比较多,目前调用每一个服务的时候都要手动写打印入参、响应和异常,比较麻烦。html
如今对这块进行优化,目的是实现自动打印入参、响应和异常,从而避免每一个服务都要手动写重复的代码。spring
新建包apache
XXX.solid.filter //以filter结尾json
新建类-自定义服务消费者日志拦截器springboot
package XXX.solid.filter; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.extension.Activate; import com.alibaba.dubbo.rpc.*; import com.alibaba.dubbo.rpc.service.GenericService; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; /** * 服务消费者日志拦截器,做用是打印dubbo调用的入参和响应 * @author gongzhihao */ @Slf4j @Activate(group = {Constants.CONSUMER}) public class LogDubboConsumerFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { //打印入参 log.info("dubbo入参,InterfaceName={},MethodName={},Parameter={}", invocation.getInvoker().getInterface().getName(), invocation.getMethodName(), invocation.getArguments()); //开始时间 long startTime = System.currentTimeMillis(); //执行接口调用逻辑 Result result = invoker.invoke(invocation); //调用耗时 long elapsed = System.currentTimeMillis() - startTime; //若是发生异常,则打印异常日志 if (result.hasException() && invoker.getInterface() != GenericService.class) { // log.error("dubbo执行异常: ", result.getException()); log.error("dubbo执行异常!!!"); } else { log.info("dubbo响应,InterfaceName={},MethodName={},Resposne={},SpendTime={} ms", invocation.getInvoker().getInterface().getName(), invocation.getMethodName(), JSON.toJSONString(new Object[]{result.getValue()}), elapsed); } //返回结果响应数据 return result; } }
新建类-自定义服务提供者日志拦截器app
package XXX.solid.filter; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.extension.Activate; import com.alibaba.dubbo.rpc.*; import com.alibaba.dubbo.rpc.service.GenericService; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; /** * 服务提供者日志拦截器,做用是打印dubbo调用的入参和响应 * @author gongzhihao */ @Slf4j @Activate(group = { Constants.PROVIDER }) public class LogDubboProviderFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { //打印入参 log.info("dubbo入参,InterfaceName={},MethodName={},Parameter={}", invocation.getInvoker().getInterface().getName(), invocation.getMethodName(), invocation.getArguments()); //开始时间 long startTime = System.currentTimeMillis(); //执行接口调用逻辑 Result result = invoker.invoke(invocation); //调用耗时 long elapsed = System.currentTimeMillis() - startTime; //若是发生异常,则打印异常日志 if (result.hasException() && invoker.getInterface() != GenericService.class) { // log.error("dubbo响应,dubbo执行异常: ", result.getException()); log.error("dubbo执行异常!!!"); } else { log.info("dubbo响应,InterfaceName={},MethodName={},Response={},SpendTime={} ms", invocation.getInvoker().getInterface().getName(), invocation.getMethodName(), JSON.toJSONString(new Object[]{result.getValue()}), elapsed); } //返回结果响应数据 return result; } }
新建目录和文件:META-INF/dubbo/org.apache.dubbo.rpc.Filteride
添加配置内容:优化
logDubboProviderFilter=XXX.solid.filter.LogDubboProviderFilter logDubboConsumerFilter=XXX.solid.filter.LogDubboConsumerFilter
注:若是不生效,配置如下内容日志
1.springboot项目code
application.properties
dubbo.provider.filter=logDubboProviderFilter dubbo.consumer.filter=logDubboConsumerFilter
2.spring项目
<dubbo:provider filter="logDubboProviderFilter"/>
<dubbo:consumer retries="0" timeout="60000" loadbalance="roundrobin" actives="0"
validation="false" filter="logDubboConsumerFilter"/>
自带的accesslog配置,只打印入参,且只在服务提供者打印入参。
若是有accesslog配置,则去掉,避免打印重复日志。
1.dubbo有自带的异常拦截器,使用默认的自带的异常拦截器便可,不作改动。
2.若是须要在异常日志里打印特殊信息(好比,定位是哪一笔订单异常),也能够捕获异常,而且打印日志。