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:
commit
a6379481cf
@ -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() {
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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" {
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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] "
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
109
logs/log.go
109
logs/log.go
@ -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.
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user