package log import ( "fmt" "log/syslog" "os" "github.com/Sirupsen/logrus" logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" ) // ShowuserlogHook stores all levels of logrus entries in memory until its told the RancherOS logging system is ready // then it replays them to be logged type ShowuserlogHook struct { Level logrus.Level syslogHook *logrus_syslog.SyslogHook storedEntries []*logrus.Entry appName string } // NewShowuserlogHook creates a new hook for use func NewShowuserlogHook(l logrus.Level, app string) (*ShowuserlogHook, error) { return &ShowuserlogHook{l, nil, []*logrus.Entry{}, app}, nil } // Fire is called by logrus when the Hook is active func (hook *ShowuserlogHook) Fire(entry *logrus.Entry) error { if entry.Level <= hook.Level { //if f, err := os.OpenFile("/dev/kmsg", os.O_WRONLY, 0644); err != nil { // fmt.Fprintf(f, "%s:%s: %s\n", hook.appName, entry.Level, entry.Message) // f.Close() //} else { fmt.Printf("[ ] %s:%s: %s\n", hook.appName, entry.Level, entry.Message) //} } if hook.syslogHook == nil { hook.storedEntries = append(hook.storedEntries, entry) } else { err := hook.syslogHook.Fire(entry) if err != nil { fmt.Fprintf(os.Stderr, "LOGERR: Unable to syslog.Fire %v, %v", entry, err) return err } } return nil } // Levels returns all log levels, so we can process them ourselves func (hook *ShowuserlogHook) Levels() []logrus.Level { return []logrus.Level{ logrus.DebugLevel, logrus.InfoLevel, logrus.WarnLevel, logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel, } } // NotUsedYetLogSystemReady Set up Syslog Hook, and replay any stored entries. func (hook *ShowuserlogHook) NotUsedYetLogSystemReady() error { if hook.syslogHook == nil { h, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_INFO, "") if err != nil { logrus.Debugf("error creating SyslogHook: %v", err) return err } hook.syslogHook = h for _, entry := range hook.storedEntries { line, _ := entry.String() fmt.Printf("---- CATCHUP %s\n", line) hook.syslogHook.Fire(entry) } } return nil }