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 }