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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/syslog"
|
//"log/syslog"
|
||||||
|
"github.com/GolangResources/syslog/syslog"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NUM_SYSLOG_WORKERS = 8
|
||||||
|
CHANNEL_DEPTH = 8192
|
||||||
|
)
|
||||||
|
|
||||||
// SyslogHook to send logs via syslog.
|
// SyslogHook to send logs via syslog.
|
||||||
type SyslogHook struct {
|
type SyslogHook struct {
|
||||||
Writer *syslog.Writer
|
Writer *syslog.Writer
|
||||||
SyslogNetwork string
|
SyslogNetwork string
|
||||||
SyslogRaddr 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
|
// Creates a hook to be added to an instance of logger. This is called with
|
||||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||||
// `if err == nil { log.Hooks.Add(hook) }`
|
// `if err == nil { log.Hooks.Add(hook) }`
|
||||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
w, err := syslog.Dial("ctcp" , raddr, priority, nil)
|
||||||
return &SyslogHook{w, network, raddr}, err
|
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 {
|
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||||
|
var err error
|
||||||
line, err := entry.String()
|
line, err := entry.String()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
sentry := &SEntry{
|
||||||
switch entry.Level {
|
line: line,
|
||||||
case logrus.PanicLevel:
|
level: entry.Level,
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
select {
|
||||||
|
case hook.syschan <- sentry:
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("logrus syslog chan full")
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||||
|
|
Loading…
Reference in New Issue