请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

可以帮我看下gorm得监控可以还有什么优化空间/不合理得吗?

package dagapm

import (
	"context"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
	"gorm.io/gorm"
	"time"
)

type GormDBWrapper struct {
}

const (
	gormTranceName     = "gorm_trance"
	callBackBeforeName = "opentracing:before"
	callBackAfterName  = "opentracing:after"
)

func (g *GormDBWrapper) Name() string {
	return "GormDB"
}

func varsToString(vars []interface{}) []string {
	res := make([]string, 0, len(vars))
	for _, value := range vars {
		res = append(res, value.(string))
	}
	return res
}

func gormBefore(db *gorm.DB) {
	trance := otel.Tracer(gormTranceName)
	beginTime := time.Now()
	_, span := trance.Start(context.Background(), "gormtrance")
	if span != nil {
		span.SetAttributes(
			attribute.String("sql.query", db.Statement.SQL.String()),
			attribute.StringSlice("sql.args", varsToString(db.Statement.Vars)),
		)
	}
	db.InstanceSet("begin_time", beginTime)
	db.InstanceSet("otel_span", span)
}

func gormAfter(db *gorm.DB) {
	span := trace.SpanFromContext(db.Statement.Context)
	defer span.End()
	beginTime, isExit := db.InstanceGet("begin_time")
	if !isExit {
		return
	}
	now := time.Now()
	if now.Sub(beginTime.(time.Time)) > time.Second {
		span.SetAttributes(
			attribute.Bool("slowsql", true))
	}
}

func (g *GormDBWrapper) Initialize(db *gorm.DB) error {
	err := db.Callback().Create().Before("gorm_create").Register(callBackBeforeName, gormBefore)
	if err != nil {
		return err
	}
	err = db.Callback().Delete().Before("gorm_delete").Register(callBackBeforeName, gormBefore)
	if err != nil {
		return err
	}
	err = db.Callback().Query().Before("gorm_query").Register(callBackBeforeName, gormBefore)
	if err != nil {
		return err
	}
	err = db.Callback().Row().Before("gorm_row").Register(callBackBeforeName, gormBefore)
	if err != nil {
		return err
	}
	err = db.Callback().Raw().Before("gorm_raw").Register(callBackBeforeName, gormBefore)
	if err != nil {
		return err
	}
	err = db.Callback().Update().Before("gorm_update").Register(callBackBeforeName, gormBefore)
	if err != nil {
		return err
	}
	err = db.Callback().Row().After("gorm_row").Register(callBackBeforeName, gormAfter)
	if err != nil {
		return err
	}
	err = db.Callback().Create().After("gorm_create").Register(callBackAfterName, gormAfter)
	if err != nil {
		return err
	}
	err = db.Callback().Delete().After("gorm_delete").Register(callBackAfterName, gormAfter)
	if err != nil {
		return err
	}
	err = db.Callback().Update().After("gorm_update").Register(callBackAfterName, gormAfter)
	if err != nil {
		return err
	}
	err = db.Callback().Raw().After("gorm_raw").Register(callBackAfterName, gormAfter)
	if err != nil {
		return err
	}
	err = db.Callback().Query().After("gorm_query").Register(callBackAfterName, gormAfter)
	if err != nil {
		return err
	}
	return err
}

正在回答 回答被采纳积分+3

1回答

蓝胖子的编程梦 2024-08-05 13:49:54

同学写的很不错,能举一反三,课程对golang mysql库的改造,采用的正是装饰器模式在原有操作前后加上一些埋点操作,gorm自带的callback机制能省去原有的改造成本,直接添加上对应埋点。

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信