Skip to content

Commit

Permalink
Use lables when resetting logger levels
Browse files Browse the repository at this point in the history
Take into consideration the labels when resetting the logger levels.
We don't want to reset all the logger levels if we're using a singular
global logger.
  • Loading branch information
SimonRichardson committed Aug 13, 2024
1 parent 564b008 commit 48b0873
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 26 deletions.
21 changes: 14 additions & 7 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ func (c *Context) GetAllLoggerTags() []string {
names[k] = v
}
}
labels := make([]string, 0, len(names))
tags := make([]string, 0, len(names))
for name := range names {
labels = append(labels, name)
tags = append(tags, name)
}
sort.Strings(labels)
return labels
sort.Strings(tags)
return tags
}

func (c *Context) getLoggerModule(name string, tags []string) *module {
Expand Down Expand Up @@ -215,15 +215,22 @@ func (c *Context) ApplyConfig(config Config, labels ...Labels) {

// ResetLoggerLevels iterates through the known logging modules and sets the
// levels of all to UNSPECIFIED, except for <root> which is set to WARNING.
func (c *Context) ResetLoggerLevels() {
// If labels are provided, then only loggers that have the provided labels
// will be reset.
func (c *Context) ResetLoggerLevels(labels ...Labels) {
label := mergeLabels(labels)

c.modulesMutex.Lock()
defer c.modulesMutex.Unlock()

// Setting the root module to UNSPECIFIED will set it to WARNING.
for _, module := range c.modules {
if !module.hasLabelIntersection(label) {
continue
}

module.setLevel(UNSPECIFIED)
}
// We can safely just wipe everything here.
c.modulesTagConfig = make(map[string]Level)
}

func (c *Context) write(entry Entry) {
Expand Down
94 changes: 90 additions & 4 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (*ContextSuite) TestApplyConfigTags(c *gc.C) {
})
}

func (*ContextSuite) TestApplyConfigLabelsAppliesToNewLoggers(c *gc.C) {
func (*ContextSuite) TestApplyConfigTagsAppliesToNewLoggers(c *gc.C) {
context := loggo.NewContext(loggo.WARNING)

context.ApplyConfig(loggo.Config{"#one": loggo.TRACE})
Expand Down Expand Up @@ -289,7 +289,7 @@ func (*ContextSuite) TestApplyConfigLabelsAppliesToNewLoggers(c *gc.C) {
})
}

func (*ContextSuite) TestApplyConfigLabelsAppliesToNewLoggersWithMultipleTags(c *gc.C) {
func (*ContextSuite) TestApplyConfigTagsAppliesToNewLoggersWithMultipleTags(c *gc.C) {
context := loggo.NewContext(loggo.WARNING)

// Invert the order here, to ensure that the config order doesn't matter,
Expand All @@ -312,7 +312,7 @@ func (*ContextSuite) TestApplyConfigLabelsAppliesToNewLoggersWithMultipleTags(c
})
}

func (*ContextSuite) TestApplyConfigLabelsResetLoggerLevels(c *gc.C) {
func (*ContextSuite) TestApplyConfigTagsResetLoggerLevels(c *gc.C) {
context := loggo.NewContext(loggo.WARNING)

context.ApplyConfig(loggo.Config{"#one": loggo.TRACE})
Expand All @@ -339,7 +339,93 @@ func (*ContextSuite) TestApplyConfigLabelsResetLoggerLevels(c *gc.C) {
})
}

func (*ContextSuite) TestApplyConfigTagsAddative(c *gc.C) {
func (*ContextSuite) TestApplyConfigTagsResetLoggerLevelsUsingLabels(c *gc.C) {
context := loggo.NewContext(loggo.WARNING)

context.ApplyConfig(loggo.Config{"#one": loggo.TRACE})
context.ApplyConfig(loggo.Config{"#two": loggo.DEBUG})

context.GetLogger("a", "one").ChildWithLabels("b", loggo.Labels{"x": "y"})
context.GetLogger("c.d", "one")
context.GetLogger("e", "two")

// If a label is available on a logger, then resetting the levels should
// not remove the label.

context.ResetLoggerLevels()

c.Assert(context.Config(), gc.DeepEquals,
loggo.Config{
"": loggo.WARNING,
})
c.Assert(context.CompleteConfig(), gc.DeepEquals,
loggo.Config{
"": loggo.WARNING,
"a": loggo.UNSPECIFIED,
"a.b": loggo.UNSPECIFIED,
"c": loggo.UNSPECIFIED,
"c.d": loggo.UNSPECIFIED,
"e": loggo.UNSPECIFIED,
})
}

func (*ContextSuite) TestApplyConfigTagsResetLoggerLevelsUsingLabelsRemoval(c *gc.C) {
context := loggo.NewContext(loggo.WARNING)

context.ApplyConfig(loggo.Config{"#one": loggo.TRACE})
context.ApplyConfig(loggo.Config{"#two": loggo.DEBUG})

context.GetLogger("a", "one").ChildWithLabels("b", loggo.Labels{"x": "y"}).ChildWithTags("g", "one")
context.GetLogger("c.d", "one")
context.GetLogger("e", "two")
context.GetLogger("f")

// Ensure that the logger that matches exactly the label is removed,
// including it's children. So we observe hierarchy in the removal.

c.Assert(context.Config(), gc.DeepEquals,
loggo.Config{
"": loggo.WARNING,
"a": loggo.TRACE,
"a.b.g": loggo.TRACE,
"c.d": loggo.TRACE,
"e": loggo.DEBUG,
})
c.Assert(context.CompleteConfig(), gc.DeepEquals,
loggo.Config{
"": loggo.WARNING,
"a": loggo.TRACE,
"a.b": loggo.UNSPECIFIED,
"a.b.g": loggo.TRACE,
"c": loggo.UNSPECIFIED,
"c.d": loggo.TRACE,
"e": loggo.DEBUG,
"f": loggo.UNSPECIFIED,
})

context.ResetLoggerLevels(loggo.Labels{"x": "y"})

c.Assert(context.Config(), gc.DeepEquals,
loggo.Config{
"": loggo.WARNING,
"a": loggo.TRACE,
"c.d": loggo.TRACE,
"e": loggo.DEBUG,
})
c.Assert(context.CompleteConfig(), gc.DeepEquals,
loggo.Config{
"": loggo.WARNING,
"a": loggo.TRACE,
"a.b": loggo.UNSPECIFIED,
"a.b.g": loggo.UNSPECIFIED,
"c": loggo.UNSPECIFIED,
"c.d": loggo.TRACE,
"e": loggo.DEBUG,
"f": loggo.UNSPECIFIED,
})
}

func (*ContextSuite) TestApplyConfigTagsAdditive(c *gc.C) {
context := loggo.NewContext(loggo.WARNING)
context.ApplyConfig(loggo.Config{"#one": loggo.TRACE})
context.ApplyConfig(loggo.Config{"#two": loggo.DEBUG})
Expand Down
22 changes: 7 additions & 15 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ func (logger Logger) Tags() []string {
return logger.getModule().tags
}

// Labels returns the configured labels of the logger's module.
func (logger Logger) Labels() Labels {
return logger.getModule().labels
}

// EffectiveLogLevel returns the effective min log level of
// the receiver - that is, messages with a lesser severity
// level will be discarded.
Expand Down Expand Up @@ -159,15 +164,6 @@ func (logger Logger) Logf(level Level, message string, args ...interface{}) {
logger.LogCallf(logger.callDepth, level, message, args...)
}

// LogWithlabelsf logs a printf-formatted message at the given level with extra
// labels. The given labels will be added to the log entry.
// A message will be discarded if level is less than the the effective log level
// of the logger. Note that the writers may also filter out messages that are
// less than their registered minimum severity level.
func (logger Logger) LogWithLabelsf(level Level, message string, extraLabels map[string]string, args ...interface{}) {
logger.logCallf(logger.callDepth, level, message, extraLabels, args...)
}

// LogCallf logs a printf-formatted message at the given level.
// The location of the call is indicated by the calldepth argument.
// A calldepth of 1 means the function that called this function.
Expand All @@ -176,12 +172,12 @@ func (logger Logger) LogWithLabelsf(level Level, message string, extraLabels map
// Note that the writers may also filter out messages that
// are less than their registered minimum severity level.
func (logger Logger) LogCallf(calldepth int, level Level, message string, args ...interface{}) {
logger.logCallf(calldepth+1, level, message, nil, args...)
logger.logCallf(calldepth+1, level, message, args...)
}

// logCallf is a private method for logging a printf-formatted message at the
// given level. Used by LogWithLabelsf and LogCallf.
func (logger Logger) logCallf(calldepth int, level Level, message string, extraLabels map[string]string, args ...interface{}) {
func (logger Logger) logCallf(calldepth int, level Level, message string, args ...interface{}) {
module := logger.getModule()
if !module.willWrite(level) {
return
Expand Down Expand Up @@ -224,10 +220,6 @@ func (logger Logger) logCallf(calldepth int, level Level, message string, extraL
for k, v := range module.labels {
entry.Labels[k] = v
}
// Add extra labels if there's any given.
for k, v := range extraLabels {
entry.Labels[k] = v
}
module.write(entry)
}

Expand Down
23 changes: 23 additions & 0 deletions logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ func (s *LoggerSuite) TestInheritedLabels(c *gc.C) {

logger := context.GetLogger("testing")

nestedLoggerWithLabels := logger.
ChildWithLabels("nested", loggo.Labels{"foo": "bar"})
deepNestedLoggerWithLabels := nestedLoggerWithLabels.
ChildWithLabels("nested", loggo.Labels{"foo": "baz"}).
ChildWithLabels("deepnested", loggo.Labels{"fred": "tim"})

loggerWithTagsAndLabels := logger.
ChildWithLabels("nested-labels", loggo.Labels{"hello": "world"}).
ChildWithTags("nested-tag", "tag1", "tag2")

c.Check(nestedLoggerWithLabels.Labels(), gc.DeepEquals, loggo.Labels{"foo": "bar"})
c.Check(deepNestedLoggerWithLabels.Labels(), gc.DeepEquals, loggo.Labels{"foo": "baz", "fred": "tim"})
c.Check(loggerWithTagsAndLabels.Labels(), gc.DeepEquals, loggo.Labels{"hello": "world"})
}

func (s *LoggerSuite) TestInheritedLabelsInLogs(c *gc.C) {
writer := &loggo.TestWriter{}
context := loggo.NewContext(loggo.INFO)
err := context.AddWriter("test", writer)
c.Assert(err, gc.IsNil)

logger := context.GetLogger("testing")

nestedLoggerWithLabels := logger.
ChildWithLabels("nested", loggo.Labels{"foo": "bar"})
deepNestedLoggerWithLabels := nestedLoggerWithLabels.
Expand Down

0 comments on commit 48b0873

Please sign in to comment.