gorm接入skywalking

首先我们用的是阿里云的mysql,本来就有性能指标可以观测,另外,在gorm也设置了慢查询的SQL日志,所以不赞同在将它投入到skywalking,这将极大的影响服务性能,其实将rpc调用纳入追踪就行了,这是分布式服务追踪的痛点,找到哪个服务的问题之后再去做分析,如果是慢SQL的问题,其实日志文件都能看到,如果你想查看SQL语句的参数问题,这是在开发阶段和单元测试阶段就该解决掉的问题。

在gorm中投递消息,可以有两种方式,第一种对 钩子,第二种是 插件。从通用性来将肯定是使用插件的方式。

文档写的很清楚,在特定的callback(比如 create操作)前后你可以插入你的逻辑,而且可以插入多个,相互不影响。比如想在create操作上投递消息,那么应该在create之前创建span,在create之后来end这个span,但是他们是两个不同的函数,如何将span传递过去呢?答案是使用db.Set(spanKey, span)

如果一个函数内执行了多条SQL,那么它们应该被连接起来,那么如何传递ctx呢?可以使用GoroutineID,当然你要明确知道协程的边界,尤其是在Golang中协程到处在使用,这里会是个隐形的Bug。

大致代码如下

func (s *SkyWalking) Name() string {
    
    
	return "gorm:skyWalking"
}

func (s *SkyWalking) Initialize(db *gorm.DB) (err error) {
    
    
	// before database operation
	db.Callback().Create().Before("gorm:create").Register("sky_create_span", s.BeforeCallback("create"))
	db.Callback().Query().Before("gorm:query").Register("sky_create_span", s.BeforeCallback("query"))
	db.Callback().Update().Before("gorm:update").Register("sky_create_span", s.BeforeCallback("update"))
	db.Callback().Delete().Before("gorm:delete").Register("sky_create_span", s.BeforeCallback("delete"))
	db.Callback().Row().Before("gorm:row").Register("sky_create_span", s.BeforeCallback("row"))
	db.Callback().Raw().Before("gorm:raw").Register("sky_create_span", s.BeforeCallback("raw"))

	// after database operation
	db.Callback().Create().After("gorm:create").Register("sky_end_span", s.AfterCallback())
	db.Callback().Query().After("gorm:query").Register("sky_end_span", s.AfterCallback())
	db.Callback().Update().After("gorm:update").Register("sky_end_span", s.AfterCallback())
	db.Callback().Delete().After("gorm:delete").Register("sky_end_span", s.AfterCallback())
	db.Callback().Row().After("gorm:row").Register("sky_end_span", s.AfterCallback())
	db.Callback().Raw().After("gorm:raw").Register("sky_end_span", s.AfterCallback())

	return
}
func (s *SkyWalking) BeforeCallback(operation string) func(db *gorm.DB) {
    
    
    ......
}
func (s *SkyWalking) AfterCallback() func(db *gorm.DB) {
    
    
    ......
}

最后使用 db.Use(xxx)来注册插件。注意, tracer 要在 model 之前启动。

演示代码:https://github.com/phprao/go-skywalking

访问 http://127.0.0.1:7001/test

效果

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/raoxiaoya/article/details/123331193