github.com/PDOK/gokoala@v0.50.6/internal/ogc/features/datasources/sqllog.go (about) 1 package datasources 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "os" 8 "strconv" 9 "strings" 10 "time" 11 ) 12 13 type contextKey int 14 15 const ( 16 envLogSQL = "LOG_SQL" 17 envSlowQueryTime = "SLOW_QUERY_TIME" 18 defaultSlowQueryTime = 5 * time.Second 19 sqlContextKey contextKey = iota 20 ) 21 22 // SQLLog query logging for debugging purposes 23 type SQLLog struct { 24 LogSQL bool 25 SlowQueryTime time.Duration 26 } 27 28 // NewSQLLogFromEnv build a SQLLog from environment variables listed in this file 29 func NewSQLLogFromEnv() *SQLLog { 30 var err error 31 logSQL := false 32 if os.Getenv(envLogSQL) != "" { 33 logSQL, err = strconv.ParseBool(os.Getenv(envLogSQL)) 34 if err != nil { 35 log.Fatalf("invalid %s value provided, must be a boolean", envLogSQL) 36 } 37 } 38 slowQueryTime := defaultSlowQueryTime 39 if os.Getenv(envSlowQueryTime) != "" { 40 slowQueryTime, err = time.ParseDuration(os.Getenv(envSlowQueryTime)) 41 if err != nil { 42 log.Fatalf("invalid %s value provided, value such as '5s' expected", envSlowQueryTime) 43 } 44 } 45 return &SQLLog{LogSQL: logSQL, SlowQueryTime: slowQueryTime} 46 } 47 48 // Before callback prior to execution of the given SQL query 49 func (s *SQLLog) Before(ctx context.Context, _ string, _ ...any) (context.Context, error) { 50 return context.WithValue(ctx, sqlContextKey, time.Now()), nil 51 } 52 53 // After callback once execution of the given SQL query is done 54 func (s *SQLLog) After(ctx context.Context, query string, args ...any) (context.Context, error) { 55 start := ctx.Value(sqlContextKey).(time.Time) 56 timeSpent := time.Since(start) 57 if timeSpent > s.SlowQueryTime || s.LogSQL { 58 query = replaceBindVars(query, args) 59 log.Printf("\n--- SQL:\n%s\n--- SQL query took: %s\n", query, timeSpent) 60 } 61 return ctx, nil 62 } 63 64 // replaceBindVars replaces '?' bind vars in order to log a complete query 65 func replaceBindVars(query string, args []any) string { 66 for _, arg := range args { 67 query = strings.Replace(query, "?", fmt.Sprintf("%v", arg), 1) 68 } 69 return query 70 }