func defaultFormatFunc(h http.HTTP) http.Formatter { var bt []byte var err error hc := h.(*HipChat) b := new(bytes.Buffer) template := hc.Template() body := new(Body) body.Notify = true return func(e *log.Entry) []byte { bt = bt[0:0] b.Reset() body.From = e.ApplicationID body.Color = hc.GetDisplayColor(e.Level) if err = template.ExecuteTemplate(b, "hipchat", e); err != nil { log.WithFields(log.F("error", err)).Error("Error parsing HipChat handler template") } body.Message = b.String() // shouldn't be possible to fail here // at least with the default handler... bt, _ = json.Marshal(body) return bt } }
func defaultFormatFunc(email *Email) Formatter { var err error b := new(bytes.Buffer) // apparently there is a race condition when I was using // email.to... below in the SetHeader for whatever reason // so copying the "to" values solves the issue // I wonder if it's a flase positive in the race detector..... to := make([]string, len(email.to), len(email.to)) copy(to, email.to) template := email.Template() message := gomail.NewMessage() message.SetHeader("From", email.from) message.SetHeader("To", to...) return func(e *log.Entry) *gomail.Message { b.Reset() if err = template.ExecuteTemplate(b, "email", e); err != nil { log.WithFields(log.F("error", err)).Error("Error parsing Email handler template") } message.SetHeader("Subject", e.Message) message.SetBody(contentType, b.String()) return message } }
// this will redirect the output of func handleStdLogger(done chan<- struct{}) { r, w := io.Pipe() defer r.Close() defer w.Close() stdlog.SetOutput(w) scanner := bufio.NewScanner(r) go func() { done <- struct{}{} }() for scanner.Scan() { log.WithFields(log.F("stdlog", true)).Notice(scanner.Text()) } }
func main() { cLog := console.New() log.RegisterHandler(cLog, log.AllLevels...) // Trace defer log.Trace("trace").End() log.Debug("debug") log.Info("info") log.Notice("notice") log.Warn("warn") log.Error("error") // log.Panic("panic") // this will panic log.Alert("alert") // log.Fatal("fatal") // this will call os.Exit(1) // logging with fields can be used with any of the above log.WithFields(log.F("key", "value")).Info("test info") }
func testFormatFunc(email *Email) Formatter { var err error b := new(bytes.Buffer) return func(e *log.Entry) *gomail.Message { b.Reset() message := gomail.NewMessage() message.SetHeader("From", email.From()) message.SetHeader("To", email.To()...) if err = email.template.ExecuteTemplate(b, "email", e); err != nil { log.WithFields(log.F("error", err)).Error("Error parsing Email handler template") } message.SetHeader("Subject", e.Message) message.SetBody(contentType, b.String()) return message } }
func BenchmarkLogConsoleTenFieldsParallel(b *testing.B) { b.ResetTimer() // log setup in TestMain b.RunParallel(func(pb *testing.PB) { for pb.Next() { log.WithFields( log.F("int", 1), log.F("int64", int64(1)), log.F("float", 3.0), log.F("string", "four!"), log.F("bool", true), log.F("time", time.Unix(0, 0)), log.F("error", errExample.Error()), log.F("duration", time.Second), log.F("user-defined type", _jane), log.F("another string", "done!"), ).Info("Go fast.") } }) }
func TestConsoleLogger(t *testing.T) { tests := getConsoleLoggerTests() buff := new(bytes.Buffer) cLog := New() cLog.SetWriter(buff) cLog.SetDisplayColor(false) cLog.SetBuffersAndWorkers(3, 0) cLog.SetTimestampFormat("MST") log.SetCallerInfoLevels(log.WarnLevel, log.ErrorLevel, log.PanicLevel, log.AlertLevel, log.FatalLevel) log.RegisterHandler(cLog, log.AllLevels...) for i, tt := range tests { buff.Reset() var l log.LeveledLogger if tt.flds != nil { l = log.WithFields(tt.flds...) } else { l = log.Logger } switch tt.lvl { case log.DebugLevel: if len(tt.printf) == 0 { l.Debug(tt.msg) } else { l.Debugf(tt.printf, tt.msg) } case log.TraceLevel: if len(tt.printf) == 0 { l.Trace(tt.msg).End() } else { l.Tracef(tt.printf, tt.msg).End() } case log.InfoLevel: if len(tt.printf) == 0 { l.Info(tt.msg) } else { l.Infof(tt.printf, tt.msg) } case log.NoticeLevel: if len(tt.printf) == 0 { l.Notice(tt.msg) } else { l.Noticef(tt.printf, tt.msg) } case log.WarnLevel: if len(tt.printf) == 0 { l.Warn(tt.msg) } else { l.Warnf(tt.printf, tt.msg) } case log.ErrorLevel: if len(tt.printf) == 0 { l.Error(tt.msg) } else { l.Errorf(tt.printf, tt.msg) } case log.PanicLevel: func() { defer func() { recover() }() if len(tt.printf) == 0 { l.Panic(tt.msg) } else { l.Panicf(tt.printf, tt.msg) } }() case log.AlertLevel: if len(tt.printf) == 0 { l.Alert(tt.msg) } else { l.Alertf(tt.printf, tt.msg) } } if buff.String() != tt.want { if tt.lvl == log.TraceLevel { if !strings.HasPrefix(buff.String(), tt.want) { t.Errorf("test %d: Expected '%s' Got '%s'", i, tt.want, buff.String()) } continue } t.Errorf("test %d: Expected '%s' Got '%s'", i, tt.want, buff.String()) } } }
func TestHTTPLogger(t *testing.T) { tests := getTestHTTPLoggerTests() var msg string server := httptest.NewServer(stdhttp.HandlerFunc(func(w stdhttp.ResponseWriter, r *stdhttp.Request) { b, err := ioutil.ReadAll(r.Body) if err != nil { msg = err.Error() return } msg = string(b) if msg == "UTC DEBUG badrequest" { w.WriteHeader(stdhttp.StatusBadRequest) return } })) defer server.Close() header := make(stdhttp.Header, 0) header.Set("Content-Type", "text/plain") hLog, err := New(server.URL, "POST", header) if err != nil { log.Fatalf("Error initializing HTTP received '%s'", err) } hLog.SetBuffersAndWorkers(0, 0) hLog.SetTimestampFormat("MST") log.SetCallerInfoLevels(log.WarnLevel, log.ErrorLevel, log.PanicLevel, log.AlertLevel, log.FatalLevel) log.RegisterHandler(hLog, log.DebugLevel, log.TraceLevel, log.InfoLevel, log.NoticeLevel, log.WarnLevel, log.PanicLevel, log.AlertLevel, log.FatalLevel) for i, tt := range tests { var l log.LeveledLogger if tt.flds != nil { l = log.WithFields(tt.flds...) } else { l = log.Logger } switch tt.lvl { case log.DebugLevel: l.Debug(tt.msg) case log.TraceLevel: l.Trace(tt.msg).End() case log.InfoLevel: l.Info(tt.msg) case log.NoticeLevel: l.Notice(tt.msg) case log.WarnLevel: l.Warn(tt.msg) case log.ErrorLevel: l.Error(tt.msg) case log.PanicLevel: func() { defer func() { recover() }() l.Panic(tt.msg) }() case log.AlertLevel: l.Alert(tt.msg) } if msg != tt.want { if tt.lvl == log.TraceLevel { if !strings.HasPrefix(msg, tt.want) { t.Errorf("test %d: Expected '%s' Got '%s'", i, tt.want, msg) } continue } t.Errorf("test %d: Expected '%s' Got '%s'", i, tt.want, msg) } } log.Debug("badrequest") }
func (email *Email) handleLog(entries <-chan *log.Entry) { var e *log.Entry var s gomail.SendCloser var err error var open bool var alreadyTriedSending bool var message *gomail.Message var count uint8 formatter := email.formatFunc(email) d := gomail.NewDialer(email.host, email.port, email.username, email.password) for { select { case e = <-entries: count = 0 alreadyTriedSending = false message = formatter(e) REOPEN: // check if smtp connection open if !open { count++ if s, err = d.Dial(); err != nil { log.WithFields(log.F("error", err)).Warn("ERROR connection to smtp server") if count == 3 { // we tried to reconnect... e.Consumed() break } goto REOPEN } count = 0 open = true } RESEND: count++ if err = gomail.Send(s, message); err != nil { log.WithFields(log.F("error", err)).Warn("ERROR sending to smtp server, retrying") if count == 3 && !alreadyTriedSending { // maybe we got disconnected... alreadyTriedSending = true open = false s.Close() goto REOPEN } else if alreadyTriedSending { // we reopened and tried 2 more times, can;t say we didn't try log.WithFields(log.F("error", err)).Alert("ERROR sending log via EMAIL, RETRY and REOPEN failed") e.Consumed() break } goto RESEND } e.Consumed() case <-time.After(email.keepalive): if open { s.Close() open = false } } } }
func TestSyslogLogger(t *testing.T) { tests := getSyslogLoggerTests() addr, err := net.ResolveUDPAddr("udp", ":2000") if err != nil { t.Errorf("Expected '%v' Got '%v'", nil, err) } conn, err := net.ListenUDP("udp", addr) if err != nil { t.Errorf("Expected '%v' Got '%v'", nil, err) } defer conn.Close() sLog, err := New("udp", "127.0.0.1:2000", "", nil) if err != nil { t.Errorf("Expected '%v' Got '%v'", nil, err) } sLog.SetDisplayColor(false) sLog.SetBuffersAndWorkers(3, 3) sLog.SetTimestampFormat("MST") log.SetCallerInfoLevels(log.WarnLevel, log.ErrorLevel, log.PanicLevel, log.AlertLevel, log.FatalLevel) log.RegisterHandler(sLog, log.AllLevels...) for i, tt := range tests { var l log.LeveledLogger if tt.flds != nil { l = log.WithFields(tt.flds...) } else { l = log.Logger } switch tt.lvl { case log.DebugLevel: if len(tt.printf) == 0 { l.Debug(tt.msg) } else { l.Debugf(tt.printf, tt.msg) } case log.TraceLevel: if len(tt.printf) == 0 { l.Trace(tt.msg).End() } else { l.Tracef(tt.printf, tt.msg).End() } case log.InfoLevel: if len(tt.printf) == 0 { l.Info(tt.msg) } else { l.Infof(tt.printf, tt.msg) } case log.NoticeLevel: if len(tt.printf) == 0 { l.Notice(tt.msg) } else { l.Noticef(tt.printf, tt.msg) } case log.WarnLevel: if len(tt.printf) == 0 { l.Warn(tt.msg) } else { l.Warnf(tt.printf, tt.msg) } case log.ErrorLevel: if len(tt.printf) == 0 { l.Error(tt.msg) } else { l.Errorf(tt.printf, tt.msg) } case log.PanicLevel: func() { defer func() { recover() }() if len(tt.printf) == 0 { l.Panic(tt.msg) } else { l.Panicf(tt.printf, tt.msg) } }() case log.AlertLevel: if len(tt.printf) == 0 { l.Alert(tt.msg) } else { l.Alertf(tt.printf, tt.msg) } } if s := hasString(conn); !strings.HasSuffix(s, tt.want) { if tt.lvl == log.TraceLevel { if !strings.Contains(s, tt.want) { t.Errorf("test %d: Contains Suffix '%s' Got '%s'", i, tt.want, s) } continue } t.Errorf("test %d: Expected Suffix '%s' Got '%s'", i, tt.want, s) } } }
func TestSyslogLoggerColor(t *testing.T) { tests := getSyslogLoggerColorTests() addr, err := net.ResolveUDPAddr("udp", ":2001") if err != nil { t.Errorf("Expected '%v' Got '%v'", nil, err) } conn, err := net.ListenUDP("udp", addr) if err != nil { t.Errorf("Expected '%v' Got '%s'", nil, err) } defer conn.Close() sLog, err := New("udp", "127.0.0.1:2001", "", nil) if err != nil { t.Errorf("Expected '%v' Got '%s'", nil, err) } sLog.SetDisplayColor(true) sLog.SetBuffersAndWorkers(3, 3) sLog.SetTimestampFormat("MST") log.RegisterHandler(sLog, log.AllLevels...) for i, tt := range tests { var l log.LeveledLogger if tt.flds != nil { l = log.WithFields(tt.flds...) } else { l = log.Logger } switch tt.lvl { case log.DebugLevel: if len(tt.printf) == 0 { l.Debug(tt.msg) } else { l.Debugf(tt.printf, tt.msg) } case log.TraceLevel: if len(tt.printf) == 0 { l.Trace(tt.msg).End() } else { l.Tracef(tt.printf, tt.msg).End() } case log.InfoLevel: if len(tt.printf) == 0 { l.Info(tt.msg) } else { l.Infof(tt.printf, tt.msg) } case log.NoticeLevel: if len(tt.printf) == 0 { l.Notice(tt.msg) } else { l.Noticef(tt.printf, tt.msg) } case log.WarnLevel: if len(tt.printf) == 0 { l.Warn(tt.msg) } else { l.Warnf(tt.printf, tt.msg) } case log.ErrorLevel: if len(tt.printf) == 0 { l.Error(tt.msg) } else { l.Errorf(tt.printf, tt.msg) } case log.PanicLevel: func() { defer func() { recover() }() if len(tt.printf) == 0 { l.Panic(tt.msg) } else { l.Panicf(tt.printf, tt.msg) } }() case log.AlertLevel: if len(tt.printf) == 0 { l.Alert(tt.msg) } else { l.Alertf(tt.printf, tt.msg) } } if s := hasString(conn); !strings.HasSuffix(s, tt.want) { if tt.lvl == log.TraceLevel { if !strings.Contains(s, tt.want) { t.Errorf("test %d: Expected Contains '%s' Got '%s'", i, tt.want, s) } continue } t.Errorf("test %d: Expected Suffix '%s' Got '%s'", i, tt.want, s) } } e := &log.Entry{ Level: log.FatalLevel, Message: "fatal", Timestamp: time.Now().UTC(), Line: 259, File: "syslog_test.go", } log.HandleEntry(e) if s := hasString(conn); !strings.Contains(s, "UTC [31m[4m[5m FATAL[0m syslog_test.go:259 fatal\n") { t.Errorf("test fatal: Expected Contains '%s' Got '%s'", "UTC [31m[4m[5m FATAL[0m syslog_test.go:259 fatal\n", s) } }