| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 | 
							- // Package lfshook is hook for sirupsen/logrus that used for writing the logs to local files.
 
- package lfshook
 
- import (
 
- 	"fmt"
 
- 	"io"
 
- 	"reflect"
 
- 	"sync"
 
- 	"github.com/sirupsen/logrus"
 
- 	"gopkg.in/natefinch/lumberjack.v2"
 
- )
 
- // We are logging to file, strip colors to make the output more readable.
 
- var defaultFormatter = &logrus.TextFormatter{DisableColors: true}
 
- // PathMap is map for mapping a log level to a file's path.
 
- // Multiple levels may share a file, but multiple files may not be used for one level.
 
- // type PathMap map[logrus.Level]string
 
- // 一个 level 对应 一个 logger
 
- type LoggerMap map[logrus.Level]*lumberjack.Logger
 
- // WriterMap is map for mapping a log level to an io.Writer.
 
- // Multiple levels may share a writer, but multiple writers may not be used for one level.
 
- type WriterMap map[logrus.Level]io.Writer
 
- type RotateFileConfig struct {
 
- 	Filename   string
 
- 	MaxSize    int
 
- 	MaxBackups int
 
- 	MaxAge     int
 
- 	Level      logrus.Level
 
- 	Formatter  logrus.Formatter
 
- }
 
- // LfsHook is a hook to handle writing to local log files.
 
- type LfsHook struct {
 
- 	loggers   LoggerMap
 
- 	writers   WriterMap
 
- 	levels    []logrus.Level
 
- 	lock      *sync.Mutex
 
- 	formatter logrus.Formatter
 
- 	Config RotateFileConfig
 
- 	defaultPath      string
 
- 	defaultWriter    io.Writer
 
- 	hasDefaultPath   bool
 
- 	hasDefaultWriter bool
 
- }
 
- // NewHook returns new LFS hook.
 
- // Output can be a string, io.Writer, WriterMap or PathMap.
 
- // If using io.Writer or WriterMap, user is responsible for closing the used io.Writer.
 
- func NewHook(output interface{}, formatter logrus.Formatter) *LfsHook {
 
- 	hook := &LfsHook{
 
- 		lock: new(sync.Mutex),
 
- 	}
 
- 	hook.SetFormatter(formatter)
 
- 	switch output.(type) {
 
- 	case string:
 
- 		hook.SetDefaultPath(output.(string))
 
- 		break
 
- 	case io.Writer:
 
- 		hook.SetDefaultWriter(output.(io.Writer))
 
- 		break
 
- 	case LoggerMap:
 
- 		hook.loggers = output.(LoggerMap)
 
- 		for level := range output.(LoggerMap) {
 
- 			hook.levels = append(hook.levels, level)
 
- 		}
 
- 		break
 
- 	case WriterMap:
 
- 		hook.writers = output.(WriterMap)
 
- 		for level := range output.(WriterMap) {
 
- 			hook.levels = append(hook.levels, level)
 
- 		}
 
- 		break
 
- 	default:
 
- 		panic(fmt.Sprintf("unsupported level map type: %v", reflect.TypeOf(output)))
 
- 	}
 
- 	return hook
 
- }
 
- // SetFormatter sets the format that will be used by hook.
 
- // If using text formatter, this method will disable color output to make the log file more readable.
 
- func (hook *LfsHook) SetFormatter(formatter logrus.Formatter) {
 
- 	hook.lock.Lock()
 
- 	defer hook.lock.Unlock()
 
- 	if formatter == nil {
 
- 		formatter = defaultFormatter
 
- 	} else {
 
- 		switch formatter.(type) {
 
- 		case *logrus.TextFormatter:
 
- 			textFormatter := formatter.(*logrus.TextFormatter)
 
- 			textFormatter.DisableColors = true
 
- 		}
 
- 	}
 
- 	hook.formatter = formatter
 
- }
 
- // SetDefaultPath sets default path for levels that don't have any defined output path.
 
- func (hook *LfsHook) SetDefaultPath(defaultPath string) {
 
- 	hook.lock.Lock()
 
- 	defer hook.lock.Unlock()
 
- 	hook.defaultPath = defaultPath
 
- 	hook.hasDefaultPath = true
 
- }
 
- // SetDefaultWriter sets default writer for levels that don't have any defined writer.
 
- func (hook *LfsHook) SetDefaultWriter(defaultWriter io.Writer) {
 
- 	hook.lock.Lock()
 
- 	defer hook.lock.Unlock()
 
- 	hook.defaultWriter = defaultWriter
 
- 	hook.hasDefaultWriter = true
 
- }
 
- // Fire writes the log file to defined path or using the defined writer.
 
- // User who run this function needs write permissions to the file or directory if the file does not yet exist.
 
- func (hook *LfsHook) Fire(entry *logrus.Entry) error {
 
- 	hook.lock.Lock()
 
- 	defer hook.lock.Unlock()
 
- 	if hook.writers != nil || hook.hasDefaultWriter {
 
- 		return hook.ioWrite(entry)
 
- 	} else if hook.loggers != nil || hook.hasDefaultPath {
 
- 		return hook.fileWrite(entry)
 
- 	}
 
- 	return nil
 
- }
 
- // Write a log line to an io.Writer.
 
- func (hook *LfsHook) ioWrite(entry *logrus.Entry) error {
 
- 	var (
 
- 		writer io.Writer
 
- 		msg    []byte
 
- 		err    error
 
- 		ok     bool
 
- 	)
 
- 	if writer, ok = hook.writers[entry.Level]; !ok {
 
- 		if hook.hasDefaultWriter {
 
- 			writer = hook.defaultWriter
 
- 		} else {
 
- 			return nil
 
- 		}
 
- 	}
 
- 	// use our formatter instead of entry.String()
 
- 	msg, err = hook.formatter.Format(entry)
 
- 	if err != nil {
 
- 		log.Println("failed to generate string for entry:", err)
 
- 		return err
 
- 	}
 
- 	_, err = writer.Write(msg)
 
- 	return err
 
- }
 
- // Write a log line directly to a file.
 
- func (hook *LfsHook) fileWrite(entry *logrus.Entry) error {
 
- 	var (
 
- 		logger *lumberjack.Logger
 
- 		msg    []byte
 
- 		err    error
 
- 		ok     bool
 
- 	)
 
- 	if logger, ok = hook.loggers[entry.Level]; !ok {
 
- 		if hook.hasDefaultPath {
 
- 			logger = &lumberjack.Logger{
 
- 				Filename:   hook.defaultPath,
 
- 				MaxSize:    10, // maxSize M
 
- 				MaxBackups: 5,  // keep 5 file
 
- 				MaxAge:     7,  //  7 day
 
- 			}
 
- 		} else {
 
- 			return nil
 
- 		}
 
- 	}
 
- 	// use our formatter instead of entry.String()
 
- 	msg, err = hook.formatter.Format(entry)
 
- 	if err != nil {
 
- 		log.Println("failed to generate string for entry:", err)
 
- 		return err
 
- 	}
 
- 	defer logger.Close()
 
- 	logger.Write(msg)
 
- 	return nil
 
- }
 
- // Levels returns configured log levels.
 
- func (hook *LfsHook) Levels() []logrus.Level {
 
- 	return logrus.AllLevels
 
- }
 
- var log *logrus.Entry
 
- var once sync.Once
 
- //NewLogger 初始化 logger
 
- func NewLogger() *logrus.Entry {
 
- 	once.Do(func() {
 
- 		log = logrus.New().WithFields(
 
- 			logrus.Fields{
 
- 				"appname": "pbx-panel",
 
- 			},
 
- 		)
 
- 	})
 
- 	return log
 
- }
 
 
  |