github.com/Rookout/GoSDK@v0.1.48/pkg/logger/logger.go (about)

     1  package logger
     2  
     3  import (
     4  	"fmt"
     5  	"runtime"
     6  
     7  	"github.com/Rookout/GoSDK/pkg/config"
     8  	pb "github.com/Rookout/GoSDK/pkg/protobuf"
     9  	"github.com/sirupsen/logrus"
    10  
    11  	logrus_lumberjack "github.com/fallais/logrus-lumberjack-hook"
    12  	"gopkg.in/natefinch/lumberjack.v2"
    13  
    14  	"os"
    15  	"path/filepath"
    16  	"time"
    17  
    18  	"golang.org/x/time/rate"
    19  )
    20  
    21  func QuietPrintln(msg string) {
    22  	if !config.LoggingConfig().Quiet {
    23  		fmt.Println(msg)
    24  	}
    25  }
    26  
    27  type LoggerOutput interface {
    28  	SendLogMessage(level pb.LogMessage_LogLevel, time time.Time, filename string, lineno int, text string, args map[string]interface{}) error
    29  }
    30  
    31  type nilWriter struct{}
    32  
    33  func (*nilWriter) Write(p []byte) (n int, err error) {
    34  	return len(p), nil
    35  }
    36  
    37  func getNilLogger(debug bool, level string) *logrus.Logger {
    38  	l := logrus.New()
    39  	if debug {
    40  		l.SetOutput(&nilWriter{})
    41  		l.Level = logrus.DebugLevel
    42  	} else {
    43  		l.Level, _ = logrus.ParseLevel(level)
    44  	}
    45  
    46  	l.SetReportCaller(true)
    47  	l.ExitFunc = func(int) {}
    48  	return l
    49  }
    50  
    51  var logger *logrus.Logger = nil
    52  var isDebug = false
    53  
    54  func Init(debug bool, level string) {
    55  	isDebug = debug
    56  	logger = getNilLogger(debug, level)
    57  }
    58  
    59  func Logger() *logrus.Logger {
    60  	if logger == nil {
    61  		Init(isDebug, "debug")
    62  	}
    63  	return logger
    64  }
    65  
    66  func NewFileHandler(file string) error {
    67  	if file == "" {
    68  		file = filepath.Join(getLogFolder(), "go-rook.log")
    69  	}
    70  
    71  	ljk := &lumberjack.Logger{
    72  		Filename:   file,
    73  		MaxSize:    100, 
    74  		MaxBackups: 5,   
    75  		MaxAge:     28,  
    76  	}
    77  	if hook, err := logrus_lumberjack.NewLumberjackHook(ljk); err != nil {
    78  		return err
    79  	} else {
    80  		logger.AddHook(hook)
    81  	}
    82  
    83  	return nil
    84  }
    85  
    86  func getLogFolder() string {
    87  	switch runtime.GOOS {
    88  	case "darwin":
    89  		return os.Getenv("HOME")
    90  	case "windows":
    91  		return os.Getenv("USERPROFILE")
    92  	default:
    93  		return "/tmp/log/rookout"
    94  	}
    95  }
    96  
    97  type outputHook struct {
    98  	output      LoggerOutput
    99  	levels      []logrus.Level
   100  	rateLimiter *rate.Limiter
   101  }
   102  
   103  func InitHandlers(logToStderr, logToFile bool, logFile string) {
   104  	if logToStderr {
   105  		logger.SetOutput(os.Stderr)
   106  	} else if isDebug {
   107  		logger.SetOutput(os.Stdout)
   108  	} else {
   109  		logger.SetOutput(&nilWriter{})
   110  	}
   111  
   112  	if logToFile {
   113  		_ = NewFileHandler(logFile)
   114  	}
   115  }
   116  
   117  func newOutputHook(output LoggerOutput) *outputHook {
   118  	hook := &outputHook{output: output, rateLimiter: rate.NewLimiter(3*rate.Every(time.Second), 10)}
   119  	if isDebug {
   120  		hook.levels = logrus.AllLevels
   121  		return hook
   122  	}
   123  
   124  	actualLvls := make([]logrus.Level, 0)
   125  	for _, level := range logrus.AllLevels {
   126  		if level <= logrus.DebugLevel {
   127  			actualLvls = append(actualLvls, level)
   128  		}
   129  	}
   130  
   131  	hook.levels = actualLvls
   132  	return hook
   133  }
   134  
   135  func (o *outputHook) Levels() []logrus.Level {
   136  	return o.levels
   137  }
   138  
   139  func LevelToInt(level logrus.Level) pb.LogMessage_LogLevel {
   140  	switch level {
   141  	case logrus.TraceLevel:
   142  		return pb.LogMessage_TRACE
   143  	case logrus.DebugLevel:
   144  		return pb.LogMessage_DEBUG
   145  	case logrus.InfoLevel:
   146  		return pb.LogMessage_INFO
   147  	case logrus.WarnLevel:
   148  		return pb.LogMessage_WARNING
   149  	case logrus.ErrorLevel:
   150  		return pb.LogMessage_ERROR
   151  	case logrus.PanicLevel, logrus.FatalLevel:
   152  		return pb.LogMessage_FATAL
   153  	default:
   154  		return pb.LogMessage_LogLevel(level)
   155  	}
   156  }
   157  
   158  func (o *outputHook) Fire(e *logrus.Entry) error {
   159  	var filename string
   160  	var lineno int
   161  	if e.HasCaller() {
   162  		filename = e.Caller.File
   163  		lineno = e.Caller.Line
   164  	}
   165  
   166  	
   167  	_ = o.output.SendLogMessage(LevelToInt(e.Level), e.Time, filename, lineno, e.Message, e.Data)
   168  	return nil
   169  }
   170  
   171  func SetLoggerOutput(output LoggerOutput) {
   172  	logger.AddHook(newOutputHook(output))
   173  }