Dubbo自定义日志拦截器
前言
上一篇文章 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自定义日志拦截器相关推荐
- Dubbo自定义日志拦截器 1
前言 上一篇文章 Spring aop+自定义注解统一记录用户行为日志 记录了 web层中通过自定义注解配合Spring aop自动记录用户行为日志的过程.那么按照分布式架构中Dubbo服务层的调用过 ...
- 自定义日志_Dubbo自定义日志拦截器源码分析
需求场景 在使用Dubbo搭建的分布式项目中,服务层代码调用是这样的: @GetMapping(value = "/info")2 public BaseResult userIn ...
- WebServices中使用cxf开发日志拦截器以及自定义拦截器
首先下载一个cxf实例,里面包含cxf的jar包.我下的是apache-cxf-2.5.9 1.为什么要设置拦截器? 为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截 ...
- 自定义Flume拦截器,并将收集的日志存储到Kafka中(案例)
1.引入POM文件 如果想调用Flume,需要引入flume相关的jar包依赖,jar包依赖如下: <?xml version="1.0" encoding="UT ...
- 好用的自定义Okhttp日志拦截器
Okhttp中自带的日志拦截器 HttpLoggingInterceptor 实在是不好用,日志太多太乱,所以想要有好看.简洁的日志打印就要靠自定义了,下面分享我参照 HttpLoggingInter ...
- 【WebService】CXF拦截器的设置以及自定义CXF拦截器
欢迎关注我新搭建的博客:http://www.itcodai.com/ WebService系列文章: [WebService]带你走进webservice的世界 [WebService]自定义Web ...
- java创建请求拦截器_80.简单Retrofit+RxJava+日志拦截器结合使用
1.需要使用到的依赖如下(Retrofit\RxJava\RecyclerView\日志拦截器) //only Retrofit(只用Retrofit联网) implementation 'io.re ...
- springboot整合shiro和session的详细过程和自定义登录拦截器
文章目录 1.shiro依赖 2.shiro配置 shiro过滤器配置: 关联自定义的其他管理器 自定义会话工厂: 3.登陆时记录用户信息 4.shiro一些工具类的学习 5.自定义登录拦截器 shi ...
- Mybatis自定义SQL拦截器
本博客介绍的是继承Mybatis提供的Interface接口,自定义拦截器,然后将项目中的sql拦截一下,打印到控制台. 先自定义一个拦截器 package com.muses.taoshop.com ...
最新文章
- linux服务器性能监控命令汇总(一)
- 实时SLAM的未来及深度学习与SLAM对比
- linux系统无线怎么设置密码,LINUX终端下配置WPA2加密无线网络
- UVA - 11572
- bzoj 2194 快速傅立叶之二
- 无法卸载 Mac 上的磁盘时该怎么办?
- html下拉菜单的某个值被选定,使用JavaScript在下拉列表中获取选定的值?
- MyCat之全局表和ER表
- flash声音播放-Sound
- 2万字用Python探索金庸小说世界
- IT大公司面试流程与总结
- Docker直接删除elasticsearch报错:Failed to obtain node locks
- 统一网关Gateway
- 安装了本地MySQL后,小皮面板上的MySQL就一直启动失败
- Android添加Flurry统计
- 学术论文中的“重点与难点”怎么写?
- 紫薇星上的数据结构(7)
- czl蒻蒟的OI之路13
- python字符串乱码问题
- python编写我的世界
热门文章
- Three.js中自定义控制几何体的点和面的属性
- AndroidStudio中Attatch debugger to Android Ptocess时 Choose Process后OK是灰色的
- C#中System.ServiceProgress报错
- 重磅 | 品牌零售行业数据驱动业务指南,全新上线!
- PPT 下载 | 神策数据杜明翰:打造趁手、好用的标签用户画像系统
- Growth Workshop:企业如何用数据驱动 GMV 增长
- consul 1.2 支持service mesh
- flutter笔记1 VScode安装dart code插件踩坑记录
- 分享一些书籍,方方面面,很多值得一读
- flash破解工具/flash decompiler