Give meaning to the zero value and handle wrapping a nil logger.
Chris Hines
8 years ago
61 | 61 |
}
|
62 | 62 |
|
63 | 63 |
// SwapLogger wraps another logger that may be safely replaced while other
|
64 | |
// goroutines use the SwapLogger concurrently.
|
|
64 |
// goroutines use the SwapLogger concurrently. An uninitialized SwapLogger
|
|
65 |
// will discard all log events without error.
|
65 | 66 |
type SwapLogger struct {
|
66 | 67 |
logger atomic.Value
|
67 | 68 |
}
|
|
78 | 79 |
}
|
79 | 80 |
|
80 | 81 |
// Log implements the Logger interface by calling Log on the currently wrapped
|
81 | |
// logger.
|
|
82 |
// logger. It does not log anything if the wrapped logger is nil.
|
82 | 83 |
func (l *SwapLogger) Log(keyvals ...interface{}) error {
|
83 | |
return l.logger.Load().(loggerStruct).Log(keyvals...)
|
|
84 |
s := l.logger.Load().(loggerStruct)
|
|
85 |
if s.Logger == nil {
|
|
86 |
return nil
|
|
87 |
}
|
|
88 |
return s.Log(keyvals...)
|
84 | 89 |
}
|
85 | 90 |
|
86 | 91 |
// Swap replaces the currently wrapped logger with logger. Swap may be called
|
133 | 133 |
if got, want := buf.String(), "k=v\n"; got != want {
|
134 | 134 |
t.Errorf("got %v, want %v", got, want)
|
135 | 135 |
}
|
|
136 |
|
|
137 |
buf.Reset()
|
|
138 |
logger.Swap(nil)
|
|
139 |
|
|
140 |
if err := logger.Log("k", "v"); err != nil {
|
|
141 |
t.Error(err)
|
|
142 |
}
|
|
143 |
if got, want := buf.String(), ""; got != want {
|
|
144 |
t.Errorf("got %v, want %v", got, want)
|
|
145 |
}
|
136 | 146 |
}
|
137 | 147 |
|
138 | 148 |
func TestSwapLoggerConcurrency(t *testing.T) {
|