podman

Форк
0
225 строк · 5.4 Кб
1
// Copyright © 2016 Steve Francia <spf@spf13.com>.
2
//
3
// Use of this source code is governed by an MIT-style
4
// license that can be found in the LICENSE file.
5

6
package jwalterweatherman
7

8
import (
9
	"fmt"
10
	"io"
11
	"io/ioutil"
12
	"log"
13
)
14

15
type Threshold int
16

17
func (t Threshold) String() string {
18
	return prefixes[t]
19
}
20

21
const (
22
	LevelTrace Threshold = iota
23
	LevelDebug
24
	LevelInfo
25
	LevelWarn
26
	LevelError
27
	LevelCritical
28
	LevelFatal
29
)
30

31
var prefixes map[Threshold]string = map[Threshold]string{
32
	LevelTrace:    "TRACE",
33
	LevelDebug:    "DEBUG",
34
	LevelInfo:     "INFO",
35
	LevelWarn:     "WARN",
36
	LevelError:    "ERROR",
37
	LevelCritical: "CRITICAL",
38
	LevelFatal:    "FATAL",
39
}
40

41
// Notepad is where you leave a note!
42
type Notepad struct {
43
	TRACE    *log.Logger
44
	DEBUG    *log.Logger
45
	INFO     *log.Logger
46
	WARN     *log.Logger
47
	ERROR    *log.Logger
48
	CRITICAL *log.Logger
49
	FATAL    *log.Logger
50

51
	LOG      *log.Logger
52
	FEEDBACK *Feedback
53

54
	loggers         [7]**log.Logger
55
	logHandle       io.Writer
56
	outHandle       io.Writer
57
	logThreshold    Threshold
58
	stdoutThreshold Threshold
59
	prefix          string
60
	flags           int
61

62
	logListeners []LogListener
63
}
64

65
// A LogListener can ble supplied to a Notepad to listen on log writes for a given
66
// threshold. This can be used to capture log events in unit tests and similar.
67
// Note that this function will be invoked once for each log threshold. If
68
// the given threshold is not of interest to you, return nil.
69
// Note that these listeners will receive log events for a given threshold, even
70
// if the current configuration says not to log it. That way you can count ERRORs even
71
// if you don't print them to the console.
72
type LogListener func(t Threshold) io.Writer
73

74
// NewNotepad creates a new Notepad.
75
func NewNotepad(
76
	outThreshold Threshold,
77
	logThreshold Threshold,
78
	outHandle, logHandle io.Writer,
79
	prefix string, flags int,
80
	logListeners ...LogListener,
81
) *Notepad {
82

83
	n := &Notepad{logListeners: logListeners}
84

85
	n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
86
	n.outHandle = outHandle
87
	n.logHandle = logHandle
88
	n.stdoutThreshold = outThreshold
89
	n.logThreshold = logThreshold
90

91
	if len(prefix) != 0 {
92
		n.prefix = "[" + prefix + "] "
93
	} else {
94
		n.prefix = ""
95
	}
96

97
	n.flags = flags
98

99
	n.LOG = log.New(n.logHandle,
100
		"LOG:   ",
101
		n.flags)
102
	n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
103

104
	n.init()
105
	return n
106
}
107

108
// init creates the loggers for each level depending on the notepad thresholds.
109
func (n *Notepad) init() {
110
	logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
111

112
	for t, logger := range n.loggers {
113
		threshold := Threshold(t)
114
		prefix := n.prefix + threshold.String() + " "
115

116
		switch {
117
		case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
118
			*logger = log.New(n.createLogWriters(threshold, logAndOut), prefix, n.flags)
119

120
		case threshold >= n.logThreshold:
121
			*logger = log.New(n.createLogWriters(threshold, n.logHandle), prefix, n.flags)
122

123
		case threshold >= n.stdoutThreshold:
124
			*logger = log.New(n.createLogWriters(threshold, n.outHandle), prefix, n.flags)
125

126
		default:
127
			*logger = log.New(n.createLogWriters(threshold, ioutil.Discard), prefix, n.flags)
128
		}
129
	}
130
}
131

132
func (n *Notepad) createLogWriters(t Threshold, handle io.Writer) io.Writer {
133
	if len(n.logListeners) == 0 {
134
		return handle
135
	}
136
	writers := []io.Writer{handle}
137
	for _, l := range n.logListeners {
138
		w := l(t)
139
		if w != nil {
140
			writers = append(writers, w)
141
		}
142
	}
143

144
	if len(writers) == 1 {
145
		return handle
146
	}
147

148
	return io.MultiWriter(writers...)
149
}
150

151
// SetLogThreshold changes the threshold above which messages are written to the
152
// log file.
153
func (n *Notepad) SetLogThreshold(threshold Threshold) {
154
	n.logThreshold = threshold
155
	n.init()
156
}
157

158
// SetLogOutput changes the file where log messages are written.
159
func (n *Notepad) SetLogOutput(handle io.Writer) {
160
	n.logHandle = handle
161
	n.init()
162
}
163

164
// GetStdoutThreshold returns the defined Treshold for the log logger.
165
func (n *Notepad) GetLogThreshold() Threshold {
166
	return n.logThreshold
167
}
168

169
// SetStdoutThreshold changes the threshold above which messages are written to the
170
// standard output.
171
func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
172
	n.stdoutThreshold = threshold
173
	n.init()
174
}
175

176
// GetStdoutThreshold returns the Treshold for the stdout logger.
177
func (n *Notepad) GetStdoutThreshold() Threshold {
178
	return n.stdoutThreshold
179
}
180

181
// SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
182
// brackets at the beginning of the line. An empty prefix won't be displayed at all.
183
func (n *Notepad) SetPrefix(prefix string) {
184
	if len(prefix) != 0 {
185
		n.prefix = "[" + prefix + "] "
186
	} else {
187
		n.prefix = ""
188
	}
189
	n.init()
190
}
191

192
// SetFlags choose which flags the logger will display (after prefix and message
193
// level). See the package log for more informations on this.
194
func (n *Notepad) SetFlags(flags int) {
195
	n.flags = flags
196
	n.init()
197
}
198

199
// Feedback writes plainly to the outHandle while
200
// logging with the standard extra information (date, file, etc).
201
type Feedback struct {
202
	out *log.Logger
203
	log *log.Logger
204
}
205

206
func (fb *Feedback) Println(v ...interface{}) {
207
	fb.output(fmt.Sprintln(v...))
208
}
209

210
func (fb *Feedback) Printf(format string, v ...interface{}) {
211
	fb.output(fmt.Sprintf(format, v...))
212
}
213

214
func (fb *Feedback) Print(v ...interface{}) {
215
	fb.output(fmt.Sprint(v...))
216
}
217

218
func (fb *Feedback) output(s string) {
219
	if fb.out != nil {
220
		fb.out.Output(2, s)
221
	}
222
	if fb.log != nil {
223
		fb.log.Output(2, s)
224
	}
225
}
226

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.