You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.1 KiB
89 lines
2.1 KiB
// +build !windows |
|
// +build !binary_log |
|
|
|
package zerolog |
|
|
|
import ( |
|
"io" |
|
) |
|
|
|
// See http://cee.mitre.org/language/1.0-beta1/clt.html#syslog |
|
// or https://www.rsyslog.com/json-elasticsearch/ |
|
const ceePrefix = "@cee:" |
|
|
|
// SyslogWriter is an interface matching a syslog.Writer struct. |
|
type SyslogWriter interface { |
|
io.Writer |
|
Debug(m string) error |
|
Info(m string) error |
|
Warning(m string) error |
|
Err(m string) error |
|
Emerg(m string) error |
|
Crit(m string) error |
|
} |
|
|
|
type syslogWriter struct { |
|
w SyslogWriter |
|
prefix string |
|
} |
|
|
|
// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level |
|
// method matching the zerolog level. |
|
func SyslogLevelWriter(w SyslogWriter) LevelWriter { |
|
return syslogWriter{w, ""} |
|
} |
|
|
|
// SyslogCEEWriter wraps a SyslogWriter with a SyslogLevelWriter that adds a |
|
// MITRE CEE prefix for JSON syslog entries, compatible with rsyslog |
|
// and syslog-ng JSON logging support. |
|
// See https://www.rsyslog.com/json-elasticsearch/ |
|
func SyslogCEEWriter(w SyslogWriter) LevelWriter { |
|
return syslogWriter{w, ceePrefix} |
|
} |
|
|
|
func (sw syslogWriter) Write(p []byte) (n int, err error) { |
|
var pn int |
|
if sw.prefix != "" { |
|
pn, err = sw.w.Write([]byte(sw.prefix)) |
|
if err != nil { |
|
return pn, err |
|
} |
|
} |
|
n, err = sw.w.Write(p) |
|
return pn + n, err |
|
} |
|
|
|
// WriteLevel implements LevelWriter interface. |
|
func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) { |
|
switch level { |
|
case TraceLevel: |
|
case DebugLevel: |
|
err = sw.w.Debug(sw.prefix + string(p)) |
|
case InfoLevel: |
|
err = sw.w.Info(sw.prefix + string(p)) |
|
case WarnLevel: |
|
err = sw.w.Warning(sw.prefix + string(p)) |
|
case ErrorLevel: |
|
err = sw.w.Err(sw.prefix + string(p)) |
|
case FatalLevel: |
|
err = sw.w.Emerg(sw.prefix + string(p)) |
|
case PanicLevel: |
|
err = sw.w.Crit(sw.prefix + string(p)) |
|
case NoLevel: |
|
err = sw.w.Info(sw.prefix + string(p)) |
|
default: |
|
panic("invalid level") |
|
} |
|
// Any CEE prefix is not part of the message, so we don't include its length |
|
n = len(p) |
|
return |
|
} |
|
|
|
// Call the underlying writer's Close method if it is an io.Closer. Otherwise |
|
// does nothing. |
|
func (sw syslogWriter) Close() error { |
|
if c, ok := sw.w.(io.Closer); ok { |
|
return c.Close() |
|
} |
|
return nil |
|
}
|
|
|