| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 | // 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 logimport (	"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(1, "Fail to set logger(%s): %v", mode, err)	}}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 intconst (	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() LoggerInterfacevar 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)}
 |