zlog/syslog.go

81 lines
1.9 KiB
Go
Raw Permalink Normal View History

2017-05-12 05:24:39 +00:00
// +build !windows
// +build !binary_log
2017-05-12 05:24:39 +00:00
2022-03-20 19:19:42 +00:00
package zlog
2017-05-12 05:24:39 +00:00
import (
"io"
)
2020-10-12 13:16:04 +00:00
// 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
}
2017-05-12 05:24:39 +00:00
type syslogWriter struct {
2020-10-12 13:16:04 +00:00
w SyslogWriter
prefix string
2017-05-12 05:24:39 +00:00
}
// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level
2022-03-20 19:19:42 +00:00
// method matching the zlog level.
func SyslogLevelWriter(w SyslogWriter) LevelWriter {
2020-10-12 13:16:04 +00:00
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}
2017-05-12 05:24:39 +00:00
}
func (sw syslogWriter) Write(p []byte) (n int, err error) {
2020-10-12 13:16:04 +00:00
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
2017-05-12 05:24:39 +00:00
}
// WriteLevel implements LevelWriter interface.
func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
switch level {
2019-11-04 19:39:22 +00:00
case TraceLevel:
2017-05-12 05:24:39 +00:00
case DebugLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Debug(sw.prefix + string(p))
2017-05-12 05:24:39 +00:00
case InfoLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Info(sw.prefix + string(p))
2017-05-12 05:24:39 +00:00
case WarnLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Warning(sw.prefix + string(p))
2017-05-12 05:24:39 +00:00
case ErrorLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Err(sw.prefix + string(p))
2017-05-12 05:24:39 +00:00
case FatalLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Emerg(sw.prefix + string(p))
2017-05-12 05:24:39 +00:00
case PanicLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Crit(sw.prefix + string(p))
2017-12-01 17:52:37 +00:00
case NoLevel:
2020-10-12 13:16:04 +00:00
err = sw.w.Info(sw.prefix + string(p))
2017-05-12 05:24:39 +00:00
default:
panic("invalid level")
}
2020-10-12 13:16:04 +00:00
// Any CEE prefix is not part of the message, so we don't include its length
2017-05-12 05:24:39 +00:00
n = len(p)
return
}