@@ -6,59 +6,65 @@ import (
66 "encoding/binary"
77 "io"
88 "log/slog"
9+ "log/syslog"
910 "os"
1011 "path"
1112 "runtime"
1213 "slices"
1314 "strconv"
1415)
1516
16- type Priority int
17-
1817const (
19- priEmerg Priority = iota
20- priAlert
21- priCrit
22- priErr
23- priWarning
24- priNotice
25- priInfo
26- priDebug
27- )
18+ LevelNotice slog.Level = 1
2819
29- const (
30- LevelNotice slog.Level = 1
3120 LevelCritical slog.Level = slog .LevelError + 1
3221 LevelAlert slog.Level = slog .LevelError + 2
3322 LevelEmergency slog.Level = slog .LevelError + 3
3423)
3524
36- func levelToPriority (l slog.Level ) Priority {
25+ func levelToPriority (l slog.Level ) syslog. Priority {
3726 switch l {
3827 case slog .LevelDebug :
39- return priDebug
28+ return syslog . LOG_DEBUG
4029 case slog .LevelInfo :
41- return priInfo
30+ return syslog . LOG_INFO
4231 case LevelNotice :
43- return priNotice
32+ return syslog . LOG_NOTICE
4433 case slog .LevelWarn :
45- return priWarning
34+ return syslog . LOG_WARNING
4635 case slog .LevelError :
47- return priErr
36+ return syslog . LOG_ERR
4837 case LevelCritical :
49- return priCrit
38+ return syslog . LOG_CRIT
5039 case LevelAlert :
51- return priAlert
40+ return syslog .LOG_ALERT
41+ case LevelEmergency :
42+ return syslog .LOG_EMERG
5243 default :
53- panic ( "unreachable" )
44+ return syslog . LOG_INFO
5445 }
5546}
5647
5748type Options struct {
58- Level slog.Leveler
49+ Level slog.Leveler
50+
51+ // ReplaceAttr is called on all non-builtin Attrs before they are written.
52+ // This can be useful for processing attributes to be in the correct format
53+ // for log statements outside of your own code as the journal only accepts
54+ // variables that are uppercase and consist only of characters, numbers and
55+ // underscores, and may not begin with an underscore.
5956 ReplaceAttr func (groups []string , a slog.Attr ) slog.Attr
57+
58+ // ReplaceGroup is called on all group names before they are written. This
59+ // can be useful for processing group names to be in the correct format for
60+ // log statements outside of your own code as the journal only accepts
61+ // variables that are uppercase and consist only of characters, numbers and
62+ // underscores, and may not begin with an underscore.
63+ ReplaceGroup func (group string ) string
6064}
6165
66+ // Handler sends logs to the systemd journal.
67+ // variable names must be in uppercase and consist only of characters, numbers and underscores, and may not begin with an underscore.
6268type Handler struct {
6369 opts Options
6470 // NOTE: We only do single Write() calls. Either the message fits in a
@@ -202,6 +208,9 @@ func (h *Handler) appendAttr(b []byte, prefix string, a slog.Attr) []byte {
202208 // If a group's key is not empty, append the group's key as a prefix.
203209 // Otherwise, if a group's key is empty, inline the group's Attrs.
204210 if a .Key != "" {
211+ if rep := h .opts .ReplaceGroup ; rep != nil {
212+ a .Key = rep (a .Key )
213+ }
205214 prefix += a .Key + "_"
206215 }
207216 for _ , a := range attrs {
@@ -229,6 +238,9 @@ func (h *Handler) WithGroup(name string) slog.Handler {
229238 if name == "" {
230239 return h
231240 }
241+ if rep := h .opts .ReplaceGroup ; rep != nil {
242+ name = rep (name )
243+ }
232244 return & Handler {
233245 opts : h .opts ,
234246 w : h .w ,
0 commit comments