grafana/pkg/infra/log/syslog.go
2023-08-30 18:46:47 +03:00

108 lines
2.4 KiB
Go

//go:build !windows && !nacl && !plan9
// +build !windows,!nacl,!plan9
package log
import (
"log/syslog"
"os"
"github.com/go-kit/log"
"github.com/go-kit/log/level"
gokitsyslog "github.com/go-kit/log/syslog"
"gopkg.in/ini.v1"
)
type SysLogHandler struct {
syslog *syslog.Writer
Network string
Address string
Facility string
Tag string
Format Formatedlogger
logger log.Logger
}
var selector = func(keyvals ...any) syslog.Priority {
for i := 0; i < len(keyvals); i += 2 {
if keyvals[i] == level.Key() {
val := keyvals[i+1]
if val != nil {
switch val {
case level.ErrorValue():
return syslog.LOG_ERR
case level.WarnValue():
return syslog.LOG_WARNING
case level.InfoValue():
return syslog.LOG_INFO
case level.DebugValue():
return syslog.LOG_DEBUG
}
}
break
}
}
return syslog.LOG_INFO
}
func NewSyslog(sec *ini.Section, format Formatedlogger) *SysLogHandler {
handler := &SysLogHandler{}
handler.Format = format
handler.Network = sec.Key("network").MustString("")
handler.Address = sec.Key("address").MustString("")
handler.Facility = sec.Key("facility").MustString("local7")
handler.Tag = sec.Key("tag").MustString("")
if err := handler.Init(); err != nil {
root.Error("Failed to init syslog log handler", "error", err)
os.Exit(1)
}
handler.logger = gokitsyslog.NewSyslogLogger(handler.syslog, format, gokitsyslog.PrioritySelectorOption(selector))
return handler
}
func (sw *SysLogHandler) Init() error {
// the facility is the origin of the syslog message
prio := parseFacility(sw.Facility)
w, err := syslog.Dial(sw.Network, sw.Address, prio, sw.Tag)
if err != nil {
return err
}
sw.syslog = w
return nil
}
func (sw *SysLogHandler) Log(keyvals ...any) error {
err := sw.logger.Log(keyvals...)
return err
}
func (sw *SysLogHandler) Close() error {
return sw.syslog.Close()
}
var facilities = map[string]syslog.Priority{
"user": syslog.LOG_USER,
"daemon": syslog.LOG_DAEMON,
"local0": syslog.LOG_LOCAL0,
"local1": syslog.LOG_LOCAL1,
"local2": syslog.LOG_LOCAL2,
"local3": syslog.LOG_LOCAL3,
"local4": syslog.LOG_LOCAL4,
"local5": syslog.LOG_LOCAL5,
"local6": syslog.LOG_LOCAL6,
"local7": syslog.LOG_LOCAL7,
}
func parseFacility(facility string) syslog.Priority {
v, found := facilities[facility]
if !found {
// default the facility level to LOG_LOCAL7
return syslog.LOG_LOCAL7
}
return v
}