-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlogger.go
221 lines (187 loc) · 5.76 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// Copyright (c) 2012-2016 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
package mlog
import (
"fmt"
"io"
"os"
"sync"
"sync/atomic"
)
// Emitter is the interface implemented by mlog logging format writers.
type Emitter interface {
Emit(logger *Logger, level int, message string, extra Map)
EmitAttrs(logger *Logger, level int, message string, extra ...*Attr)
}
// A Logger represents a logging object, that embeds log.Logger, and
// provides support for a toggle-able debug flag.
type Logger struct {
out io.Writer
e Emitter
mu sync.Mutex // ensures atomic writes are synchronized
flags uint64
}
// SetOutput sets the Logger output io.Writer
func (l *Logger) SetOutput(writer io.Writer) {
// lock writing to serialize log output (no scrambled log lines)
l.mu.Lock()
defer l.mu.Unlock()
l.out = writer
}
func (l *Logger) Write(b []byte) (int, error) {
// lock writing to serialize log output (no scrambled log lines)
l.mu.Lock()
defer l.mu.Unlock()
return l.out.Write(b)
}
// Emit invokes the FormatWriter and logs the event.
func (l *Logger) Emit(level int, message string, extra Map) {
l.e.Emit(l, level, message, extra)
}
// Emit invokes the FormatWriter and logs the event.
func (l *Logger) EmitAttrs(level int, message string, extra ...*Attr) {
l.e.EmitAttrs(l, level, message, extra...)
}
// SetEmitter sets the Emitter
func (l *Logger) SetEmitter(e Emitter) {
l.mu.Lock()
defer l.mu.Unlock()
l.e = e
}
// Flags returns the current FlagSet
func (l *Logger) Flags() FlagSet {
return FlagSet(atomic.LoadUint64(&l.flags))
}
// SetFlags sets the current FlagSet
func (l *Logger) SetFlags(flags FlagSet) {
atomic.StoreUint64(&l.flags, uint64(flags))
}
// HasDebug returns true if the debug logging FlagSet is enabled, false
// otherwise.
func (l *Logger) HasDebug() bool {
flags := FlagSet(atomic.LoadUint64(&l.flags))
return flags&Ldebug != 0
}
// Debugx conditionally logs message and any Attr elements at level="debug".
// If the Logger does not have the Ldebug flag, nothing is logged.
func (l *Logger) Debugx(message string, attrs ...*Attr) {
if l.HasDebug() {
l.EmitAttrs(-1, message, attrs...)
}
}
// Infox logs message and any Map elements at level="info".
func (l *Logger) Infox(message string, attrs ...*Attr) {
l.EmitAttrs(0, message, attrs...)
}
// Printx logs message and any Map elements at level="info".
func (l *Logger) Printx(message string, attrs ...*Attr) {
l.EmitAttrs(0, message, attrs...)
}
// Fatalx logs message and any Map elements at level="fatal", then calls
// os.Exit(1)
func (l *Logger) Fatalx(message string, attrs ...*Attr) {
l.EmitAttrs(1, message, attrs...)
os.Exit(1)
}
// Panicx logs message and any Map elements at level="fatal", then calls
// panic().
func (l *Logger) Panicx(message string, attrs ...*Attr) {
l.EmitAttrs(1, message, attrs...)
panic(message)
}
// Debugm conditionally logs message and any Map elements at level="debug".
// If the Logger does not have the Ldebug flag, nothing is logged.
func (l *Logger) Debugm(message string, v Map) {
if l.HasDebug() {
l.Emit(-1, message, v)
}
}
// Infom logs message and any Map elements at level="info".
func (l *Logger) Infom(message string, v Map) {
l.Emit(0, message, v)
}
// Printm logs message and any Map elements at level="info".
func (l *Logger) Printm(message string, v Map) {
l.Emit(0, message, v)
}
// Fatalm logs message and any Map elements at level="fatal", then calls
// os.Exit(1)
func (l *Logger) Fatalm(message string, v Map) {
l.Emit(1, message, v)
os.Exit(1)
}
// Panicm logs message and any Map elements at level="fatal", then calls
// panic().
func (l *Logger) Panicm(message string, v Map) {
l.Emit(1, message, v)
panic(message)
}
// Debugf formats and conditionally logs message at level="debug".
// If the Logger does not have the Ldebug flag, nothing is logged.
func (l *Logger) Debugf(format string, v ...interface{}) {
if l.HasDebug() {
l.Emit(-1, fmt.Sprintf(format, v...), nil)
}
}
// Infof formats and logs message at level="info".
func (l *Logger) Infof(format string, v ...interface{}) {
l.Emit(0, fmt.Sprintf(format, v...), nil)
}
// Printf formats and logs message at level="info".
func (l *Logger) Printf(format string, v ...interface{}) {
l.Emit(0, fmt.Sprintf(format, v...), nil)
}
// Fatalf formats and logs message at level="fatal", then calls
// os.Exit(1)
func (l *Logger) Fatalf(format string, v ...interface{}) {
l.Emit(1, fmt.Sprintf(format, v...), nil)
os.Exit(1)
}
// Panicf formats and logs message at level="fatal", then calls
// panic().
func (l *Logger) Panicf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
l.Emit(1, s, nil)
panic(s)
}
// Debug conditionally logs message at level="debug".
// If the Logger does not have the Ldebug flag, nothing is logged.
func (l *Logger) Debug(v ...interface{}) {
if l.HasDebug() {
l.Emit(-1, fmt.Sprint(v...), nil)
}
}
// Info logs message at level="info".
func (l *Logger) Info(v ...interface{}) {
l.Emit(0, fmt.Sprint(v...), nil)
}
// Print logs message at level="info".
func (l *Logger) Print(v ...interface{}) {
l.Emit(0, fmt.Sprint(v...), nil)
}
// Fatal logs message at level="fatal", then calls
// os.Exit(1)
func (l *Logger) Fatal(v ...interface{}) {
l.Emit(1, fmt.Sprint(v...), nil)
os.Exit(1)
}
// Panic logs message at level="fatal", then calls
// panic().
func (l *Logger) Panic(v ...interface{}) {
s := fmt.Sprint(v...)
l.Emit(1, s, nil)
panic(s)
}
// New creates a new Logger.
func New(out io.Writer, flags FlagSet) *Logger {
return NewFormatLogger(out, flags, &FormatWriterStructured{})
}
// NewFormatLogger creates a new Logger, using the specified Emitter.
func NewFormatLogger(out io.Writer, flags FlagSet, e Emitter) *Logger {
return &Logger{
out: out,
flags: uint64(flags),
e: e,
}
}