123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package base
- import (
- "fmt"
- "github.com/gin-gonic/gin"
- _ "github.com/go-sql-driver/mysql"
- "github.com/opentracing/opentracing-go"
- "github.com/opentracing/opentracing-go/ext"
- "base-gin/pkg/gorm"
- "time"
- )
- const SqlTraceContextKey = "traceContext"
- type MysqlConf struct {
- User string
- Password string
- Addr string
- DataBase string
- MaxIdleConns int
- MaxOpenConns int
- ConnMaxLifeTime time.Duration
- LogMode bool
- }
- // InitMysqlClient 一定要在bootstrap之后
- func InitMysqlClient(conf MysqlConf) (client *gorm.DB, err error) {
- client, err = gorm.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Asia%%2FShanghai",
- conf.User,
- conf.Password,
- conf.Addr,
- conf.DataBase))
- if err != nil {
- return client, err
- }
- client.DB().SetMaxIdleConns(conf.MaxIdleConns)
- client.DB().SetMaxOpenConns(conf.MaxOpenConns)
- client.DB().SetConnMaxLifetime(conf.ConnMaxLifeTime)
- client.LogMode(conf.LogMode)
- // register tracer callback
- setCallback(client, "create")
- setCallback(client, "delete")
- setCallback(client, "update")
- setCallback(client, "query")
- setCallback(client, "row_query")
- return client, nil
- }
- func setCallback(client *gorm.DB, callbackName string) {
- beforeName := fmt.Sprintf("tracer:%v_before", callbackName)
- afterName := fmt.Sprintf("tracer:%v_after", callbackName)
- gormCallbackName := fmt.Sprintf("gorm:%v", callbackName)
- switch callbackName {
- case "create":
- client.Callback().Create().Before(gormCallbackName).Register(beforeName, func(scope *gorm.Scope) {
- tracerBefore(scope, callbackName)
- })
- client.Callback().Create().After(gormCallbackName).Register(afterName, func(scope *gorm.Scope) {
- tracerAfter(scope, callbackName)
- })
- case "query":
- client.Callback().Query().Before(gormCallbackName).Register(beforeName, func(scope *gorm.Scope) {
- tracerBefore(scope, callbackName)
- })
- client.Callback().Query().After(gormCallbackName).Register(afterName, func(scope *gorm.Scope) {
- tracerAfter(scope, callbackName)
- })
- case "update":
- client.Callback().Update().Before(gormCallbackName).Register(beforeName, func(scope *gorm.Scope) {
- tracerBefore(scope, callbackName)
- })
- client.Callback().Update().After(gormCallbackName).Register(afterName, func(scope *gorm.Scope) {
- tracerAfter(scope, callbackName)
- })
- case "delete":
- client.Callback().Delete().Before(gormCallbackName).Register(beforeName, func(scope *gorm.Scope) {
- tracerBefore(scope, callbackName)
- })
- client.Callback().Delete().After(gormCallbackName).Register(afterName, func(scope *gorm.Scope) {
- tracerAfter(scope, callbackName)
- })
- case "row_query":
- client.Callback().RowQuery().Before(gormCallbackName).Register(beforeName, func(scope *gorm.Scope) {
- tracerBefore(scope, callbackName)
- })
- client.Callback().RowQuery().After(gormCallbackName).Register(afterName, func(scope *gorm.Scope) {
- tracerAfter(scope, callbackName)
- })
- }
- }
- func tracerBefore(scope *gorm.Scope, callbackName string) {
- ctx, ok := scope.Search.GetCtx().(*gin.Context)
- if !ok {
- return
- }
- var parentSpanContext opentracing.SpanContext
- if ctx != nil {
- tempSpan, exist := ctx.Get(TraceContextKey)
- if exist {
- parentSpanContext = tempSpan.(opentracing.Span).Context()
- }
- }
- span := TracerStartSpan(parentSpanContext, "DB_"+callbackName, map[string]interface{}{
- ext.SpanKindRPCClient.Key: ext.SpanKindRPCClient,
- string(ext.Component): "gorm",
- string(ext.DBInstance): scope.InstanceID(),
- string(ext.DBType): "mysql",
- })
- scope.Set(SqlTraceContextKey, span)
- }
- func tracerAfter(scope *gorm.Scope, callbackName string) {
- tempSpan, exist := scope.Get(SqlTraceContextKey)
- if !exist {
- return
- }
- span := tempSpan.(opentracing.Span)
- span.SetTag(string(ext.DBStatement), scope.SQL)
- span.Finish()
- }
|