-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogger.go
More file actions
147 lines (130 loc) · 4.24 KB
/
logger.go
File metadata and controls
147 lines (130 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
// Package gorm0log provides a gorm logger using zerolog as backend.
//
// Thanks to zerolog, we have goo performance since most features are skipped if the
// log message is not visible.
//
// If you queries gorm with context ([gorm.DB.WithContext]), the context can be
// handled by a function in [Config] named "Customize".
//
// Default value of [Config] should be fairly enough for small projects.
//
// [gorm.DB.Debug] switches underlying [zerolog.Logger] to Debug level, which shows
// every message but Trace level ones. Some features, controlled by [Config], can be
// set to customized level. So you can disable those messages by changing its level
// to [UseTrace].
package gorm0log
import (
"context"
"time"
"github.com/rs/zerolog"
"gorm.io/gorm/logger"
)
// DefaultLogLevelMap enables sql dumping if you use [logger.Info] log mode.
//
// It translates Gorm's [logger.Info] mode to [zerolog.DebugLevel], so sql dumping
// is logged.
func DefaultLogLevelMap(i logger.LogLevel) zerolog.Level {
switch {
case i <= logger.Silent:
return zerolog.Disabled
case i == logger.Error:
return zerolog.ErrorLevel
case i == logger.Warn:
return zerolog.WarnLevel
}
return zerolog.DebugLevel
}
// WithTimeTracking enables time tracking info if you use [logger.Info] log mode.
//
// It translates Gorm's [logger.Info] mode to [zerolog.TraceLevel], so sql dumping
// and time tracking info are logged.
func WithTimeTracking(i logger.LogLevel) zerolog.Level {
switch {
case i <= logger.Silent:
return zerolog.Disabled
case i == logger.Error:
return zerolog.ErrorLevel
case i == logger.Warn:
return zerolog.WarnLevel
}
return zerolog.TraceLevel
}
// Logger implements [logger.Interface].
//
// This implementation provides some customizable features, take a look at [Config].
//
// Using [gorm.DB.Debug] switches log level of zerolog.Logger to Debug level.
//
// Zero value means a logger that:
//
// - Log to empty [zerolog.Logger], which logs nothing.
// - Using default [Config].
type Logger struct {
zerolog.Logger
Config
}
// LogMode implements [logger.Interface], to control which message is visible.
func (l *Logger) LogMode(lv logger.LogLevel) logger.Interface {
var lvl zerolog.Level
switch {
case lv <= logger.Silent:
lvl = zerolog.Disabled
case lv == logger.Error:
lvl = zerolog.ErrorLevel
case lv == logger.Warn:
lvl = zerolog.WarnLevel
default:
lvl = zerolog.DebugLevel
}
return &Logger{
Logger: l.Logger.Level(lvl),
Config: l.Config,
}
}
// Info implements [logger.Interface], to show a message at Info level.
func (l *Logger) Info(ctx context.Context, msg string, args ...any) {
l.Logger.Info().Func(l.custom(ctx)).Msgf(msg, args...)
}
// Warn implements [logger.Interface], to show a message at Warn level.
func (l *Logger) Warn(ctx context.Context, msg string, args ...any) {
l.Logger.Warn().Func(l.custom(ctx)).Msgf(msg, args...)
}
// Error implements [logger.Interface], to show a message at Error level.
func (l *Logger) Error(ctx context.Context, msg string, args ...any) {
l.Logger.Error().Func(l.custom(ctx)).Msgf(msg, args...)
}
// Trace implements [logger.Ingerface]. It is called every query by Gorm, so we can
// provide useful features like slow log or sql dump.
func (l *Logger) Trace(ctx context.Context, begin time.Time, f func() (string, int64), err error) {
dur := time.Since(begin)
if err != nil {
ev := l.errLevel(err, l.Logger)
ev.Func(l.custom(ctx)).Func(l.logErr(err, f)).Msg("a sql error occurred")
if ev.Enabled() {
// do not log other messages
return
}
}
if l.SlowThreshold > 0 && dur >= l.SlowThreshold {
// slow log
l.slowLevel(l.Logger).
Func(l.custom(ctx)).
Func(l.logSlow(dur, f)).
Msg("sql query time exceeds threshold")
return
}
l.dumpLevel(l.Logger).
Func(l.custom(ctx)).
Func(l.logDump(dur, f)).
Msg("dump sql")
}
// ParamsFilter implements [gorm.ParamsFilter] to check if parameters should be shown.
func (l *Logger) ParamsFilter(ctx context.Context, sql string, params ...interface{}) (string, []interface{}) {
if l.ParameterizedQueries {
return sql, nil
}
return sql, params
}