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
|
package logging
import (
"github.com/icinga/icingadb/pkg/utils"
"github.com/pkg/errors"
"github.com/ssgreg/journald"
"go.uber.org/zap/zapcore"
"strings"
"unicode"
)
// priorities maps zapcore.Level to journal.Priority.
var priorities = map[zapcore.Level]journald.Priority{
zapcore.DebugLevel: journald.PriorityDebug,
zapcore.InfoLevel: journald.PriorityInfo,
zapcore.WarnLevel: journald.PriorityWarning,
zapcore.ErrorLevel: journald.PriorityErr,
zapcore.FatalLevel: journald.PriorityCrit,
zapcore.PanicLevel: journald.PriorityCrit,
zapcore.DPanicLevel: journald.PriorityCrit,
}
// NewJournaldCore returns a zapcore.Core that sends log entries to systemd-journald and
// uses the given identifier as a prefix for structured logging context that is sent as journal fields.
func NewJournaldCore(identifier string, enab zapcore.LevelEnabler) zapcore.Core {
return &journaldCore{
LevelEnabler: enab,
identifier: identifier,
identifierU: strings.ToUpper(identifier),
}
}
type journaldCore struct {
zapcore.LevelEnabler
context []zapcore.Field
identifier string
identifierU string
}
func (c *journaldCore) Check(ent zapcore.Entry, ce *zapcore.CheckedEntry) *zapcore.CheckedEntry {
if c.Enabled(ent.Level) {
return ce.AddCore(ent, c)
}
return ce
}
func (c *journaldCore) Sync() error {
return nil
}
func (c *journaldCore) With(fields []zapcore.Field) zapcore.Core {
cc := *c
cc.context = append(cc.context[:len(cc.context):len(cc.context)], fields...)
return &cc
}
func (c *journaldCore) Write(ent zapcore.Entry, fields []zapcore.Field) error {
pri, ok := priorities[ent.Level]
if !ok {
return errors.Errorf("unknown log level %q", ent.Level)
}
enc := zapcore.NewMapObjectEncoder()
c.addFields(enc, fields)
c.addFields(enc, c.context)
enc.Fields["SYSLOG_IDENTIFIER"] = c.identifier
message := ent.Message
if ent.LoggerName != c.identifier {
message = ent.LoggerName + ": " + message
}
return journald.Send(message, pri, enc.Fields)
}
func (c *journaldCore) addFields(enc zapcore.ObjectEncoder, fields []zapcore.Field) {
for _, field := range fields {
field.Key = c.identifierU +
"_" +
utils.ConvertCamelCase(field.Key, unicode.UpperCase, '_')
field.AddTo(enc)
}
}
|