1
0
mirror of https://github.com/astaxie/beego.git synced 2024-12-23 12:50:50 +00:00

Merge pull request #691 from FGM/logger-rfc5424

Issue #682: convert logs package to RFC5424 logging levels.
This commit is contained in:
astaxie 2014-07-11 21:35:56 +08:00
commit a6379481cf
8 changed files with 138 additions and 73 deletions

View File

@ -48,7 +48,7 @@ func (c *ConnWriter) Init(jsonconfig string) error {
// write message in connection. // write message in connection.
// if connection is down, try to re-connect. // if connection is down, try to re-connect.
func (c *ConnWriter) WriteMsg(msg string, level int) error { func (c *ConnWriter) WriteMsg(msg string, level int) error {
if level < c.Level { if level > c.Level {
return nil return nil
} }
if c.neddedConnectOnMsg() { if c.neddedConnectOnMsg() {

View File

@ -16,5 +16,5 @@ import (
func TestConn(t *testing.T) { func TestConn(t *testing.T) {
log := NewLogger(1000) log := NewLogger(1000)
log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`) log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`)
log.Info("info") log.Informational("informational")
} }

View File

@ -27,12 +27,14 @@ func NewBrush(color string) Brush {
} }
var colors = []Brush{ var colors = []Brush{
NewBrush("1;36"), // Trace cyan NewBrush("1;37"), // Emergency white
NewBrush("1;34"), // Debug blue NewBrush("1;36"), // Alert cyan
NewBrush("1;32"), // Info green NewBrush("1;35"), // Critical magenta
NewBrush("1;33"), // Warn yellow
NewBrush("1;31"), // Error red NewBrush("1;31"), // Error red
NewBrush("1;35"), // Critical purple NewBrush("1;33"), // Warning yellow
NewBrush("1;32"), // Notice green
NewBrush("1;34"), // Informational green
NewBrush("1;30"), // Debug black
} }
// ConsoleWriter implements LoggerInterface and writes messages to terminal. // ConsoleWriter implements LoggerInterface and writes messages to terminal.
@ -45,7 +47,7 @@ type ConsoleWriter struct {
func NewConsole() LoggerInterface { func NewConsole() LoggerInterface {
cw := new(ConsoleWriter) cw := new(ConsoleWriter)
cw.lg = log.New(os.Stdout, "", log.Ldate|log.Ltime) cw.lg = log.New(os.Stdout, "", log.Ldate|log.Ltime)
cw.Level = LevelTrace cw.Level = LevelDebug
return cw return cw
} }
@ -64,7 +66,7 @@ func (c *ConsoleWriter) Init(jsonconfig string) error {
// write message in console. // write message in console.
func (c *ConsoleWriter) WriteMsg(msg string, level int) error { func (c *ConsoleWriter) WriteMsg(msg string, level int) error {
if level < c.Level { if level > c.Level {
return nil return nil
} }
if goos := runtime.GOOS; goos == "windows" { if goos := runtime.GOOS; goos == "windows" {

View File

@ -13,22 +13,29 @@ import (
"testing" "testing"
) )
// Try each log level in decreasing order of priority.
func testConsoleCalls(bl *BeeLogger) {
bl.Emergency("emergency")
bl.Alert("alert")
bl.Critical("critical")
bl.Error("error")
bl.Warning("warning")
bl.Notice("notice")
bl.Informational("informational")
bl.Debug("debug")
}
// Test console logging by visually comparing the lines being output with and
// without a log level specification.
func TestConsole(t *testing.T) { func TestConsole(t *testing.T) {
log := NewLogger(10000) log1 := NewLogger(10000)
log.EnableFuncCallDepth(true) log1.EnableFuncCallDepth(true)
log.SetLogger("console", "") log1.SetLogger("console", "")
log.Trace("trace") testConsoleCalls(log1)
log.Info("info")
log.Warn("warning")
log.Debug("debug")
log.Critical("critical")
log2 := NewLogger(100) log2 := NewLogger(100)
log2.SetLogger("console", `{"level":1}`) log2.SetLogger("console", `{"level":3}`)
log.Trace("trace") testConsoleCalls(log2)
log.Info("info")
log.Warn("warning")
log.Debug("debug")
log.Critical("critical")
} }
func BenchmarkConsole(b *testing.B) { func BenchmarkConsole(b *testing.B) {
@ -36,6 +43,6 @@ func BenchmarkConsole(b *testing.B) {
log.EnableFuncCallDepth(true) log.EnableFuncCallDepth(true)
log.SetLogger("console", "") log.SetLogger("console", "")
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
log.Trace("trace") log.Debug("debug")
} }
} }

View File

@ -141,7 +141,7 @@ func (w *FileLogWriter) docheck(size int) {
// write logger message into file. // write logger message into file.
func (w *FileLogWriter) WriteMsg(msg string, level int) error { func (w *FileLogWriter) WriteMsg(msg string, level int) error {
if level < w.Level { if level > w.Level {
return nil return nil
} }
n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] " n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] "

View File

@ -13,6 +13,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"os" "os"
"strconv"
"testing" "testing"
"time" "time"
) )
@ -20,12 +21,14 @@ import (
func TestFile(t *testing.T) { func TestFile(t *testing.T) {
log := NewLogger(10000) log := NewLogger(10000)
log.SetLogger("file", `{"filename":"test.log"}`) log.SetLogger("file", `{"filename":"test.log"}`)
log.Trace("test")
log.Info("info")
log.Debug("debug") log.Debug("debug")
log.Warn("warning") log.Informational("info")
log.Notice("notice")
log.Warning("warning")
log.Error("error") log.Error("error")
log.Alert("alert")
log.Critical("critical") log.Critical("critical")
log.Emergency("emergency")
time.Sleep(time.Second * 4) time.Sleep(time.Second * 4)
f, err := os.Open("test.log") f, err := os.Open("test.log")
if err != nil { if err != nil {
@ -42,21 +45,24 @@ func TestFile(t *testing.T) {
linenum++ linenum++
} }
} }
if linenum != 6 { var expected = LevelDebug + 1
t.Fatal(linenum, "not line 6") if linenum != expected {
t.Fatal(linenum, "not "+strconv.Itoa(expected)+" lines")
} }
os.Remove("test.log") os.Remove("test.log")
} }
func TestFile2(t *testing.T) { func TestFile2(t *testing.T) {
log := NewLogger(10000) log := NewLogger(10000)
log.SetLogger("file", `{"filename":"test2.log","level":2}`) log.SetLogger("file", fmt.Sprintf(`{"filename":"test2.log","level":%d}`, LevelError))
log.Trace("test")
log.Info("info")
log.Debug("debug") log.Debug("debug")
log.Warn("warning") log.Info("info")
log.Notice("notice")
log.Warning("warning")
log.Error("error") log.Error("error")
log.Alert("alert")
log.Critical("critical") log.Critical("critical")
log.Emergency("emergency")
time.Sleep(time.Second * 4) time.Sleep(time.Second * 4)
f, err := os.Open("test2.log") f, err := os.Open("test2.log")
if err != nil { if err != nil {
@ -73,8 +79,9 @@ func TestFile2(t *testing.T) {
linenum++ linenum++
} }
} }
if linenum != 4 { var expected = LevelError + 1
t.Fatal(linenum, "not line 4") if linenum != expected {
t.Fatal(linenum, "not "+strconv.Itoa(expected)+" lines")
} }
os.Remove("test2.log") os.Remove("test2.log")
} }
@ -82,17 +89,19 @@ func TestFile2(t *testing.T) {
func TestFileRotate(t *testing.T) { func TestFileRotate(t *testing.T) {
log := NewLogger(10000) log := NewLogger(10000)
log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`) log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`)
log.Trace("test")
log.Info("info")
log.Debug("debug") log.Debug("debug")
log.Warn("warning") log.Info("info")
log.Notice("notice")
log.Warning("warning")
log.Error("error") log.Error("error")
log.Alert("alert")
log.Critical("critical") log.Critical("critical")
log.Emergency("emergency")
time.Sleep(time.Second * 4) time.Sleep(time.Second * 4)
rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1)
b, err := exists(rotatename) b, err := exists(rotatename)
if !b || err != nil { if !b || err != nil {
t.Fatal("rotate not gen") t.Fatal("rotate not generated")
} }
os.Remove(rotatename) os.Remove(rotatename)
os.Remove("test3.log") os.Remove("test3.log")
@ -113,7 +122,7 @@ func BenchmarkFile(b *testing.B) {
log := NewLogger(100000) log := NewLogger(100000)
log.SetLogger("file", `{"filename":"test4.log"}`) log.SetLogger("file", `{"filename":"test4.log"}`)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
log.Trace("trace") log.Debug("debug")
} }
os.Remove("test4.log") os.Remove("test4.log")
} }

View File

@ -16,14 +16,25 @@ import (
"sync" "sync"
) )
// RFC5424 log message levels.
const ( const (
// log message levels LevelEmergency = iota
LevelTrace = iota LevelAlert
LevelDebug
LevelInfo
LevelWarn
LevelError
LevelCritical LevelCritical
LevelError
LevelWarning
LevelNotice
LevelInformational
LevelDebug
)
// Legacy loglevel constants to ensure backwards compatibility.
//
// Deprecated: will be removed in 1.5.0.
const (
LevelInfo = LevelInformational
LevelTrace = LevelDebug
LevelWarn = LevelWarning
) )
type loggerType func() LoggerInterface type loggerType func() LoggerInterface
@ -72,6 +83,7 @@ type logMsg struct {
// if the buffering chan is full, logger adapters write to file or other way. // if the buffering chan is full, logger adapters write to file or other way.
func NewLogger(channellen int64) *BeeLogger { func NewLogger(channellen int64) *BeeLogger {
bl := new(BeeLogger) bl := new(BeeLogger)
bl.level = LevelDebug
bl.loggerFuncCallDepth = 2 bl.loggerFuncCallDepth = 2
bl.msg = make(chan *logMsg, channellen) bl.msg = make(chan *logMsg, channellen)
bl.outputs = make(map[string]LoggerInterface) bl.outputs = make(map[string]LoggerInterface)
@ -113,7 +125,7 @@ func (bl *BeeLogger) DelLogger(adaptername string) error {
} }
func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { func (bl *BeeLogger) writerMsg(loglevel int, msg string) error {
if bl.level > loglevel { if loglevel > bl.level {
return nil return nil
} }
lm := new(logMsg) lm := new(logMsg)
@ -133,8 +145,10 @@ func (bl *BeeLogger) writerMsg(loglevel int, msg string) error {
return nil return nil
} }
// set log message level. // Set log message level.
// if message level (such as LevelTrace) is less than logger level (such as LevelWarn), ignore message. //
// If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
// log providers will not even be sent the message.
func (bl *BeeLogger) SetLevel(l int) { func (bl *BeeLogger) SetLevel(l int) {
bl.level = l bl.level = l
} }
@ -162,40 +176,73 @@ func (bl *BeeLogger) startLogger() {
} }
} }
// log trace level message. // Log EMERGENCY level message.
func (bl *BeeLogger) Trace(format string, v ...interface{}) { func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
msg := fmt.Sprintf("[T] "+format, v...)
bl.writerMsg(LevelTrace, msg)
}
// log debug level message.
func (bl *BeeLogger) Debug(format string, v ...interface{}) {
msg := fmt.Sprintf("[D] "+format, v...) msg := fmt.Sprintf("[D] "+format, v...)
bl.writerMsg(LevelDebug, msg) bl.writerMsg(LevelEmergency, msg)
} }
// log info level message. // Log ALERT level message.
func (bl *BeeLogger) Info(format string, v ...interface{}) { func (bl *BeeLogger) Alert(format string, v ...interface{}) {
msg := fmt.Sprintf("[I] "+format, v...) msg := fmt.Sprintf("[D] "+format, v...)
bl.writerMsg(LevelInfo, msg) bl.writerMsg(LevelAlert, msg)
} }
// log warn level message. // Log CRITICAL level message.
func (bl *BeeLogger) Warn(format string, v ...interface{}) { func (bl *BeeLogger) Critical(format string, v ...interface{}) {
msg := fmt.Sprintf("[W] "+format, v...) msg := fmt.Sprintf("[C] "+format, v...)
bl.writerMsg(LevelWarn, msg) bl.writerMsg(LevelCritical, msg)
} }
// log error level message. // Log ERROR level message.
func (bl *BeeLogger) Error(format string, v ...interface{}) { func (bl *BeeLogger) Error(format string, v ...interface{}) {
msg := fmt.Sprintf("[E] "+format, v...) msg := fmt.Sprintf("[E] "+format, v...)
bl.writerMsg(LevelError, msg) bl.writerMsg(LevelError, msg)
} }
// log critical level message. // Log WARNING level message.
func (bl *BeeLogger) Critical(format string, v ...interface{}) { func (bl *BeeLogger) Warning(format string, v ...interface{}) {
msg := fmt.Sprintf("[C] "+format, v...) msg := fmt.Sprintf("[W] "+format, v...)
bl.writerMsg(LevelCritical, msg) bl.writerMsg(LevelWarning, msg)
}
// Log NOTICE level message.
func (bl *BeeLogger) Notice(format string, v ...interface{}) {
msg := fmt.Sprintf("[W] "+format, v...)
bl.writerMsg(LevelNotice, msg)
}
// Log INFORMATIONAL level message.
func (bl *BeeLogger) Informational(format string, v ...interface{}) {
msg := fmt.Sprintf("[I] "+format, v...)
bl.writerMsg(LevelInformational, msg)
}
// Log DEBUG level message.
func (bl *BeeLogger) Debug(format string, v ...interface{}) {
msg := fmt.Sprintf("[D] "+format, v...)
bl.writerMsg(LevelDebug, msg)
}
// Log WARN level message.
//
// Deprecated: compatibility alias for Warning(), Will be removed in 1.5.0.
func (bl *BeeLogger) Warn(format string, v ...interface{}) {
bl.Warning(format, v...)
}
// Log INFO level message.
//
// Deprecated: compatibility alias for Informational(), Will be removed in 1.5.0.
func (bl *BeeLogger) Info(format string, v ...interface{}) {
bl.Informational(format, v...)
}
// Log TRACE level message.
//
// Deprecated: compatibility alias for Debug(), Will be removed in 1.5.0.
func (bl *BeeLogger) Trace(format string, v ...interface{}) {
bl.Debug(format, v...)
} }
// flush all chan data. // flush all chan data.

View File

@ -57,7 +57,7 @@ func (s *SmtpWriter) Init(jsonconfig string) error {
// write message in smtp writer. // write message in smtp writer.
// it will send an email with subject and only this message. // it will send an email with subject and only this message.
func (s *SmtpWriter) WriteMsg(msg string, level int) error { func (s *SmtpWriter) WriteMsg(msg string, level int) error {
if level < s.Level { if level > s.Level {
return nil return nil
} }