package daemon import ( "github.com/op/go-logging" "github.com/subgraph/oz/ipc" "log" "os" ) func (d *daemonState) Debug(format string, args ...interface{}) { d.log.Debug(format, args...) } func (d *daemonState) Info(format string, args ...interface{}) { d.log.Info(format, args...) } func (d *daemonState) Notice(format string, args ...interface{}) { d.log.Notice(format, args...) } func (d *daemonState) Warning(format string, args ...interface{}) { d.log.Warning(format, args...) } func (d *daemonState) Error(format string, args ...interface{}) { d.log.Error(format, args...) } func (d *daemonState) Critical(format string, args ...interface{}) { d.log.Critical(format, args...) } func (d *daemonState) initializeLogging() { d.log = logging.MustGetLogger("oz") be := logging.NewChannelMemoryBackend(100) fbe := logging.NewBackendFormatter(be, format) d.memBackend = be stderr := logging.NewLogBackend(os.Stderr, "", log.LstdFlags) d.backends = []logging.Backend{ stderr, fbe, } d.installBackends() } var format = logging.MustStringFormatter( "%{color}%{time:15:04:05} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}", ) func (d *daemonState) addBackend(be logging.Backend) { d.backends = append(d.backends, be) d.installBackends() } func (d *daemonState) removeBackend(be logging.Backend) { newBackends := []logging.Backend{} for _, b := range d.backends { if b != be { newBackends = append(newBackends, b) } } d.backends = newBackends d.installBackends() } func (d *daemonState) installBackends() { if len(d.backends) == 1 { d.log.SetBackend(logging.AddModuleLevel(d.backends[0])) return } d.log.SetBackend(logging.MultiLogger(d.backends...)) } type logFollower struct { daemon *daemonState wrapper logging.Backend m *ipc.Message } func (lf *logFollower) Log(level logging.Level, calldepth int, rec *logging.Record) error { s := rec.Formatted(calldepth) if err := lf.m.Respond(&LogData{[]string{s}}); err != nil { lf.remove() } return nil } func (lf *logFollower) remove() { lf.daemon.removeBackend(lf.wrapper) } func (d *daemonState) followLogs(m *ipc.Message) { be := &logFollower{m: m, daemon: d} be.wrapper = logging.NewBackendFormatter(be, format) d.addBackend(be.wrapper) }