Beego/logs/log.go

222 lines
5.2 KiB
Go
Raw Normal View History

2014-04-12 05:18:18 +00:00
// Beego (http://beego.me/)
// @description beego is an open-source, high-performance web framework for the Go programming language.
// @link http://github.com/astaxie/beego for the canonical source repository
// @license http://github.com/astaxie/beego/blob/master/LICENSE
// @authors astaxie
2013-08-27 15:48:58 +00:00
package logs
import (
"fmt"
2014-03-25 15:48:18 +00:00
"path"
"runtime"
2013-08-27 15:48:58 +00:00
"sync"
)
const (
2013-12-30 15:32:57 +00:00
// log message levels
2013-08-27 15:48:58 +00:00
LevelTrace = iota
LevelDebug
LevelInfo
LevelWarn
LevelError
LevelCritical
)
type loggerType func() LoggerInterface
2013-12-30 15:32:57 +00:00
// LoggerInterface defines the behavior of a log provider.
2013-08-27 15:48:58 +00:00
type LoggerInterface interface {
Init(config string) error
WriteMsg(msg string, level int) error
Destroy()
2013-11-27 09:50:10 +00:00
Flush()
2013-08-27 15:48:58 +00:00
}
var adapters = make(map[string]loggerType)
// Register makes a log provide available by the provided name.
// If Register is called twice with the same name or if driver is nil,
// it panics.
func Register(name string, log loggerType) {
if log == nil {
panic("logs: Register provide is nil")
}
if _, dup := adapters[name]; dup {
panic("logs: Register called twice for provider " + name)
}
adapters[name] = log
}
2013-12-30 15:32:57 +00:00
// BeeLogger is default logger in beego application.
// it can contain several providers and log message into all providers.
2013-08-27 15:48:58 +00:00
type BeeLogger struct {
2014-03-25 15:48:18 +00:00
lock sync.Mutex
level int
enableFuncCallDepth bool
loggerFuncCallDepth int
msg chan *logMsg
outputs map[string]LoggerInterface
2013-08-27 15:48:58 +00:00
}
type logMsg struct {
level int
msg string
}
2013-12-30 15:32:57 +00:00
// NewLogger returns a new BeeLogger.
// channellen means the number of messages in chan.
// if the buffering chan is full, logger adapters write to file or other way.
2013-08-27 15:48:58 +00:00
func NewLogger(channellen int64) *BeeLogger {
bl := new(BeeLogger)
2014-03-25 15:48:18 +00:00
bl.loggerFuncCallDepth = 2
2013-08-27 15:48:58 +00:00
bl.msg = make(chan *logMsg, channellen)
bl.outputs = make(map[string]LoggerInterface)
//bl.SetLogger("console", "") // default output to console
2014-04-02 15:43:37 +00:00
go bl.startLogger()
2013-08-27 15:48:58 +00:00
return bl
}
2013-12-30 15:32:57 +00:00
// SetLogger provides a given logger adapter into BeeLogger with config string.
// config need to be correct JSON as string: {"interval":360}.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) SetLogger(adaptername string, config string) error {
bl.lock.Lock()
defer bl.lock.Unlock()
if log, ok := adapters[adaptername]; ok {
lg := log()
2014-04-02 15:43:37 +00:00
err := lg.Init(config)
bl.outputs[adaptername] = lg
2014-04-02 15:43:37 +00:00
if err != nil {
fmt.Println("logs.BeeLogger.SetLogger: " + err.Error())
2014-04-02 15:43:37 +00:00
return err
}
2013-08-27 15:48:58 +00:00
} else {
return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adaptername)
}
return nil
2013-08-27 15:48:58 +00:00
}
2013-12-30 15:32:57 +00:00
// remove a logger adapter in BeeLogger.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) DelLogger(adaptername string) error {
bl.lock.Lock()
defer bl.lock.Unlock()
if lg, ok := bl.outputs[adaptername]; ok {
lg.Destroy()
delete(bl.outputs, adaptername)
return nil
} else {
return fmt.Errorf("logs: unknown adaptername %q (forgotten Register?)", adaptername)
}
}
func (bl *BeeLogger) writerMsg(loglevel int, msg string) error {
if bl.level > loglevel {
return nil
}
lm := new(logMsg)
lm.level = loglevel
2014-03-25 15:48:18 +00:00
if bl.enableFuncCallDepth {
_, file, line, ok := runtime.Caller(bl.loggerFuncCallDepth)
if ok {
_, filename := path.Split(file)
lm.msg = fmt.Sprintf("[%s:%d] %s", filename, line, msg)
} else {
lm.msg = msg
}
} else {
lm.msg = msg
}
2013-08-27 15:48:58 +00:00
bl.msg <- lm
return nil
}
2013-12-30 15:32:57 +00:00
// set log message level.
// if message level (such as LevelTrace) is less than logger level (such as LevelWarn), ignore message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) SetLevel(l int) {
bl.level = l
}
2014-03-25 15:48:18 +00:00
// set log funcCallDepth
func (bl *BeeLogger) SetLogFuncCallDepth(d int) {
bl.loggerFuncCallDepth = d
}
// enable log funcCallDepth
func (bl *BeeLogger) EnableFuncCallDepth(b bool) {
bl.enableFuncCallDepth = b
}
2013-12-30 15:32:57 +00:00
// start logger chan reading.
// when chan is full, write logs.
2014-04-02 15:43:37 +00:00
func (bl *BeeLogger) startLogger() {
2013-08-27 15:48:58 +00:00
for {
select {
case bm := <-bl.msg:
for _, l := range bl.outputs {
l.WriteMsg(bm.msg, bm.level)
}
}
}
}
2013-12-30 15:32:57 +00:00
// log trace level message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Trace(format string, v ...interface{}) {
msg := fmt.Sprintf("[T] "+format, v...)
bl.writerMsg(LevelTrace, msg)
}
2013-12-30 15:32:57 +00:00
// log debug level message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Debug(format string, v ...interface{}) {
msg := fmt.Sprintf("[D] "+format, v...)
bl.writerMsg(LevelDebug, msg)
}
2013-12-30 15:32:57 +00:00
// log info level message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Info(format string, v ...interface{}) {
msg := fmt.Sprintf("[I] "+format, v...)
bl.writerMsg(LevelInfo, msg)
}
2013-12-30 15:32:57 +00:00
// log warn level message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Warn(format string, v ...interface{}) {
msg := fmt.Sprintf("[W] "+format, v...)
bl.writerMsg(LevelWarn, msg)
}
2013-12-30 15:32:57 +00:00
// log error level message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Error(format string, v ...interface{}) {
msg := fmt.Sprintf("[E] "+format, v...)
bl.writerMsg(LevelError, msg)
}
2013-12-30 15:32:57 +00:00
// log critical level message.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Critical(format string, v ...interface{}) {
msg := fmt.Sprintf("[C] "+format, v...)
bl.writerMsg(LevelCritical, msg)
}
2013-12-30 15:32:57 +00:00
// flush all chan data.
2013-11-27 09:50:10 +00:00
func (bl *BeeLogger) Flush() {
for _, l := range bl.outputs {
l.Flush()
}
}
2013-12-30 15:32:57 +00:00
// close logger, flush all chan data and destroy all adapters in BeeLogger.
2013-08-27 15:48:58 +00:00
func (bl *BeeLogger) Close() {
2013-11-27 09:50:10 +00:00
for {
if len(bl.msg) > 0 {
bm := <-bl.msg
for _, l := range bl.outputs {
l.WriteMsg(bm.msg, bm.level)
}
} else {
break
}
}
2013-08-27 15:48:58 +00:00
for _, l := range bl.outputs {
2013-11-27 09:50:10 +00:00
l.Flush()
2013-08-27 15:48:58 +00:00
l.Destroy()
}
}