-
Notifications
You must be signed in to change notification settings - Fork 145
/
logger.go
91 lines (76 loc) · 2.65 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
package core
import (
"log"
"os"
"runtime/debug"
"strings"
)
// ConfigLogger is the key for the pipeline's logger
const ConfigLogger = "Core.Logger"
// Logger defines the output interface used by Hercules components.
type Logger interface {
Info(...interface{})
Infof(string, ...interface{})
Warn(...interface{})
Warnf(string, ...interface{})
Error(...interface{})
Errorf(string, ...interface{})
Critical(...interface{})
Criticalf(string, ...interface{})
}
// DefaultLogger is the default logger used by a pipeline, and wraps the standard
// log library.
type DefaultLogger struct {
I *log.Logger
W *log.Logger
E *log.Logger
}
// NewLogger returns a configured default logger.
func NewLogger() *DefaultLogger {
return &DefaultLogger{
I: log.New(os.Stderr, "[INFO] ", log.LstdFlags),
W: log.New(os.Stderr, "[WARN] ", log.LstdFlags),
E: log.New(os.Stderr, "[ERROR] ", log.LstdFlags),
}
}
// Info writes to "info" logger.
func (d *DefaultLogger) Info(v ...interface{}) { d.I.Println(v...) }
// Infof writes to "info" logger with printf-style formatting.
func (d *DefaultLogger) Infof(f string, v ...interface{}) { d.I.Printf(f, v...) }
// Warn writes to the "warning" logger.
func (d *DefaultLogger) Warn(v ...interface{}) { d.W.Println(v...) }
// Warnf writes to the "warning" logger with printf-style formatting.
func (d *DefaultLogger) Warnf(f string, v ...interface{}) { d.W.Printf(f, v...) }
// Error writes to the "error" logger.
func (d *DefaultLogger) Error(v ...interface{}) { d.E.Println(v...) }
// Errorf writes to the "error" logger with printf-style formatting.
func (d *DefaultLogger) Errorf(f string, v ...interface{}) { d.E.Printf(f, v...) }
// Critical writes to the "error" logger and logs the current stacktrace.
func (d *DefaultLogger) Critical(v ...interface{}) {
d.E.Println(v...)
d.logStacktraceToErr()
}
// Criticalf writes to the "error" logger with printf-style formatting and logs the
// current stacktrace.
func (d *DefaultLogger) Criticalf(f string, v ...interface{}) {
d.E.Printf(f, v...)
d.logStacktraceToErr()
}
// logStacktraceToErr prints a stacktrace to the logger's error output.
// It skips 4 levels that aren't meaningful to a logged stacktrace:
// * debug.Stack()
// * core.captureStacktrace()
// * DefaultLogger::logStacktraceToErr()
// * DefaultLogger::Error() or DefaultLogger::Errorf()
func (d *DefaultLogger) logStacktraceToErr() {
d.E.Println("stacktrace:\n" + strings.Join(captureStacktrace(4), "\n"))
}
func captureStacktrace(skip int) []string {
stack := string(debug.Stack())
lines := strings.Split(stack, "\n")
linesToSkip := 2*skip + 1
if linesToSkip > len(lines) {
return lines
}
return lines[linesToSkip:]
}