-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlogger.go
131 lines (114 loc) · 3.05 KB
/
logger.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package log
import (
"fmt"
goLog "log"
"os"
"testing"
"time"
)
// Logger provides pluggable logging for Arcalot.
type Logger interface {
// Debugf logs with the debug log level. This is the finest and least-consequential log type.
Debugf(format string, args ...interface{})
// Infof logs with the Info log level.
Infof(format string, args ...interface{})
// Warningf logs with the Warning log level.
Warningf(format string, args ...interface{})
// Errorf logs with the Error log level.
Errorf(format string, args ...interface{})
// Writef allows logging with convenient programmatic setting of level
Writef(level Level, format string, args ...interface{})
// WithLabel creates a child logger with this label attached.
WithLabel(name string, value string) Logger
}
func New(config Config) Logger {
if err := config.Validate(); err != nil {
panic(err)
}
writer := newWriter(config)
return NewLogger(config.Level, writer)
}
func newWriter(config Config) Writer {
switch config.Destination {
case DestinationStdout:
out := config.Stdout
if out == nil {
out = os.Stdout
}
logger := goLog.New(out, "", 0)
return NewGoLogWriter(logger)
case DestinationTest:
return NewTestWriter(config.T)
default:
panic(fmt.Errorf("invalid destination: %s", config.Destination))
}
}
// NewLogger creates a new logger with the specified minimum level and target writer.
func NewLogger(minLevel Level, writer Writer) Logger {
return &logger{
minLevel,
writer,
map[string]string{},
}
}
// NewTestLogger creates a logger that writes to the Go test output.
func NewTestLogger(t *testing.T) Logger {
return NewLogger(
LevelDebug,
NewTestWriter(t),
)
}
// NewGoLogger writes to the Go log facility. If no logger is passed, the standard logger is used.
func NewGoLogger(minimumLevel Level, logger ...*goLog.Logger) Logger {
return NewLogger(
minimumLevel,
NewGoLogWriter(logger...),
)
}
type logger struct {
minLevel Level
writer Writer
labels Labels
}
func (l logger) Debugf(format string, args ...interface{}) {
l.Writef(LevelDebug, format, args...)
}
func (l logger) Infof(format string, args ...interface{}) {
l.Writef(LevelInfo, format, args...)
}
func (l logger) Warningf(format string, args ...interface{}) {
l.Writef(LevelWarning, format, args...)
}
func (l logger) Errorf(format string, args ...interface{}) {
l.Writef(LevelError, format, args...)
}
func (l logger) Writef(level Level, message string, args ...interface{}) {
if !l.minLevel.ShouldPrint(level) {
return
}
if err := l.writer.Write(Message{
Timestamp: time.Now(),
Level: level,
Labels: l.labels,
Message: fmt.Sprintf(message, args...),
}); err != nil {
panic(err)
}
}
func (l logger) WithLabel(name string, value string) Logger {
var newLabels Labels
if _, contains := l.labels[name]; contains {
newLabels = make(Labels, len(l.labels))
} else {
newLabels = make(Labels, len(l.labels)+1)
}
for k, v := range l.labels {
newLabels[k] = v
}
newLabels[name] = value
return &logger{
minLevel: l.minLevel,
writer: l.writer,
labels: newLabels,
}
}