forked from ssgreg/journalhook
-
Notifications
You must be signed in to change notification settings - Fork 0
/
journalhook.go
87 lines (73 loc) · 2.33 KB
/
journalhook.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
// Copyright 2017 Grigory Zubankov. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.
//
package journalhook
import (
"errors"
"strings"
"github.com/sirupsen/logrus"
"github.com/ssgreg/journald"
)
var errJournalMissing = errors.New("systemd journal is not exist")
// NormalizeFieldName returns field name acceptable by journald.
func NormalizeFieldName(s string) string {
return strings.ToUpper(strings.Replace(s, "-", "_", -1))
}
// NewJournalHookWithLevels creates a hook to be added to an instance of logger.
// It's also allowed to specify logrus levels to fire events for.
func NewJournalHookWithLevels(levels []logrus.Level) (*JournalHook, error) {
if journald.IsNotExist() {
return nil, errJournalMissing
}
j := &journald.Journal{
NormalizeFieldNameFn: NormalizeFieldName,
}
// Register an exit handler to be sure that journal connection will
// be successfully closed and no log entries will be lost.
// Client should call logrus.Exit() at exit.
logrus.RegisterExitHandler(func() {
j.Close()
})
return &JournalHook{
Journal: j,
LogrusLevels: levels,
Formatter: &SyslogFormatter{},
}, nil
}
// NewJournalHook creates a hook to be added to an instance of logger.
func NewJournalHook() (*JournalHook, error) {
return NewJournalHookWithLevels(logrus.AllLevels)
}
// JournalHook is the systemd-journald hook for logrus.
type JournalHook struct {
Journal *journald.Journal
LogrusLevels []logrus.Level
Formatter logrus.Formatter
}
// Fire writes a log entry to the systemd journal.
func (h *JournalHook) Fire(entry *logrus.Entry) error {
line, _ := h.Formatter.Format(entry)
return h.Journal.Send(string(line), levelToPriority(entry.Level), entry.Data)
}
// Levels returns a slice of Levels the hook is fired for.
func (h *JournalHook) Levels() []logrus.Level {
return h.LogrusLevels
}
func levelToPriority(l logrus.Level) journald.Priority {
switch l {
case logrus.DebugLevel, logrus.TraceLevel:
return journald.PriorityDebug
case logrus.InfoLevel:
return journald.PriorityInfo
case logrus.WarnLevel:
return journald.PriorityWarning
case logrus.ErrorLevel:
return journald.PriorityErr
case logrus.FatalLevel:
return journald.PriorityCrit
case logrus.PanicLevel:
return journald.PriorityEmerg
}
return journald.PriorityNotice
}