This repository has been archived by the owner on Nov 26, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
logging.go
182 lines (162 loc) · 4.39 KB
/
logging.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
// package logging implements a Logger that, when nil, forwards to the
// corresponding functions in the standard log package. When not nil,
// it captures log calls in a buffer for later inspection. This can be
// useful when needing to inspect or squelch log output from test code.
// The main advantage to this approach is that it is not necessary to
// provide a non-nil instance in 'constructor' functions or wireup for
// production code. It is also still trivial to set a non-nil reference
// in test code.
package logging
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"os"
)
// Logger is meant be included as a pointer field on a struct. Leaving the
// instance as a nil reference will cause any calls on the *Logger to forward
// to the corresponding functions from the standard log package. This is meant
// to be the behavior in production. In testing, set the field to a non-nil
// instance of a *Logger to record log statements for later inspection.
type Logger struct {
*log.Logger
Log *bytes.Buffer
Calls int
}
// Capture creates a new *Logger instance with a multi writer containing an
// internal buffer as well as any other writers provided as arguments. The
// prefix and flags default to the values of log.Prefix() and log.Flags(),
// respectively. This function is meant to be called from test code. See the
// godoc of the Logger struct for details.
func Capture(writers ...io.Writer) *Logger {
out := new(bytes.Buffer)
writers = append(writers, out)
multi := io.MultiWriter(writers...)
return &Logger{
Log: out,
Logger: log.New(multi, log.Prefix(), log.Flags()),
}
}
// Discard creates a new *Logger instance with its internal buffer set to
// ioutil.Discard. This is useful if you want your production code to be
// quiet but your test code to be verbose. In that case, use Discard()
// in production code and Capture() in test code.
func Discard() *Logger {
return &Logger{
Log: new(bytes.Buffer),
Logger: log.New(ioutil.Discard, "", 0),
}
}
// SetOutput -> log.SetOutput
func (this *Logger) SetOutput(w io.Writer) {
if this == nil {
log.SetOutput(w)
} else {
this.Logger.SetOutput(w)
}
}
// Output -> log.Output
func (this *Logger) Output(calldepth int, s string) error {
if this == nil {
return log.Output(calldepth, s)
}
this.Calls++
return this.Logger.Output(calldepth, s)
}
// Fatal -> log.Fatal (except in testing it uses log.Print)
func (this *Logger) Fatal(v ...interface{}) {
s := fmt.Sprint(v...)
if this == nil {
_ = this.Output(3, s)
os.Exit(1)
} else {
_ = this.Logger.Output(2, s)
}
}
// Fatalf -> log.Fatalf (except in testing it uses log.Printf)
func (this *Logger) Fatalf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
if this == nil {
_ = this.Output(3, s)
os.Exit(1)
} else {
_ = this.Logger.Output(2, s)
}
}
// Fatalln -> log.Fatalln (except in testing it uses log.Println)
func (this *Logger) Fatalln(v ...interface{}) {
s := fmt.Sprintln(v...)
if this == nil {
_ = this.Output(3, s)
os.Exit(1)
} else {
_ = this.Logger.Output(2, s)
}
}
// Flags -> log.Flags
func (this *Logger) Flags() int {
if this == nil {
return log.Flags()
} else {
return this.Logger.Flags()
}
}
// Panic -> log.Panic
func (this *Logger) Panic(v ...interface{}) {
s := fmt.Sprint(v...)
_ = this.Output(3, s)
panic(s)
}
// Panicf -> log.Panicf
func (this *Logger) Panicf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
_ = this.Output(3, s)
panic(s)
}
// Panicln -> log.Panicln
func (this *Logger) Panicln(v ...interface{}) {
s := fmt.Sprintln(v...)
_ = this.Output(3, s)
panic(s)
}
// Prefix -> log.Prefix
func (this *Logger) Prefix() string {
if this == nil {
return log.Prefix()
} else {
return this.Logger.Prefix()
}
}
// Print -> log.Print
func (this *Logger) Print(v ...interface{}) {
s := fmt.Sprint(v...)
_ = this.Output(3, s)
}
// Printf -> log.Printf
func (this *Logger) Printf(format string, v ...interface{}) {
s := fmt.Sprintf(format, v...)
_ = this.Output(3, s)
}
// Println -> log.Println
func (this *Logger) Println(v ...interface{}) {
s := fmt.Sprintln(v...)
_ = this.Output(3, s)
}
// SetFlags -> log.SetFlags
func (this *Logger) SetFlags(flag int) {
if this == nil {
log.SetFlags(flag)
} else {
this.Logger.SetFlags(flag)
}
}
// SetPrefix -> log.SetPrefix
func (this *Logger) SetPrefix(prefix string) {
if this == nil {
log.SetPrefix(prefix)
} else {
this.Logger.SetPrefix(prefix)
}
}