写了 Spring AOP 实现自定义注解,打印日志之后,感觉在调用第三方 dubbo 接口的时候,依然会有同样的问题,然后看了一下 dubbo 的官方文档,决定下一个 filter,实现 dubbo 接口的日志拦截,以下是自己完的一个小例子,同样也是供需要的同学参考。

  1. filter 具体实现如下:
package cn.bridgeli.demo.filter;

import com.alibaba.dubbo.rpc.Filter;  
import com.alibaba.dubbo.rpc.Invocation;  
import com.alibaba.dubbo.rpc.Invoker;  
import com.alibaba.dubbo.rpc.Result;  
import com.alibaba.dubbo.rpc.RpcException;  
import com.alibaba.dubbo.rpc.service.GenericService;  
import org.apache.commons.lang3.StringUtils;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;

/**  
 * @author bridgeli  
 */  
public class DubboServiceFilter implements Filter {

  private static final Logger LOGGER = LoggerFactory.getLogger(DubboServiceFilter.class);

  @Override  
  public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {  
    // 打印入参日志  
    String className = invocation.getInvoker().getInterface().getName();  
    String methodName = invocation.getMethodName();  
    String arguments = StringUtils.join(invocation.getArguments(), ";");  
    LOGGER.info("调用 dubbo 服务接口: " + className + "#" + methodName + ",参数:" + arguments);  
    // 开始时间  
    long startTime = System.currentTimeMillis();  
    //执行接口调用逻辑  
    Result result = invoker.invoke(invocation);  
    //调用耗时  
    long elapsed = System.currentTimeMillis() - startTime;  
    //如果发生异常 则打印异常日志  
    if (result.hasException() && invoker.getInterface() != GenericService.class) {  
      LOGGER.error("dubbo执行异常,接口:" + className + "#" + methodName + ",参数:" + arguments, result.getException());  
    } else {  
      // 打印响应日志  
      LOGGER.info("dubbo服务响应成功:" + className + "#" + methodName + ",参数:" + arguments + ",返回值:" + result.getValue() + ",用时:" + elapsed);  
    }  
    //返回结果响应结果  
    return result;  
  }  
}
  1. 在/src/main/resources/META-INF/dubbo目录下新增纯文本文件 com.alibaba.dubbo.rpc.Filter 内容为:
dubboServiceFilter=cn.bridgeli.demo.filter.DubboServiceFilter
  1. 最后在服务提供者配置文件中添加配置使拦截器生效:
<dubbo:provider filter="dubboServiceFilter"/>

或者

<dubbo:service filter="dubboServiceFilter"/>

这样即可实现。不过需要说明的是,因为我们项目用的 dubbo 版本是:2.5.3,所以包名和配置名还都是:com.alibaba.dubbo,而最新的版本阿里已经捐献给 apache,所以都变成了:org.apache.dubbo。最后的最后想说的是,具体大家可以参考 dubbo 的官方文档,个人认为 dubbo 的官方文档写的是极好的,各种通俗易懂。

参考文档:http://dubbo.apache.org/en-us/docs/dev/impls/filter.html