forked from mailgun/log
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.go
173 lines (145 loc) · 4.43 KB
/
log.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
package log
import (
"fmt"
"io"
)
type grouplogger struct {
loggers []Logger
}
var gl grouplogger
// Supported log types.
const (
Console = "console"
Syslog = "syslog"
UDPLog = "udplog"
)
// Logger is an interface that should be implemented by all loggers wishing to participate
// in the logger chain initialized by this package.
type Logger interface {
// Writer returns logger's underlying io.Writer used to write log messages to.
//
// It may be, for example, the standard output for a console logger or a socket
// connection for a UDP logger.
//
// Should return `nil` if the logger is not supposed to log at the specified severity.
Writer(Severity) io.Writer
// FormatMessage constructs and returns a final message that will go to the logger's
// output channel.
FormatMessage(Severity, *CallerInfo, string, ...interface{}) string
// Sets a loggers current Severity level.
SetSeverity(Severity)
// Gets the current Severity level.
GetSeverity() Severity
}
// Config represents a configuration of an individual logger.
type Config struct {
// Name is a logger's identificator used to instantiate a proper logger type
// from a config.
Name string
// Severity indicates the minimum severity a logger will be logging messages at.
Severity string
}
// Init initializes the logging package with the provided loggers.
func Init(l ...Logger) {
for _, logger := range l {
gl.loggers = append(gl.loggers, logger)
}
}
// InitWithConfig instantiates loggers based on the provided configs and initializes
// the package with them.
func InitWithConfig(configs ...Config) error {
for _, config := range configs {
l, err := NewLogger(config)
if err != nil {
return err
}
gl.loggers = append(gl.loggers, l)
}
return nil
}
// NewLogger makes a proper logger from the given configuration.
func NewLogger(config Config) (Logger, error) {
switch config.Name {
case Console:
return NewConsoleLogger(config)
case Syslog:
return NewSysLogger(config)
case UDPLog:
return NewUDPLogger(config)
}
return nil, fmt.Errorf("unknown logger: %v", config)
}
func SetSeverity(sev Severity) {
gl.SetSeverity(sev)
}
func (gl *grouplogger) SetSeverity(sev Severity) {
for _, logger := range gl.loggers {
logger.SetSeverity(sev)
}
}
// Debugf logs to the DEBUG log.
func Debugf(format string, args ...interface{}) {
gl.Debugf(format, args...)
}
func (gl *grouplogger) Debugf(format string, args ...interface{}) {
for _, logger := range gl.loggers {
writeMessage(logger, 2, SeverityDebug, format, args...)
}
}
// Infof logs to the INFO log.
func Infof(format string, args ...interface{}) {
gl.Infof(format, args...)
}
func (gl *grouplogger) Infof(format string, args ...interface{}) {
for _, logger := range gl.loggers {
writeMessage(logger, 2, SeverityInfo, format, args...)
}
}
// Warningf logs to the WARN and INFO logs.
func Warningf(format string, args ...interface{}) {
gl.Warningf(format, args...)
}
func (gl *grouplogger) Warningf(format string, args ...interface{}) {
for _, logger := range gl.loggers {
writeMessage(logger, 2, SeverityWarning, format, args...)
}
}
// Errorf logs to the ERROR, WARN, and INFO logs.
func Errorf(format string, args ...interface{}) {
gl.Errorf(format, args...)
}
func (gl *grouplogger) Errorf(format string, args ...interface{}) {
for _, logger := range gl.loggers {
writeMessage(logger, 2, SeverityError, format, args...)
}
}
// Logfmt logs a formatted message of the specified severity, marking it
// attributed to a function at the specified depth on the current goroutine
// stack.
func Logfmt(callDepth int, sev Severity, format string, args ...interface{}) {
gl.Logf(callDepth, sev, format, args...)
}
func (gl *grouplogger) Logf(callDepth int, sev Severity, format string, args ...interface{}) {
caller := getCallerInfo(callDepth + 2)
for _, logger := range gl.loggers {
if w := logger.Writer(sev); w != nil {
message := logger.FormatMessage(sev, caller, format, args...)
io.WriteString(w, message)
}
}
}
func writeMessage(logger Logger, callDepth int, sev Severity, format string, args ...interface{}) {
caller := getCallerInfo(callDepth + 1)
if w := logger.Writer(sev); w != nil {
message := logger.FormatMessage(sev, caller, format, args...)
io.WriteString(w, message)
}
}
type LogWriter interface {
Infof(format string, args ...interface{})
Warningf(format string, args ...interface{})
Errorf(format string, args ...interface{})
}
func GetGlobalLogger() LogWriter {
return &gl
}