Skip to content

Commit e59fd7e

Browse files
authored
Merge pull request #80 from hashicorp/jbardin/independent-child-levels
add IndependentLevels
2 parents 5774f3f + 0868a5a commit e59fd7e

File tree

3 files changed

+49
-17
lines changed

3 files changed

+49
-17
lines changed

intlogger.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ type intLogger struct {
6666
implied []interface{}
6767

6868
exclude func(level Level, msg string, args ...interface{}) bool
69+
70+
// create subloggers with their own level setting
71+
independentLevels bool
6972
}
7073

7174
// New returns a configured logger.
@@ -100,14 +103,15 @@ func newLogger(opts *LoggerOptions) *intLogger {
100103
}
101104

102105
l := &intLogger{
103-
json: opts.JSONFormat,
104-
caller: opts.IncludeLocation,
105-
name: opts.Name,
106-
timeFormat: TimeFormat,
107-
mutex: mutex,
108-
writer: newWriter(output, opts.Color),
109-
level: new(int32),
110-
exclude: opts.Exclude,
106+
json: opts.JSONFormat,
107+
caller: opts.IncludeLocation,
108+
name: opts.Name,
109+
timeFormat: TimeFormat,
110+
mutex: mutex,
111+
writer: newWriter(output, opts.Color),
112+
level: new(int32),
113+
exclude: opts.Exclude,
114+
independentLevels: opts.IndependentLevels,
111115
}
112116

113117
l.setColorization(opts)
@@ -514,7 +518,7 @@ func (l *intLogger) With(args ...interface{}) Logger {
514518
args = args[:len(args)-1]
515519
}
516520

517-
sl := *l
521+
sl := l.copy()
518522

519523
result := make(map[string]interface{}, len(l.implied)+len(args))
520524
keys := make([]string, 0, len(l.implied)+len(args))
@@ -548,32 +552,32 @@ func (l *intLogger) With(args ...interface{}) Logger {
548552
sl.implied = append(sl.implied, MissingKey, extra)
549553
}
550554

551-
return &sl
555+
return sl
552556
}
553557

554558
// Create a new sub-Logger that a name decending from the current name.
555559
// This is used to create a subsystem specific Logger.
556560
func (l *intLogger) Named(name string) Logger {
557-
sl := *l
561+
sl := l.copy()
558562

559563
if sl.name != "" {
560564
sl.name = sl.name + "." + name
561565
} else {
562566
sl.name = name
563567
}
564568

565-
return &sl
569+
return sl
566570
}
567571

568572
// Create a new sub-Logger with an explicit name. This ignores the current
569573
// name. This is used to create a standalone logger that doesn't fall
570574
// within the normal hierarchy.
571575
func (l *intLogger) ResetNamed(name string) Logger {
572-
sl := *l
576+
sl := l.copy()
573577

574578
sl.name = name
575579

576-
return &sl
580+
return sl
577581
}
578582

579583
func (l *intLogger) ResetOutput(opts *LoggerOptions) error {
@@ -660,3 +664,16 @@ func (i *intLogger) ImpliedArgs() []interface{} {
660664
func (i *intLogger) Name() string {
661665
return i.name
662666
}
667+
668+
// copy returns a shallow copy of the intLogger, replacing the level pointer
669+
// when necessary
670+
func (l *intLogger) copy() *intLogger {
671+
sl := *l
672+
673+
if l.independentLevels {
674+
sl.level = new(int32)
675+
*sl.level = *l.level
676+
}
677+
678+
return &sl
679+
}

logger.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ type Logger interface {
186186
// the current name as well.
187187
ResetNamed(name string) Logger
188188

189-
// Updates the level. This should affect all sub-loggers as well. If an
189+
// Updates the level. This should affect all related loggers as well,
190+
// unless they were created with IndependentLevels. If an
190191
// implementation cannot update the level on the fly, it should no-op.
191192
SetLevel(level Level)
192193

@@ -250,6 +251,12 @@ type LoggerOptions struct {
250251
// This is useful when interacting with a system that you wish to suppress the log
251252
// message for (because it's too noisy, etc)
252253
Exclude func(level Level, msg string, args ...interface{}) bool
254+
255+
// IndependentLevels causes subloggers to be created with an independent
256+
// copy of this logger's level. This means that using SetLevel on this
257+
// logger will not effect any subloggers, and SetLevel on any subloggers
258+
// will not effect the parent or sibling loggers.
259+
IndependentLevels bool
253260
}
254261

255262
// InterceptLogger describes the interface for using a logger

logger_test.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,9 @@ func TestLogger(t *testing.T) {
419419

420420
logger := New(&LoggerOptions{
421421
// No name!
422-
Output: &buf,
423-
Level: Off,
422+
Output: &buf,
423+
Level: Off,
424+
IndependentLevels: true,
424425
})
425426

426427
logger.Info("this is test")
@@ -438,6 +439,13 @@ func TestLogger(t *testing.T) {
438439
dataIdx := strings.IndexByte(str, ' ')
439440
rest := str[dataIdx+1:]
440441
assert.Equal(t, "[INFO] sublogger: this is test\n", rest)
442+
443+
buf.Reset()
444+
logger.Info("parent should still be quiet")
445+
str = buf.String()
446+
if len(str) > 0 {
447+
t.Fatal("output from disabled logger:", str)
448+
}
441449
})
442450
}
443451

0 commit comments

Comments
 (0)