forked from elastic/beats
-
Notifications
You must be signed in to change notification settings - Fork 1
/
log_unix.go
145 lines (123 loc) · 3.49 KB
/
log_unix.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
// +build !windows
package main
import (
"fmt"
"log"
"log/syslog"
"os"
"runtime/debug"
)
type Priority int
const (
// Severity.
// From /usr/include/sys/syslog.h.
// These are the same on Linux, BSD, and OS X.
LOG_EMERG Priority = iota
LOG_ALERT
LOG_CRIT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG
)
type Logger struct {
toSyslog bool
level syslog.Priority
selectors map[string]bool
logger *log.Logger
syslog [syslog.LOG_DEBUG + 1]*log.Logger
}
var _log Logger
func DEBUG(selector string, format string, v ...interface{}) {
if _log.level >= syslog.LOG_DEBUG {
selected := _log.selectors[selector]
if !selected {
return
}
if _log.toSyslog {
_log.syslog[syslog.LOG_INFO].Output(2, fmt.Sprintf(format, v...))
} else {
_log.logger.Output(2, fmt.Sprintf("DBG "+format, v...))
}
}
}
func IS_DEBUG(selector string) bool {
return _log.selectors[selector]
}
func INFO(format string, v ...interface{}) {
if _log.level >= syslog.LOG_INFO {
if _log.toSyslog {
_log.syslog[syslog.LOG_INFO].Output(2, fmt.Sprintf(format, v...))
} else {
_log.logger.Output(2, fmt.Sprintf("INFO "+format, v...))
}
}
}
func WARN(format string, v ...interface{}) {
if _log.level >= syslog.LOG_WARNING {
if _log.toSyslog {
_log.syslog[syslog.LOG_WARNING].Output(2, fmt.Sprintf(format, v...))
} else {
_log.logger.Output(2, fmt.Sprintf("WARN "+format, v...))
}
}
}
func ERR(format string, v ...interface{}) {
if _log.level >= syslog.LOG_ERR {
if _log.toSyslog {
_log.syslog[syslog.LOG_ERR].Output(2, fmt.Sprintf(format, v...))
} else {
_log.logger.Output(2, fmt.Sprintf("ERR "+format, v...))
}
}
}
func CRIT(format string, v ...interface{}) {
if _log.level >= syslog.LOG_CRIT {
if _log.toSyslog {
_log.syslog[syslog.LOG_CRIT].Output(2, fmt.Sprintf(format, v...))
} else {
_log.logger.Output(2, fmt.Sprintf("CRIT "+format, v...))
}
}
}
func WTF(format string, v ...interface{}) {
if _log.level >= syslog.LOG_CRIT {
if _log.toSyslog {
_log.syslog[syslog.LOG_CRIT].Output(2, fmt.Sprintf(format, v...))
} else {
_log.logger.Output(2, fmt.Sprintf("CRIT "+format, v...))
}
}
// TODO: assert here when not in production mode
}
func RECOVER(msg string) {
if r := recover(); r != nil {
ERR("%s. Recovering, but please report this: %s.", msg, r)
ERR("Stacktrace: %s", debug.Stack())
}
}
func openSyslog(level syslog.Priority, prefix string) *log.Logger {
logger, err := syslog.NewLogger(level, log.Lshortfile)
if err != nil {
fmt.Println("Error opening syslog: ", err)
return nil
}
logger.SetPrefix(prefix)
return logger
}
func LogInit(level Priority, prefix string, toSyslog bool, debugSelectors []string) {
_log.toSyslog = toSyslog
_log.level = syslog.Priority(level)
_log.selectors = make(map[string]bool)
for _, selector := range debugSelectors {
_log.selectors[selector] = true
}
if _log.toSyslog {
for prio := syslog.LOG_EMERG; prio <= syslog.LOG_DEBUG; prio++ {
_log.syslog[prio] = openSyslog(prio, prefix)
}
} else {
_log.logger = log.New(os.Stdout, prefix, log.Lshortfile)
}
}