2019-06-15 23:35:17 +00:00
|
|
|
package mlog
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mcmp"
|
2019-06-17 01:15:41 +00:00
|
|
|
"github.com/mediocregopher/mediocre-go-lib/mctx"
|
2019-06-15 23:35:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type cmpKey int
|
|
|
|
|
|
|
|
// SetLogger sets the given logger onto the Component. The logger can later be
|
|
|
|
// retrieved from the Component, or any of its children, using From.
|
2019-06-17 22:18:50 +00:00
|
|
|
//
|
|
|
|
// NOTE that if a Logger is set onto a Component and then changed, even though
|
|
|
|
// the Logger is a pointer and so is changed within the Component, SetLogger
|
|
|
|
// should still be called. This is due to some caching that From does for
|
|
|
|
// performance.
|
2019-06-15 23:35:17 +00:00
|
|
|
func SetLogger(cmp *mcmp.Component, l *Logger) {
|
|
|
|
cmp.SetValue(cmpKey(0), l)
|
2019-06-17 21:56:14 +00:00
|
|
|
|
|
|
|
// If the base Logger on this Component gets changed, then the cached Logger
|
|
|
|
// from From on this Component, and all of its Children, ought to be reset,
|
|
|
|
// so that any changes can be reflected in their loggers.
|
|
|
|
var resetFromLogger func(*mcmp.Component)
|
|
|
|
resetFromLogger = func(cmp *mcmp.Component) {
|
|
|
|
cmp.SetValue(cmpKey(1), nil)
|
|
|
|
for _, childCmp := range cmp.Children() {
|
|
|
|
resetFromLogger(childCmp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
resetFromLogger(cmp)
|
2019-06-15 23:35:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultLogger is an instance of Logger which is returned by From when a
|
|
|
|
// Logger hasn't been previously set with SetLogger on the passed in Component.
|
|
|
|
var DefaultLogger = NewLogger()
|
|
|
|
|
2019-06-17 21:56:14 +00:00
|
|
|
// GetLogger returns the Logger which was set on the Component, or on of its
|
2019-06-15 23:35:17 +00:00
|
|
|
// ancestors, using SetLogger. If no Logger was ever set then DefaultLogger is
|
|
|
|
// returned.
|
2019-06-17 21:56:14 +00:00
|
|
|
func GetLogger(cmp *mcmp.Component) *Logger {
|
|
|
|
if l, ok := cmp.InheritedValue(cmpKey(0)); ok {
|
|
|
|
return l.(*Logger)
|
|
|
|
}
|
|
|
|
return DefaultLogger
|
|
|
|
}
|
|
|
|
|
|
|
|
// From returns the result from GetLogger, modified so as to automatically add
|
|
|
|
// some annotations related to the Component itself to all Messages being
|
|
|
|
// logged.
|
2019-06-15 23:35:17 +00:00
|
|
|
func From(cmp *mcmp.Component) *Logger {
|
2019-06-17 21:56:14 +00:00
|
|
|
if l, _ := cmp.Value(cmpKey(1)).(*Logger); l != nil {
|
2019-06-17 01:15:41 +00:00
|
|
|
return l
|
2019-06-15 23:35:17 +00:00
|
|
|
}
|
2019-06-17 01:15:41 +00:00
|
|
|
|
|
|
|
// if we're here it means a modified Logger wasn't set on this particular
|
|
|
|
// Component, and therefore the current one must be modified.
|
2019-06-17 21:56:14 +00:00
|
|
|
l := GetLogger(cmp).Clone()
|
2019-06-17 01:15:41 +00:00
|
|
|
oldHandler := l.Handler()
|
|
|
|
l.SetHandler(func(msg Message) error {
|
|
|
|
ctx := mctx.MergeAnnotationsInto(cmp.Context(), msg.Contexts...)
|
|
|
|
msg.Contexts = append(msg.Contexts[:0], ctx)
|
|
|
|
return oldHandler(msg)
|
|
|
|
})
|
|
|
|
cmp.SetValue(cmpKey(1), l)
|
|
|
|
|
2019-06-15 23:35:17 +00:00
|
|
|
return l
|
|
|
|
}
|