Skip to content

Commit d456f76

Browse files
committed
add option to set custom level on preparer, execer, queryer, and flag to include start time
1 parent dfc221e commit d456f76

File tree

2 files changed

+169
-17
lines changed

2 files changed

+169
-17
lines changed

options.go

+77-17
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,27 @@ import (
99
)
1010

1111
type options struct {
12-
errorFieldname string
13-
durationFieldname string
14-
timeFieldname string
15-
sqlQueryFieldname string
16-
sqlArgsFieldname string
17-
stmtIDFieldname string
18-
connIDFieldname string
19-
txIDFieldname string
20-
sqlQueryAsMsg bool
21-
logArgs bool
22-
logDriverErrSkip bool
23-
wrapResult bool
24-
minimumLogLevel Level
25-
durationUnit DurationUnit
26-
timeFormat TimeFormat
27-
uidGenerator UIDGenerator
12+
errorFieldname string
13+
durationFieldname string
14+
timeFieldname string
15+
startTimeFieldname string
16+
sqlQueryFieldname string
17+
sqlArgsFieldname string
18+
stmtIDFieldname string
19+
connIDFieldname string
20+
txIDFieldname string
21+
sqlQueryAsMsg bool
22+
logArgs bool
23+
logDriverErrSkip bool
24+
wrapResult bool
25+
minimumLogLevel Level
26+
durationUnit DurationUnit
27+
timeFormat TimeFormat
28+
uidGenerator UIDGenerator
29+
includeStartTime bool
30+
preparerLevel Level
31+
queryerLevel Level
32+
execerLevel Level
2833
}
2934

3035
// setDefaultOptions called first time before Log() called (see: OpenDriver()).
@@ -33,6 +38,7 @@ func setDefaultOptions(opt *options) {
3338
opt.errorFieldname = "error"
3439
opt.durationFieldname = "duration"
3540
opt.timeFieldname = "time"
41+
opt.startTimeFieldname = "start"
3642
opt.sqlQueryFieldname = "query"
3743
opt.sqlArgsFieldname = "args"
3844
opt.stmtIDFieldname = "stmt_id"
@@ -46,6 +52,10 @@ func setDefaultOptions(opt *options) {
4652
opt.durationUnit = DurationMillisecond
4753
opt.timeFormat = TimeFormatUnix
4854
opt.uidGenerator = newDefaultUIDDGenerator()
55+
opt.includeStartTime = false
56+
opt.preparerLevel = LevelInfo
57+
opt.queryerLevel = LevelInfo
58+
opt.execerLevel = LevelInfo
4959
}
5060

5161
// DurationUnit is total time spent on an actual driver function call calculated by time.Since(start).
@@ -140,7 +150,7 @@ func (u *defaultUID) UniqueID() string {
140150
// using math/rand.Read because it's slightly faster than crypto/rand.Read
141151
// unique id always scoped under connectionID so there is no need to super-secure-random using crypto/rand.
142152
//
143-
// nolint: gosec
153+
// nolint // disable gosec check as it does not need crypto/rand
144154
if _, err := rand.Read(random[:]); err != nil {
145155
panic(fmt.Sprintf("sqldblogger: random read error from math/rand: '%s'", err.Error()))
146156
}
@@ -332,3 +342,53 @@ func WithWrapResult(flag bool) Option {
332342
opt.wrapResult = flag
333343
}
334344
}
345+
346+
// WithIncludeStartTime flag to include actual start time before actual driver execution.
347+
//
348+
// Can be useful if we want to combine Log implementation with tracing from context
349+
// and set start time span manually.
350+
//
351+
// Default: false
352+
func WithIncludeStartTime(flag bool) Option {
353+
return func(opt *options) {
354+
opt.includeStartTime = flag
355+
}
356+
}
357+
358+
// WithStartTimeFieldname to customize start time fieldname on log output.
359+
//
360+
// If WithIncludeStartTime true, start time fieldname will use this value.
361+
//
362+
// Default: "start"
363+
func WithStartTimeFieldname(name string) Option {
364+
return func(opt *options) {
365+
opt.startTimeFieldname = name
366+
}
367+
}
368+
369+
// WithPreparerLevel set default level of Prepare(Context) method calls.
370+
//
371+
// Default: LevelInfo
372+
func WithPreparerLevel(lvl Level) Option {
373+
return func(opt *options) {
374+
opt.preparerLevel = lvl
375+
}
376+
}
377+
378+
// WithQueryerLevel set default level of Query(Context) method calls.
379+
//
380+
// Default: LevelInfo
381+
func WithQueryerLevel(lvl Level) Option {
382+
return func(opt *options) {
383+
opt.queryerLevel = lvl
384+
}
385+
}
386+
387+
// WithExecerLevel set default level of Exec(Context) method calls.
388+
//
389+
// Default: LevelInfo
390+
func WithExecerLevel(lvl Level) Option {
391+
return func(opt *options) {
392+
opt.execerLevel = lvl
393+
}
394+
}

options_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,98 @@ func TestWithUIDGenerator(t *testing.T) {
222222
})
223223
}
224224

225+
func TestWithIncludeStartTime(t *testing.T) {
226+
t.Run("Default not include", func(t *testing.T) {
227+
cfg := &options{}
228+
setDefaultOptions(cfg)
229+
230+
assert.False(t, cfg.includeStartTime)
231+
})
232+
233+
t.Run("Set start time flag true", func(t *testing.T) {
234+
cfg := &options{}
235+
setDefaultOptions(cfg)
236+
WithIncludeStartTime(true)(cfg)
237+
WithStartTimeFieldname("start_time")(cfg)
238+
WithTimeFormat(TimeFormatUnix)(cfg)
239+
240+
assert.True(t, cfg.includeStartTime)
241+
assert.Equal(t, "start_time", cfg.startTimeFieldname)
242+
243+
bl := &bufferTestLogger{}
244+
l := &logger{opt: cfg, logger: bl}
245+
start := time.Now()
246+
l.log(
247+
context.TODO(),
248+
LevelInfo,
249+
"msg",
250+
start,
251+
nil,
252+
testLogger.withUID(cfg.stmtIDFieldname, l.opt.uidGenerator.UniqueID()),
253+
testLogger.withQuery("query"),
254+
testLogger.withArgs([]driver.Value{}),
255+
)
256+
257+
var content bufLog
258+
err := json.Unmarshal(bl.Bytes(), &content)
259+
assert.NoError(t, err)
260+
assert.Contains(t, content.Data, cfg.startTimeFieldname)
261+
assert.Equal(t, float64(start.Unix()), content.Data["start_time"])
262+
bl.Reset()
263+
})
264+
}
265+
266+
func TestWithPreparerLevel(t *testing.T) {
267+
t.Run("Default value", func(t *testing.T) {
268+
cfg := &options{}
269+
setDefaultOptions(cfg)
270+
271+
assert.Equal(t, cfg.preparerLevel, LevelInfo)
272+
})
273+
274+
t.Run("Custom value", func(t *testing.T) {
275+
cfg := &options{}
276+
setDefaultOptions(cfg)
277+
WithPreparerLevel(LevelDebug)(cfg)
278+
279+
assert.Equal(t, cfg.preparerLevel, LevelDebug)
280+
})
281+
}
282+
283+
func TestWithQueryerLevel(t *testing.T) {
284+
t.Run("Default value", func(t *testing.T) {
285+
cfg := &options{}
286+
setDefaultOptions(cfg)
287+
288+
assert.Equal(t, cfg.queryerLevel, LevelInfo)
289+
})
290+
291+
t.Run("Custom value", func(t *testing.T) {
292+
cfg := &options{}
293+
setDefaultOptions(cfg)
294+
WithQueryerLevel(LevelDebug)(cfg)
295+
296+
assert.Equal(t, cfg.queryerLevel, LevelDebug)
297+
})
298+
}
299+
300+
func TestWithExecerLevel(t *testing.T) {
301+
t.Run("Default value", func(t *testing.T) {
302+
cfg := &options{}
303+
setDefaultOptions(cfg)
304+
305+
assert.Equal(t, cfg.execerLevel, LevelInfo)
306+
})
307+
308+
t.Run("Custom value", func(t *testing.T) {
309+
cfg := &options{}
310+
setDefaultOptions(cfg)
311+
WithExecerLevel(LevelDebug)(cfg)
312+
313+
assert.Equal(t, cfg.execerLevel, LevelDebug)
314+
})
315+
}
316+
225317
var uidBtest = newDefaultUIDDGenerator()
226318

227319
func BenchmarkUniqueID(b *testing.B) {

0 commit comments

Comments
 (0)