github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/sqlext/logger/logger.go (about) 1 package logger 2 3 import ( 4 "context" 5 "fmt" 6 "github.com/ascarter/requestid" 7 "github.com/opentracing/opentracing-go" 8 "github.com/pkg/errors" 9 "github.com/rs/zerolog" 10 "github.com/uber/jaeger-client-go" 11 "github.com/unionj-cloud/go-doudou/v2/toolkit/caller" 12 "github.com/unionj-cloud/go-doudou/v2/toolkit/cast" 13 "github.com/unionj-cloud/go-doudou/v2/toolkit/reflectutils" 14 "github.com/unionj-cloud/go-doudou/v2/toolkit/stringutils" 15 "github.com/unionj-cloud/go-doudou/v2/toolkit/zlogger" 16 "os" 17 "strings" 18 ) 19 20 type SqlLogger struct { 21 Logger zerolog.Logger 22 } 23 24 func (receiver SqlLogger) Enable() bool { 25 return cast.ToBoolOrDefault(os.Getenv("GDD_SQL_LOG_ENABLE"), false) 26 } 27 28 func (receiver SqlLogger) Log(ctx context.Context, query string, args ...interface{}) { 29 if !receiver.Enable() { 30 return 31 } 32 receiver.LogWithErr(ctx, nil, nil, query, args...) 33 } 34 35 type SqlLoggerOption func(logger *SqlLogger) 36 37 func WithLogger(logger zerolog.Logger) SqlLoggerOption { 38 return func(sqlLogger *SqlLogger) { 39 sqlLogger.Logger = logger 40 } 41 } 42 43 func NewSqlLogger(opts ...SqlLoggerOption) SqlLogger { 44 sqlLogger := SqlLogger{ 45 Logger: zlogger.Logger, 46 } 47 for _, item := range opts { 48 item(&sqlLogger) 49 } 50 return sqlLogger 51 } 52 53 func PopulatedSql(query string, args ...interface{}) string { 54 var sb strings.Builder 55 sb.WriteString(strings.Join(strings.Fields(query), " ")) 56 for _, arg := range args { 57 value := reflectutils.ValueOf(arg) 58 if value.IsValid() { 59 sb.WriteString(fmt.Sprint(value.Interface())) 60 } else { 61 sb.WriteString(fmt.Sprint(arg)) 62 } 63 } 64 return strings.ReplaceAll(sb.String(), "'<nil>'", "null") 65 } 66 67 func (receiver SqlLogger) LogWithErr(ctx context.Context, err error, hit *bool, query string, args ...interface{}) { 68 if !receiver.Enable() { 69 return 70 } 71 var sb strings.Builder 72 if reqId, ok := requestid.FromContext(ctx); ok && stringutils.IsNotEmpty(reqId) { 73 sb.WriteString(fmt.Sprintf("RequestID: %s\t", reqId)) 74 } 75 span := opentracing.SpanFromContext(ctx) 76 if span != nil { 77 if jspan, ok := span.(*jaeger.Span); ok { 78 sb.WriteString(fmt.Sprintf("TraceID: %s\t", jspan.SpanContext().TraceID().String())) 79 } else { 80 sb.WriteString(fmt.Sprintf("TraceID: %s\t", span)) 81 } 82 } 83 sb.WriteString(fmt.Sprintf("SQL: %s", PopulatedSql(query, args...))) 84 if hit != nil { 85 sb.WriteString(fmt.Sprintf("\tHIT: %t", *hit)) 86 } 87 if err != nil { 88 sb.WriteString(fmt.Sprintf("\tERR: %s", errors.Wrap(err, caller.NewCaller().String()))) 89 } 90 receiver.Logger.Info().Msgf(sb.String()) 91 }