mirror of https://github.com/sirupsen/logrus.git
The syslog library has been changed to prevent crashes if the syslog server is down, writing does not degrade if syslog server is slow.
This commit is contained in:
parent
cd4bf4ef8d
commit
f160b155bb
|
@ -4,50 +4,95 @@ package syslog
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log/syslog"
|
||||
//"log/syslog"
|
||||
"github.com/GolangResources/syslog/syslog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
NUM_SYSLOG_WORKERS = 8
|
||||
CHANNEL_DEPTH = 8192
|
||||
)
|
||||
|
||||
// SyslogHook to send logs via syslog.
|
||||
type SyslogHook struct {
|
||||
Writer *syslog.Writer
|
||||
SyslogNetwork string
|
||||
SyslogRaddr string
|
||||
Writer *syslog.Writer
|
||||
SyslogNetwork string
|
||||
SyslogRaddr string
|
||||
Tag string
|
||||
syschan chan *SEntry
|
||||
}
|
||||
|
||||
type SEntry struct {
|
||||
line string
|
||||
level logrus.Level
|
||||
}
|
||||
|
||||
// Creates a hook to be added to an instance of logger. This is called with
|
||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||
// `if err == nil { log.Hooks.Add(hook) }`
|
||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
||||
return &SyslogHook{w, network, raddr}, err
|
||||
w, err := syslog.Dial("ctcp" , raddr, priority, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hook := &SyslogHook{
|
||||
w,
|
||||
network,
|
||||
raddr,
|
||||
tag,
|
||||
make(chan *SEntry, CHANNEL_DEPTH),
|
||||
}
|
||||
for i := 0; i <= NUM_SYSLOG_WORKERS; i++ {
|
||||
go hook.worker(i)
|
||||
}
|
||||
return hook, err
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) worker(i int) {
|
||||
for entry := range hook.syschan {
|
||||
time.Sleep(1)
|
||||
func() error {
|
||||
switch entry.level {
|
||||
case logrus.PanicLevel:
|
||||
return hook.Writer.Crit(&entry.line, hook.Tag)
|
||||
case logrus.FatalLevel:
|
||||
return hook.Writer.Crit(&entry.line, hook.Tag)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.Writer.Err(&entry.line, hook.Tag)
|
||||
case logrus.WarnLevel:
|
||||
return hook.Writer.Warning(&entry.line, hook.Tag)
|
||||
case logrus.InfoLevel:
|
||||
return hook.Writer.Info(&entry.line, hook.Tag)
|
||||
case logrus.DebugLevel, logrus.TraceLevel:
|
||||
return hook.Writer.Debug(&entry.line, hook.Tag)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||
var err error
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.FatalLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.Writer.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
return hook.Writer.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
return hook.Writer.Info(line)
|
||||
case logrus.DebugLevel, logrus.TraceLevel:
|
||||
return hook.Writer.Debug(line)
|
||||
default:
|
||||
return nil
|
||||
sentry := &SEntry{
|
||||
line: line,
|
||||
level: entry.Level,
|
||||
}
|
||||
select {
|
||||
case hook.syschan <- sentry:
|
||||
default:
|
||||
err = fmt.Errorf("logrus syslog chan full")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||
|
|
Loading…
Reference in New Issue