Permalink
Browse files

Make every logger a taggable logger

  • Loading branch information...
1 parent 038c38e commit b5e945172ad56e91b57dc62bad2e2115e7392d70 Pieter Noordhuis and Tim Labeeuw committed Mar 8, 2013
Showing with 157 additions and 38 deletions.
  1. +93 −28 logger.go
  2. +58 −4 logger_test.go
  3. +1 −1 perf_test.go
  4. +2 −2 steno.go
  5. +3 −3 tagged_logger.go
View
121 logger.go
@@ -2,6 +2,7 @@ package steno
import (
"fmt"
+ "sync"
)
type L interface {
@@ -10,7 +11,9 @@ type L interface {
}
type Logger struct {
+ sync.Mutex
L
+ d map[string]interface{}
}
type BaseLogger struct {
@@ -39,114 +42,176 @@ func (l *BaseLogger) Log(x LogLevel, m string, d map[string]interface{}) {
}
}
-func (l Logger) Fatal(m string) {
+func (l *Logger) Log(x LogLevel, m string, d map[string]interface{}) {
+ var r map[string]interface{}
+
+ if d != nil && l.d != nil {
+ r = make(map[string]interface{})
+
+ // Copy the loggers data
+ for k, v := range l.d {
+ r[k] = v
+ }
+
+ // Overwrite specified data
+ for k, v := range d {
+ r[k] = v
+ }
+ } else if d != nil {
+ r = d
+ } else {
+ r = l.d
+ }
+
+ l.L.Log(x, m, r)
+}
+
+func (l *Logger) Set(k string, v interface{}) {
+ l.Lock()
+
+ if l.d == nil {
+ l.d = make(map[string]interface{})
+ }
+
+ l.d[k] = v
+
+ l.Unlock()
+}
+
+func (l *Logger) Get(k string) (rv interface{}) {
+ l.Lock()
+
+ if l.d != nil {
+ rv = l.d[k]
+ }
+
+ l.Unlock()
+
+ return
+}
+
+func (l *Logger) Copy() (rv *Logger) {
+ rv = &Logger{L: l.L}
+
+ l.Lock()
+
+ for k, v := range l.d {
+ rv.Set(k, v)
+ }
+
+ l.Unlock()
+
+ return
+}
+
+func (l *Logger) Fatal(m string) {
l.Log(LOG_FATAL, m, nil)
}
-func (l Logger) Error(m string) {
+func (l *Logger) Error(m string) {
l.Log(LOG_ERROR, m, nil)
}
-func (l Logger) Warn(m string) {
+func (l *Logger) Warn(m string) {
l.Log(LOG_WARN, m, nil)
}
-func (l Logger) Info(m string) {
+func (l *Logger) Info(m string) {
l.Log(LOG_INFO, m, nil)
}
-func (l Logger) Debug(m string) {
+func (l *Logger) Debug(m string) {
l.Log(LOG_DEBUG, m, nil)
}
-func (l Logger) Debug1(m string) {
+func (l *Logger) Debug1(m string) {
l.Log(LOG_DEBUG1, m, nil)
}
-func (l Logger) Debug2(m string) {
+func (l *Logger) Debug2(m string) {
l.Log(LOG_DEBUG2, m, nil)
}
-func (l Logger) Fatald(d map[string]interface{}, m string) {
+func (l *Logger) Fatald(d map[string]interface{}, m string) {
l.Log(LOG_FATAL, m, d)
}
-func (l Logger) Errord(d map[string]interface{}, m string) {
+func (l *Logger) Errord(d map[string]interface{}, m string) {
l.Log(LOG_ERROR, m, d)
}
-func (l Logger) Warnd(d map[string]interface{}, m string) {
+func (l *Logger) Warnd(d map[string]interface{}, m string) {
l.Log(LOG_WARN, m, d)
}
-func (l Logger) Infod(d map[string]interface{}, m string) {
+func (l *Logger) Infod(d map[string]interface{}, m string) {
l.Log(LOG_INFO, m, d)
}
-func (l Logger) Debugd(d map[string]interface{}, m string) {
+func (l *Logger) Debugd(d map[string]interface{}, m string) {
l.Log(LOG_DEBUG, m, d)
}
-func (l Logger) Debug1d(d map[string]interface{}, m string) {
+func (l *Logger) Debug1d(d map[string]interface{}, m string) {
l.Log(LOG_DEBUG1, m, d)
}
-func (l Logger) Debug2d(d map[string]interface{}, m string) {
+func (l *Logger) Debug2d(d map[string]interface{}, m string) {
l.Log(LOG_DEBUG2, m, d)
}
-func (l Logger) Fatalf(f string, a ...interface{}) {
+func (l *Logger) Fatalf(f string, a ...interface{}) {
l.Log(LOG_FATAL, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Errorf(f string, a ...interface{}) {
+func (l *Logger) Errorf(f string, a ...interface{}) {
l.Log(LOG_ERROR, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Warnf(f string, a ...interface{}) {
+func (l *Logger) Warnf(f string, a ...interface{}) {
l.Log(LOG_WARN, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Infof(f string, a ...interface{}) {
+func (l *Logger) Infof(f string, a ...interface{}) {
l.Log(LOG_INFO, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Debugf(f string, a ...interface{}) {
+func (l *Logger) Debugf(f string, a ...interface{}) {
l.Log(LOG_DEBUG, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Debug1f(f string, a ...interface{}) {
+func (l *Logger) Debug1f(f string, a ...interface{}) {
l.Log(LOG_DEBUG1, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Debug2f(f string, a ...interface{}) {
+func (l *Logger) Debug2f(f string, a ...interface{}) {
l.Log(LOG_DEBUG2, fmt.Sprintf(f, a...), nil)
}
-func (l Logger) Fataldf(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Fataldf(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_FATAL, fmt.Sprintf(f, a...), d)
}
-func (l Logger) Errordf(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Errordf(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_ERROR, fmt.Sprintf(f, a...), d)
}
-func (l Logger) Warndf(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Warndf(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_WARN, fmt.Sprintf(f, a...), d)
}
-func (l Logger) Infodf(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Infodf(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_INFO, fmt.Sprintf(f, a...), d)
}
-func (l Logger) Debugdf(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Debugdf(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_DEBUG, fmt.Sprintf(f, a...), d)
}
-func (l Logger) Debug1df(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Debug1df(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_DEBUG1, fmt.Sprintf(f, a...), d)
}
-func (l Logger) Debug2df(d map[string]interface{}, f string, a ...interface{}) {
+func (l *Logger) Debug2df(d map[string]interface{}, f string, a ...interface{}) {
l.Log(LOG_DEBUG2, fmt.Sprintf(f, a...), d)
}
View
62 logger_test.go
@@ -76,15 +76,69 @@ func (s *LoggerSuite) TestLevelVisibility(c *C) {
func (s *LoggerSuite) TestCreatingDupLogger(c *C) {
logger1 := NewLogger("foobar")
logger2 := NewLogger("foobar")
- c.Assert(logger1, Equals, logger2)
+ c.Assert(logger1, DeepEquals, logger2)
}
func (s *LoggerSuite) TestPanic(c *C) {
logger := NewLogger("foobar")
c.Assert(func() { logger.Fatal("fail!") }, PanicMatches, "fail!")
c.Assert(func() { logger.Fatalf("fail!%s", "fail!") }, PanicMatches, "fail!fail!")
+}
+
+var logWithDataExamples = []struct {
+ A, B, R map[string]interface{}
+}{
+ {
+ A: map[string]interface{}{"foo": "bar"},
+ B: nil,
+ R: map[string]interface{}{"foo": "bar"},
+ },
+ {
+ A: nil,
+ B: map[string]interface{}{"foo": "bar"},
+ R: map[string]interface{}{"foo": "bar"},
+ },
+ {
+ A: map[string]interface{}{"foo": "qux"},
+ B: map[string]interface{}{"foo": "bar"},
+ R: map[string]interface{}{"foo": "bar"},
+ },
+ {
+ A: map[string]interface{}{"foo": "qux", "baz": "zap"},
+ B: map[string]interface{}{"foo": "bar"},
+ R: map[string]interface{}{"foo": "bar", "baz": "zap"},
+ },
+}
+
+func (s *LoggerSuite) TestLogWithData(c *C) {
+ for _, e := range logWithDataExamples {
+ n := newNullSink()
+ l := NewLogger("logger")
+ l.L.(*BaseLogger).sinks = []Sink{n}
+
+ l.d = e.A
+ l.Log(LOG_INFO, "message", e.B)
+
+ c.Check(n.records[0].Data, DeepEquals, e.R)
+ }
+}
+
+func (s *LoggerSuite) TestLoggerSetGet(c *C) {
+ l := NewLogger("logger")
+ l.Set("key", "value")
+ c.Check(l.Get("key"), Equals, "value")
+}
+
+func (s *LoggerSuite) TestLoggerCopy(c *C) {
+ x := NewLogger("logger")
+ x.Set("key", "value")
+
+ y := x.Copy()
+ c.Check(y.Get("key"), Equals, "value")
+
+ y.Set("key", "other_value")
+ c.Check(y.Get("key"), Equals, "other_value")
- t := NewTaggedLogger(logger, map[string]interface{}{"foo": "bar"})
- c.Assert(func() { t.Fatal("panic") }, PanicMatches, "panic")
- c.Assert(func() { t.Fatalf("panic!%s", "panic!") }, PanicMatches, "panic!panic!")
+ // The original logger should be left unchanged
+ c.Check(x.Get("key"), Equals, "value")
}
View
2 perf_test.go
@@ -47,7 +47,7 @@ func BenchmarkTaggedLoggerInDevNullSink(b *testing.B) {
performBenchmark(logger, b)
}
-func performBenchmark(logger Logger, b *testing.B) {
+func performBenchmark(logger *Logger, b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
logger.Fatal("Hello, world.")
View
4 steno.go
@@ -38,7 +38,7 @@ func Init(c *Config) {
}
}
-func NewLogger(name string) Logger {
+func NewLogger(name string) *Logger {
loggersMutex.Lock()
defer loggersMutex.Unlock()
@@ -54,7 +54,7 @@ func NewLogger(name string) Logger {
l = bl
}
- return Logger{l}
+ return &Logger{L: l}
}
func loggersInJson() string {
View
6 tagged_logger.go
@@ -1,18 +1,18 @@
package steno
type TaggedLogger struct {
- Logger
+ *Logger
d map[string]interface{}
}
-func NewTaggedLogger(l Logger, d map[string]interface{}) Logger {
+func NewTaggedLogger(l *Logger, d map[string]interface{}) *Logger {
tl := &TaggedLogger{
Logger: l,
d: d,
}
- return Logger{tl}
+ return &Logger{L: tl}
}
func (l *TaggedLogger) Log(x LogLevel, m string, d map[string]interface{}) {

0 comments on commit b5e9451

Please sign in to comment.