文档章节

聊聊dubbo-go的AccessLogFilter

go4it
 go4it
发布于 07/14 23:19
字数 484
阅读 78
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

本文主要研究一下dubbo-go的AccessLogFilter

AccessLogFilter

dubbo-go-v1.4.2/filter/filter_impl/access_log_filter.go

type AccessLogFilter struct {
	logChan chan AccessLogData
}
  • AccessLogFilter定义了AccessLogData类型的chan

Invoke

dubbo-go-v1.4.2/filter/filter_impl/access_log_filter.go

func (ef *AccessLogFilter) Invoke(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
	accessLog := invoker.GetUrl().GetParam(constant.ACCESS_LOG_KEY, "")
	if len(accessLog) > 0 {
		accessLogData := AccessLogData{data: ef.buildAccessLogData(invoker, invocation), accessLog: accessLog}
		ef.logIntoChannel(accessLogData)
	}
	return invoker.Invoke(ctx, invocation)
}
  • Invoke方法首先通过invoker.GetUrl().GetParam获取constant.ACCESS_LOG_KEY配置,若accessLog有值,则通过ef.buildAccessLogData构建accessLogData,然后执行ef.logIntoChannel(accessLogData),最后执行invoker.Invoke(ctx, invocation)

logIntoChannel

dubbo-go-v1.4.2/filter/filter_impl/access_log_filter.go

func (ef *AccessLogFilter) logIntoChannel(accessLogData AccessLogData) {
	select {
	case ef.logChan <- accessLogData:
		return
	default:
		logger.Warn("The channel is full and the access logIntoChannel data will be dropped")
		return
	}
}
  • logIntoChannel方法通过select方法将accessLogData写入ef.logChan

buildAccessLogData

dubbo-go-v1.4.2/filter/filter_impl/access_log_filter.go

func (ef *AccessLogFilter) buildAccessLogData(_ protocol.Invoker, invocation protocol.Invocation) map[string]string {
	dataMap := make(map[string]string, 16)
	attachments := invocation.Attachments()
	dataMap[constant.INTERFACE_KEY] = attachments[constant.INTERFACE_KEY]
	dataMap[constant.METHOD_KEY] = invocation.MethodName()
	dataMap[constant.VERSION_KEY] = attachments[constant.VERSION_KEY]
	dataMap[constant.GROUP_KEY] = attachments[constant.GROUP_KEY]
	dataMap[constant.TIMESTAMP_KEY] = time.Now().Format(MessageDateLayout)
	dataMap[constant.LOCAL_ADDR], _ = attachments[constant.LOCAL_ADDR]
	dataMap[constant.REMOTE_ADDR], _ = attachments[constant.REMOTE_ADDR]

	if len(invocation.Arguments()) > 0 {
		builder := strings.Builder{}
		// todo(after the paramTypes were set to the invocation. we should change this implementation)
		typeBuilder := strings.Builder{}

		builder.WriteString(reflect.ValueOf(invocation.Arguments()[0]).String())
		typeBuilder.WriteString(reflect.TypeOf(invocation.Arguments()[0]).Name())
		for idx := 1; idx < len(invocation.Arguments()); idx++ {
			arg := invocation.Arguments()[idx]
			builder.WriteString(",")
			builder.WriteString(reflect.ValueOf(arg).String())

			typeBuilder.WriteString(",")
			typeBuilder.WriteString(reflect.TypeOf(arg).Name())
		}
		dataMap[Arguments] = builder.String()
		dataMap[Types] = typeBuilder.String()
	}

	return dataMap
}
  • buildAccessLogData方法提取invocation.Attachments()的数据来构建dataMap

writeLogToFile

dubbo-go-v1.4.2/filter/filter_impl/access_log_filter.go

func (ef *AccessLogFilter) writeLogToFile(data AccessLogData) {
	accessLog := data.accessLog
	if isDefault(accessLog) {
		logger.Info(data.toLogMessage())
		return
	}

	logFile, err := ef.openLogFile(accessLog)
	if err != nil {
		logger.Warnf("Can not open the access log file: %s, %v", accessLog, err)
		return
	}
	logger.Debugf("Append log to %s", accessLog)
	message := data.toLogMessage()
	message = message + "\n"
	_, err = logFile.WriteString(message)
	if err != nil {
		logger.Warnf("Can not write the log into access log file: %s, %v", accessLog, err)
	}
}
  • writeLogToFile方法通过logFile.WriteString(message)将log写到文件

GetAccessLogFilter

dubbo-go-v1.4.2/filter/filter_impl/access_log_filter.go

func GetAccessLogFilter() filter.Filter {
	accessLogFilter := &AccessLogFilter{logChan: make(chan AccessLogData, LogMaxBuffer)}
	go func() {
		for accessLogData := range accessLogFilter.logChan {
			accessLogFilter.writeLogToFile(accessLogData)
		}
	}()
	return accessLogFilter
}
  • GetAccessLogFilter方法会创建AccessLogFilter,同时异步遍历accessLogFilter.logChan执行accessLogFilter.writeLogToFile(accessLogData)

小结

AccessLogFilter定义了AccessLogData类型的chan;Invoke方法首先通过invoker.GetUrl().GetParam获取constant.ACCESS_LOG_KEY配置,若accessLog有值,则通过ef.buildAccessLogData构建accessLogData,然后执行ef.logIntoChannel(accessLogData),最后执行invoker.Invoke(ctx, invocation)

doc

go4it
粉丝 95
博文 1425
码字总数 1299794
作品 0
深圳
私信 提问
加载中
请先登录后再评论。
日志分析(二)jvm agent+kafka+es +kibana 的OLAP日志分析系统

jvm agent+kafka+es +kibana 一般web业务的场景都包含了分布式,web事务的多应用间跳转,各层次间实现负载均衡等。日志分析OLAP的技术要求就需要跟踪夸web应用的多层次、多应用的链式请求,针...

venuser
2015/12/14
969
4
聊聊数据权限哪些事儿

序 一般来说,权限有许多种,我们经常用到的一般有操作权限和数据权限两种。 所谓操作权限就是有或者没有做某种操作的权限,具体表现形式就是你看不到某个菜单或按钮,当然也有的是把菜单或按...

悠悠然然
2016/03/04
1.4W
82
当技术已经产品

当技术已经产品,我是程序员,尽管工作三年,但是在初级的路口徘徊。一直在考虑,如何去做好技术这件事情?如何去区分业务和技术,又如何去融合业务和技术,从而来提高我们的工作效率?一直很...

zjut_l
2016/03/07
953
5
三个分享——异步流程控制 / Modern Node.js/Java项目如何与Node.js共存

分享1《深入浅出js(Node.js)异步流程控制》 StuQ分享专题《深入浅出js(Node.js)异步流程控制》 InfoQ 前端之巅分享 精简版 摘要 目前在js流程控制领域越来越乱,各种派系。。。比如promi...

i5ting
2016/07/18
1.9K
6
聊聊视图层切面实现方案

前面发过一篇《谈谈应用层切面设计》,@HulkZ说看了好几遍也没看懂,然后我又拉他到小黑屋面壁思过了好几次;也有人关心个性与扩展性如何得到平衡;也有人说,悠然就会扯淡,如何实现呢?那么...

悠悠然然
2016/05/30
1.4K
3

没有更多内容

加载失败,请刷新页面

加载更多

【实用技巧】MAC苹果电脑怎么远程?

一般电脑远程包括三方面: 1、如果从外部windows或者linux终端连接到mac苹果电脑; 2、从苹果电脑内如何远程外面的windows、linux和mac等; 3、苹果和安卓手机怎么远程连接苹果/Windows电脑。...

osc_doeya1ck
8分钟前
0
0
虚拟主机和VPS主机有哪些不同点呢

虚拟主机是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术。vps主机是将一台服务器分割成多个虚拟专享服务器的服务。实现VPS的技术分为容器技术和虚拟机技术...

osc_b88oux8w
9分钟前
0
0
合理的使用MySQL乐观锁与悲观锁

针对 MySQL的乐观锁与悲观锁的使用,基本都是按照业务场景针对性使用的。针对每个业务场景,对应的使用锁。 但是两种锁无非都是解决并发所产生的问题。下面我们来看看如何合理的使用乐观锁与...

php开源社区
10分钟前
0
0
fusionpbx 中文 汉化

  自己以前有从事过呼叫中心的工作经验,然而由于自己是从事后端开发,对于前端界面的开发还是有些吃力,但是自己却又想自己搭建一套呼叫中心,所以购买了一台云服务器并克隆了FusionPBX的...

osc_ydeb2o99
11分钟前
7
0
关于大O表示法和小O表示法

上节课老师讲了一下各种表示法,当时没咋听懂,后来查了一些资料弄懂了,记录一下。 主要是从维基百科上看的。http://en.wikipedia.org/wiki/Big_O_notation 大O表示法: f(x) = O(g(x)) 表示...

osc_3mzamgkq
12分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部