前言

上一篇文章 Spring aop+自定义注解统一记录用户行为日志 记录了 web层中通过自定义注解配合Spring aop自动记录用户行为日志的过程。那么按照分布式架构中Dubbo服务层的调用过程是否也可以实现统一记录日志?自定义日志拦截器可以实现这个需求。

需求场景

在使用Dubbo搭建的分布式项目中,服务层代码调用是这样的:

     @GetMapping(value = "/info")
2    public BaseResult userInfo() {
3        //rpc远程调用用户服务
4        BaseResult result = mUserService.userInfo();
6        return result;
7    }

这里的用户服务位于另外一个服务进程,由服务提供者暴露出来,让web层远程调用,需要记录服务结果的调用过程,便于跟踪定位bug.

自定义日志拦截器

翻看下Dubbo官方文档,可以看到如下内容:

简要说明:

  • Dubbo 中所有的拦截器全部继承自org.apache.dubbo.rpc.Filter接口,我们自己也可以自行扩展,只要继承该接口即可.
  • 用户自定义 filter 默认在内置 filter 之后执行

新增 DubboServiceFilter 拦截器如下:

public class DubboServiceFilter implements Filter {private static final Logger LOGGER = LoggerFactory.getLogger(DubboServiceFilter.class);@Overridepublic Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {//外部日志开关默认关闭String logSwitch = StringUtils.equals(RedisUtil.get(BaseConstants.CACHE_SERVICE_LOG_SWITCH), BaseConstants.YES) ? BaseConstants.YES : BaseConstants.NO;if (StringUtils.equals(BaseConstants.YES, logSwitch)) {//打印入参日志DubboServiceRequest serviceRequest = new DubboServiceRequest();serviceRequest.setInterfaceName(invocation.getInvoker().getInterface().getName());serviceRequest.setMethodName(invocation.getMethodName());serviceRequest.setArgs(invocation.getArguments());LOGGER.info("dubbo服务接口入参: " + JSON.toJSONString(serviceRequest));}//开始时间long startTime = System.currentTimeMillis();//执行接口调用逻辑Result result = invoker.invoke(invocation);//调用耗时long elapsed = System.currentTimeMillis() - startTime;//如果发生异常 则打印异常日志if (result.hasException() && invoker.getInterface() != GenericService.class) {LOGGER.error("dubbo执行异常: ", result.getException());} else {if (StringUtils.equals(BaseConstants.YES, logSwitch)) {//打印响应日志DubboServiceResponse serviceResponse = new DubboServiceResponse();serviceResponse.setMethodName(invocation.getMethodName());serviceResponse.setInterfaceName(invocation.getInvoker().getInterface().getName());serviceResponse.setArgs(invocation.getArguments());serviceResponse.setResult(new Object[]{result.getValue()});serviceResponse.setSpendTime(elapsed);LOGGER.info("dubbo服务响应成功,返回数据: " + JSON.toJSONString(serviceResponse));}}//返回结果响应结果return result;}
}

代码中对应的实体bean如下:

入参实体:

/*** @program: easywits* @description:Dubbo服务请求入参实体* @author: zhangshaolin* @create: 2019-01-08 20:35**/
@Data
public class DubboServiceRequest implements Serializable{private static final long serialVersionUID = 7127824956842786618L;/*** 接口名*/private String interfaceName;/*** 方法名*/private String methodName;/*** 参数*/private Object[] args;
}

响应实体:

/*** @program: easywits* @description: Dubbo服务响应结果实体* @author: zhangshaolin* @create: 2019-01-08 20:36**/
@Data
public class DubboServiceResponse implements Serializable{private static final long serialVersionUID = -2531169660859647737L;/*** 接口名*/private String interfaceName;/*** 方法名*/private String methodName;/*** 参数*/private Object[] args;/*** 返回结果*/private Object result;/*** 调用耗时(毫秒)*/private long spendTime;
}

/src/main/resources/META-INF/dubbo目录下新增纯文本文件org.apache.dubbo.rpc.Filter 内容为:

dubboServiceFilter=com.easywits.common.filter.DubboServiceFilter
  • 键值对形式,键随便起个名字
  • 值为DubboServiceFilter拦截器的完整包名.

最后在服务提供者配置文件中添加配置使拦截器生效:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"...省略部分代码"><!--服务提供方应用信息,用于计算依赖关系--><dubbo:application name="easywits-upms-rpc-service"/><!--用dubbo协议在20881端口暴露服务--><dubbo:protocol name="dubbo" port="20881" payload="52428800"/><!--自定义服务层过滤器,值为上述步骤文本文件中的键--><dubbo:provider filter="dubboServiceFilter"/>....省略部分服务配置
</beans>

验证结果

抓一下我们业务中的部分日志信息看下效果,如下图:

可以清楚地看到Dubbo服务接口调用的请求参数信息,以及最终的响应结果信息,便于定位线上问题。

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

最后

记录一个比较简单的具体实用场景,后续会不定期更新更多的实用场景,欢迎关注公众号【张少林同学】!

Dubbo自定义日志拦截器相关推荐

  1. Dubbo自定义日志拦截器 1

    前言 上一篇文章 Spring aop+自定义注解统一记录用户行为日志 记录了 web层中通过自定义注解配合Spring aop自动记录用户行为日志的过程.那么按照分布式架构中Dubbo服务层的调用过 ...

  2. 自定义日志_Dubbo自定义日志拦截器源码分析

    需求场景 在使用Dubbo搭建的分布式项目中,服务层代码调用是这样的: @GetMapping(value = "/info")2 public BaseResult userIn ...

  3. WebServices中使用cxf开发日志拦截器以及自定义拦截器

    首先下载一个cxf实例,里面包含cxf的jar包.我下的是apache-cxf-2.5.9 1.为什么要设置拦截器? 为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截 ...

  4. 自定义Flume拦截器,并将收集的日志存储到Kafka中(案例)

    1.引入POM文件 如果想调用Flume,需要引入flume相关的jar包依赖,jar包依赖如下: <?xml version="1.0" encoding="UT ...

  5. 好用的自定义Okhttp日志拦截器

    Okhttp中自带的日志拦截器 HttpLoggingInterceptor 实在是不好用,日志太多太乱,所以想要有好看.简洁的日志打印就要靠自定义了,下面分享我参照 HttpLoggingInter ...

  6. 【WebService】CXF拦截器的设置以及自定义CXF拦截器

    欢迎关注我新搭建的博客:http://www.itcodai.com/ WebService系列文章: [WebService]带你走进webservice的世界 [WebService]自定义Web ...

  7. java创建请求拦截器_80.简单Retrofit+RxJava+日志拦截器结合使用

    1.需要使用到的依赖如下(Retrofit\RxJava\RecyclerView\日志拦截器) //only Retrofit(只用Retrofit联网) implementation 'io.re ...

  8. springboot整合shiro和session的详细过程和自定义登录拦截器

    文章目录 1.shiro依赖 2.shiro配置 shiro过滤器配置: 关联自定义的其他管理器 自定义会话工厂: 3.登陆时记录用户信息 4.shiro一些工具类的学习 5.自定义登录拦截器 shi ...

  9. Mybatis自定义SQL拦截器

    本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...

最新文章

  1. linux服务器性能监控命令汇总(一)
  2. 实时SLAM的未来及深度学习与SLAM对比
  3. linux系统无线怎么设置密码,LINUX终端下配置WPA2加密无线网络
  4. UVA - 11572
  5. bzoj 2194 快速傅立叶之二
  6. 无法卸载 Mac 上的磁盘时该怎么办?
  7. html下拉菜单的某个值被选定,使用JavaScript在下拉列表中获取选定的值?
  8. MyCat之全局表和ER表
  9. flash声音播放-Sound
  10. 2万字用Python探索金庸小说世界
  11. IT大公司面试流程与总结
  12. Docker直接删除elasticsearch报错:Failed to obtain node locks
  13. 统一网关Gateway
  14. 安装了本地MySQL后,小皮面板上的MySQL就一直启动失败
  15. Android添加Flurry统计
  16. 学术论文中的“重点与难点”怎么写?
  17. 紫薇星上的数据结构(7)
  18. czl蒻蒟的OI之路13
  19. python字符串乱码问题
  20. python编写我的世界

热门文章

  1. Three.js中自定义控制几何体的点和面的属性
  2. AndroidStudio中Attatch debugger to Android Ptocess时 Choose Process后OK是灰色的
  3. C#中System.ServiceProgress报错
  4. 重磅 | 品牌零售行业数据驱动业务指南,全新上线!
  5. PPT 下载 | 神策数据杜明翰:打造趁手、好用的标签用户画像系统
  6. Growth Workshop:企业如何用数据驱动 GMV 增长
  7. consul 1.2 支持service mesh
  8. flutter笔记1 VScode安装dart code插件踩坑记录
  9. 分享一些书籍,方方面面,很多值得一读
  10. flash破解工具/flash decompiler