-
Notifications
You must be signed in to change notification settings - Fork 4
/
gelf.go
102 lines (90 loc) · 2.39 KB
/
gelf.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
package formatters
import (
"encoding/json"
"log/syslog"
"runtime"
"time"
"github.com/sirupsen/logrus"
)
const (
// GelfVersion is the supported gelf version
GelfVersion = "1.1"
)
var (
levelMap map[logrus.Level]syslog.Priority
syslogNameMap map[syslog.Priority]string
protectedFields map[string]bool
// DefaultLevel is the default syslog level to use if the logrus level does not map to a syslog level
DefaultLevel = syslog.LOG_INFO
)
func init() {
levelMap = map[logrus.Level]syslog.Priority{
logrus.PanicLevel: syslog.LOG_EMERG,
logrus.FatalLevel: syslog.LOG_CRIT,
logrus.ErrorLevel: syslog.LOG_ERR,
logrus.WarnLevel: syslog.LOG_WARNING,
logrus.InfoLevel: syslog.LOG_INFO,
logrus.DebugLevel: syslog.LOG_DEBUG,
}
syslogNameMap = map[syslog.Priority]string{
syslog.LOG_EMERG: "EMERGENCY",
syslog.LOG_ALERT: "ALERT",
syslog.LOG_CRIT: "CRITICAL",
syslog.LOG_ERR: "ERROR",
syslog.LOG_WARNING: "WARNING",
syslog.LOG_NOTICE: "NOTICE",
syslog.LOG_INFO: "INFORMATIONAL",
syslog.LOG_DEBUG: "DEBUGGING",
}
protectedFields = map[string]bool{
"version": true,
"host": true,
"short_message": true,
"full_message": true,
"timestamp": true,
"level": true,
}
}
type gelfFormatter struct {
hostname string
}
// NewGelf returns a new logrus / gelf-compliant formatter
func NewGelf(hostname string) gelfFormatter {
return gelfFormatter{hostname: hostname}
}
// Format implements logrus formatter
func (f gelfFormatter) Format(entry *logrus.Entry) ([]byte, error) {
level := toSyslogLevel(entry.Level)
gelfEntry := map[string]interface{}{
"version": GelfVersion,
"short_message": entry.Message,
"level": level,
"timestamp": toTimestamp(entry.Time),
"host": f.hostname,
"_level_name": syslogNameMap[level],
}
if _, file, line, ok := runtime.Caller(5); ok {
gelfEntry["_file"] = file
gelfEntry["_line"] = line
}
for key, value := range entry.Data {
if !protectedFields[key] {
key = "_" + key
}
gelfEntry[key] = value
}
message, err := json.Marshal(gelfEntry)
return append(message, '\n'), err
}
func toTimestamp(t time.Time) float64 {
nanosecond := float64(t.Nanosecond()) / 1e9
seconds := float64(t.Unix())
return seconds + nanosecond
}
func toSyslogLevel(level logrus.Level) syslog.Priority {
syslog, ok := levelMap[level]
if ok {
return syslog
}
return DefaultLevel
}