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  }