package main import ( "fmt" "log/syslog" "os" "github.com/sirupsen/logrus" ) var ( syslogLevels = map[string]logrus.Level{ "crit": logrus.FatalLevel, "error": logrus.ErrorLevel, "warning": logrus.WarnLevel, "info": logrus.InfoLevel, } ) type syslogHook struct { writer *syslog.Writer levels []logrus.Level formatter logrus.Formatter } func isSyslogEnabled() (enabled bool) { boolEnvConfig(&enabled, "IMGPROXY_SYSLOG_ENABLE") return } func newSyslogHook() (*syslogHook, error) { var ( network, addr string level logrus.Level tag = "imgproxy" levelStr = "notice" ) strEnvConfig(&network, "IMGPROXY_SYSLOG_NETWORK") strEnvConfig(&addr, "IMGPROXY_SYSLOG_ADDRESS") strEnvConfig(&tag, "IMGPROXY_SYSLOG_TAG") strEnvConfig(&levelStr, "IMGPROXY_SYSLOG_LEVEL") if l, ok := syslogLevels[levelStr]; ok { level = l } else { level = logrus.InfoLevel logWarning("Syslog level '%s' is invalid, 'info' is used", levelStr) } w, err := syslog.Dial(network, addr, syslog.LOG_NOTICE, tag) return &syslogHook{ writer: w, levels: logrus.AllLevels[:int(level)+1], formatter: &logStructuredFormatter{}, }, err } func (hook *syslogHook) Fire(entry *logrus.Entry) error { line, err := hook.formatter.Format(entry) if err != nil { fmt.Fprintf(os.Stderr, "Unable to read entry, %v\n", err) return err } switch entry.Level { case logrus.PanicLevel, logrus.FatalLevel: return hook.writer.Crit(string(line)) case logrus.ErrorLevel: return hook.writer.Err(string(line)) case logrus.WarnLevel: return hook.writer.Warning(string(line)) case logrus.InfoLevel: return hook.writer.Info(string(line)) default: return nil } } func (hook *syslogHook) Levels() []logrus.Level { return hook.levels }