| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 | 
							- // Copyright 2014 The Gogs Authors. All rights reserved.
 
- // Use of this source code is governed by a MIT-style
 
- // license that can be found in the LICENSE file.
 
- package log
 
- import (
 
- 	"fmt"
 
- 	"os"
 
- 	"path"
 
- 	"path/filepath"
 
- 	"runtime"
 
- 	"strings"
 
- 	"sync"
 
- )
 
- var (
 
- 	loggers   []*Logger
 
- 	GitLogger *Logger
 
- )
 
- func NewLogger(bufLen int64, mode, config string) {
 
- 	logger := newLogger(bufLen)
 
- 	isExist := false
 
- 	for _, l := range loggers {
 
- 		if l.adapter == mode {
 
- 			isExist = true
 
- 			l = logger
 
- 		}
 
- 	}
 
- 	if !isExist {
 
- 		loggers = append(loggers, logger)
 
- 	}
 
- 	if err := logger.SetLogger(mode, config); err != nil {
 
- 		Fatal(2, "Fail to set logger (%s): %v", mode, err)
 
- 	}
 
- }
 
- // FIXME: use same log level as other loggers.
 
- func NewGitLogger(logPath string) {
 
- 	os.MkdirAll(path.Dir(logPath), os.ModePerm)
 
- 	GitLogger = newLogger(0)
 
- 	GitLogger.SetLogger("file", fmt.Sprintf(`{"level":0,"filename":"%s","rotate":false}`, logPath))
 
- }
 
- func Trace(format string, v ...interface{}) {
 
- 	for _, logger := range loggers {
 
- 		logger.Trace(format, v...)
 
- 	}
 
- }
 
- func Debug(format string, v ...interface{}) {
 
- 	for _, logger := range loggers {
 
- 		logger.Debug(format, v...)
 
- 	}
 
- }
 
- func Info(format string, v ...interface{}) {
 
- 	for _, logger := range loggers {
 
- 		logger.Info(format, v...)
 
- 	}
 
- }
 
- func Warn(format string, v ...interface{}) {
 
- 	for _, logger := range loggers {
 
- 		logger.Warn(format, v...)
 
- 	}
 
- }
 
- func Error(skip int, format string, v ...interface{}) {
 
- 	for _, logger := range loggers {
 
- 		logger.Error(skip, format, v...)
 
- 	}
 
- }
 
- func Critical(skip int, format string, v ...interface{}) {
 
- 	for _, logger := range loggers {
 
- 		logger.Critical(skip, format, v...)
 
- 	}
 
- }
 
- func Fatal(skip int, format string, v ...interface{}) {
 
- 	Error(skip, format, v...)
 
- 	for _, l := range loggers {
 
- 		l.Close()
 
- 	}
 
- 	os.Exit(1)
 
- }
 
- func Close() {
 
- 	for _, l := range loggers {
 
- 		l.Close()
 
- 	}
 
- }
 
- // .___        __                 _____
 
- // |   | _____/  |_  ____________/ ____\____    ____  ____
 
- // |   |/    \   __\/ __ \_  __ \   __\\__  \ _/ ___\/ __ \
 
- // |   |   |  \  | \  ___/|  | \/|  |   / __ \\  \__\  ___/
 
- // |___|___|  /__|  \___  >__|   |__|  (____  /\___  >___  >
 
- //          \/          \/                  \/     \/    \/
 
- type LogLevel int
 
- const (
 
- 	TRACE = iota
 
- 	DEBUG
 
- 	INFO
 
- 	WARN
 
- 	ERROR
 
- 	CRITICAL
 
- 	FATAL
 
- )
 
- // LoggerInterface represents behaviors of a logger provider.
 
- type LoggerInterface interface {
 
- 	Init(config string) error
 
- 	WriteMsg(msg string, skip, level int) error
 
- 	Destroy()
 
- 	Flush()
 
- }
 
- type loggerType func() LoggerInterface
 
- var adapters = make(map[string]loggerType)
 
- // Register registers given logger provider to adapters.
 
- func Register(name string, log loggerType) {
 
- 	if log == nil {
 
- 		panic("log: register provider is nil")
 
- 	}
 
- 	if _, dup := adapters[name]; dup {
 
- 		panic("log: register called twice for provider \"" + name + "\"")
 
- 	}
 
- 	adapters[name] = log
 
- }
 
- type logMsg struct {
 
- 	skip, level int
 
- 	msg         string
 
- }
 
- // Logger is default logger in beego application.
 
- // it can contain several providers and log message into all providers.
 
- type Logger struct {
 
- 	adapter string
 
- 	lock    sync.Mutex
 
- 	level   int
 
- 	msg     chan *logMsg
 
- 	outputs map[string]LoggerInterface
 
- 	quit    chan bool
 
- }
 
- // newLogger initializes and returns a new logger.
 
- func newLogger(buffer int64) *Logger {
 
- 	l := &Logger{
 
- 		msg:     make(chan *logMsg, buffer),
 
- 		outputs: make(map[string]LoggerInterface),
 
- 		quit:    make(chan bool),
 
- 	}
 
- 	go l.StartLogger()
 
- 	return l
 
- }
 
- // SetLogger sets new logger instance with given logger adapter and config.
 
- func (l *Logger) SetLogger(adapter string, config string) error {
 
- 	l.lock.Lock()
 
- 	defer l.lock.Unlock()
 
- 	if log, ok := adapters[adapter]; ok {
 
- 		lg := log()
 
- 		if err := lg.Init(config); err != nil {
 
- 			return err
 
- 		}
 
- 		l.outputs[adapter] = lg
 
- 		l.adapter = adapter
 
- 	} else {
 
- 		panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)")
 
- 	}
 
- 	return nil
 
- }
 
- // DelLogger removes a logger adapter instance.
 
- func (l *Logger) DelLogger(adapter string) error {
 
- 	l.lock.Lock()
 
- 	defer l.lock.Unlock()
 
- 	if lg, ok := l.outputs[adapter]; ok {
 
- 		lg.Destroy()
 
- 		delete(l.outputs, adapter)
 
- 	} else {
 
- 		panic("log: unknown adapter \"" + adapter + "\" (forgotten register?)")
 
- 	}
 
- 	return nil
 
- }
 
- func (l *Logger) writerMsg(skip, level int, msg string) error {
 
- 	if l.level > level {
 
- 		return nil
 
- 	}
 
- 	lm := &logMsg{
 
- 		skip:  skip,
 
- 		level: level,
 
- 	}
 
- 	// Only error information needs locate position for debugging.
 
- 	if lm.level >= ERROR {
 
- 		pc, file, line, ok := runtime.Caller(skip)
 
- 		if ok {
 
- 			// Get caller function name.
 
- 			fn := runtime.FuncForPC(pc)
 
- 			var fnName string
 
- 			if fn == nil {
 
- 				fnName = "?()"
 
- 			} else {
 
- 				fnName = strings.TrimLeft(filepath.Ext(fn.Name()), ".") + "()"
 
- 			}
 
- 			fileName := file
 
- 			if len(fileName) > 20 {
 
- 				fileName = "..." + fileName[len(fileName)-20:]
 
- 			}
 
- 			lm.msg = fmt.Sprintf("[%s:%d %s] %s", fileName, line, fnName, msg)
 
- 		} else {
 
- 			lm.msg = msg
 
- 		}
 
- 	} else {
 
- 		lm.msg = msg
 
- 	}
 
- 	l.msg <- lm
 
- 	return nil
 
- }
 
- // StartLogger starts logger chan reading.
 
- func (l *Logger) StartLogger() {
 
- 	for {
 
- 		select {
 
- 		case bm := <-l.msg:
 
- 			for _, l := range l.outputs {
 
- 				if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil {
 
- 					fmt.Println("ERROR, unable to WriteMsg:", err)
 
- 				}
 
- 			}
 
- 		case <-l.quit:
 
- 			return
 
- 		}
 
- 	}
 
- }
 
- // Flush flushs all chan data.
 
- func (l *Logger) Flush() {
 
- 	for _, l := range l.outputs {
 
- 		l.Flush()
 
- 	}
 
- }
 
- // Close closes logger, flush all chan data and destroy all adapter instances.
 
- func (l *Logger) Close() {
 
- 	l.quit <- true
 
- 	for {
 
- 		if len(l.msg) > 0 {
 
- 			bm := <-l.msg
 
- 			for _, l := range l.outputs {
 
- 				if err := l.WriteMsg(bm.msg, bm.skip, bm.level); err != nil {
 
- 					fmt.Println("ERROR, unable to WriteMsg:", err)
 
- 				}
 
- 			}
 
- 		} else {
 
- 			break
 
- 		}
 
- 	}
 
- 	for _, l := range l.outputs {
 
- 		l.Flush()
 
- 		l.Destroy()
 
- 	}
 
- }
 
- func (l *Logger) Trace(format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[T] "+format, v...)
 
- 	l.writerMsg(0, TRACE, msg)
 
- }
 
- func (l *Logger) Debug(format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[D] "+format, v...)
 
- 	l.writerMsg(0, DEBUG, msg)
 
- }
 
- func (l *Logger) Info(format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[I] "+format, v...)
 
- 	l.writerMsg(0, INFO, msg)
 
- }
 
- func (l *Logger) Warn(format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[W] "+format, v...)
 
- 	l.writerMsg(0, WARN, msg)
 
- }
 
- func (l *Logger) Error(skip int, format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[E] "+format, v...)
 
- 	l.writerMsg(skip, ERROR, msg)
 
- }
 
- func (l *Logger) Critical(skip int, format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[C] "+format, v...)
 
- 	l.writerMsg(skip, CRITICAL, msg)
 
- }
 
- func (l *Logger) Fatal(skip int, format string, v ...interface{}) {
 
- 	msg := fmt.Sprintf("[F] "+format, v...)
 
- 	l.writerMsg(skip, FATAL, msg)
 
- 	l.Close()
 
- 	os.Exit(1)
 
- }
 
 
  |