gopkg.in/dedis/onet.v2@v2.0.0-20181115163211-c8f3724038a7/log/loggers.go (about) 1 package log 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/daviddengcn/go-colortext" 8 ) 9 10 // LoggerInfo is a structure that should be used when creating a logger. 11 // It contains parameters about how to log (with time, colors, ...) and 12 // embeds the Logger interface, which should define how the logger should log. 13 type LoggerInfo struct { 14 // These are information-debugging levels that can be turned on or off. 15 // Every logging greater than 'debugLvl' will be discarded . So you can 16 // Log at different levels and easily turn on or off the amount of logging 17 // generated by adjusting the 'debugLvl' variable. 18 DebugLvl int 19 // If 'showTime' is true, it will print the time for each line displayed 20 // by the logger. 21 ShowTime bool 22 // If 'useColors' is true, logs will be colored (defaults to monochrome 23 // output). It also controls padding, since colorful output is higly 24 // correlated with humans who like their log lines padded. 25 UseColors bool 26 // If 'padding' is true, it will nicely pad the line that is written. 27 Padding bool 28 } 29 30 // Logger is the interface that specifies how loggers 31 // will receive and display messages. 32 type Logger interface { 33 Log(level int, msg string) 34 Close() 35 GetLoggerInfo() *LoggerInfo 36 } 37 38 const ( 39 // DefaultStdDebugLvl is the default debug level for the standard logger 40 DefaultStdDebugLvl = 1 41 // DefaultStdShowTime is the default value for 'showTime' for the standard logger 42 DefaultStdShowTime = false 43 // DefaultStdUseColors is the default value for 'useColors' for the standard logger 44 DefaultStdUseColors = false 45 // DefaultStdPadding is the default value for 'padding' for the standard logger 46 DefaultStdPadding = true 47 ) 48 49 var ( 50 // concurrent access is protected by debugMut 51 loggers = make(map[int]Logger) 52 loggersCounter int 53 ) 54 55 // RegisterLogger will register a callback that will receive a copy of every 56 // message, fully formatted. It returns the key assigned to the logger (used 57 // to unregister the logger). 58 func RegisterLogger(l Logger) int { 59 debugMut.Lock() 60 defer debugMut.Unlock() 61 key := loggersCounter 62 loggers[key] = l 63 loggersCounter++ 64 return key 65 } 66 67 // UnregisterLogger takes the key it was assigned and returned by 68 // 'RegisterLogger', closes the corresponding Logger and removes it from the 69 // loggers. 70 func UnregisterLogger(key int) { 71 debugMut.Lock() 72 defer debugMut.Unlock() 73 if l, ok := loggers[key]; ok { 74 l.Close() 75 delete(loggers, key) 76 } 77 } 78 79 type fileLogger struct { 80 lInfo *LoggerInfo 81 file *os.File 82 } 83 84 func (fl *fileLogger) Log(level int, msg string) { 85 if _, err := fl.file.WriteString(msg); err != nil { 86 panic(err) 87 } 88 } 89 90 func (fl *fileLogger) Close() { 91 fl.file.Close() 92 } 93 94 func (fl *fileLogger) GetLoggerInfo() *LoggerInfo { 95 return fl.lInfo 96 } 97 98 // NewFileLogger creates a logger that writes into the file with 99 // the given path and is using the given LoggerInfo. 100 // It returns the logger. 101 func NewFileLogger(lInfo *LoggerInfo, path string) (Logger, error) { 102 // Override file if it already exists. 103 file, err := os.Create(path) 104 if err != nil { 105 return nil, err 106 } 107 return &fileLogger{ 108 lInfo: lInfo, 109 file: file, 110 }, nil 111 } 112 113 type stdLogger struct { 114 lInfo *LoggerInfo 115 } 116 117 func (sl *stdLogger) Log(lvl int, msg string) { 118 if sl.lInfo.UseColors { 119 bright := lvl < 0 120 lvlAbs := lvl 121 if bright { 122 lvlAbs *= -1 123 } 124 125 switch lvl { 126 case lvlPrint: 127 ct.Foreground(ct.White, true) 128 case lvlInfo: 129 ct.Foreground(ct.White, true) 130 case lvlWarning: 131 ct.Foreground(ct.Green, true) 132 case lvlError: 133 ct.Foreground(ct.Red, false) 134 case lvlFatal: 135 ct.Foreground(ct.Red, true) 136 case lvlPanic: 137 ct.Foreground(ct.Red, true) 138 default: 139 if lvl != 0 { 140 if lvlAbs <= 5 { 141 colors := []ct.Color{ct.Yellow, ct.Cyan, ct.Green, ct.Blue, ct.Cyan} 142 ct.Foreground(colors[lvlAbs-1], bright) 143 } 144 } 145 } 146 } 147 148 if lvl < lvlInfo { 149 fmt.Fprint(stdErr, msg) 150 } else { 151 fmt.Fprint(stdOut, msg) 152 } 153 154 if sl.lInfo.UseColors { 155 ct.ResetColor() 156 } 157 } 158 159 func (sl *stdLogger) Close() {} 160 161 func (sl *stdLogger) GetLoggerInfo() *LoggerInfo { 162 return sl.lInfo 163 } 164 165 // Not public + not taking a LoggerInfo as argument because we don't want 166 // multiple stdLoggers. 167 func newStdLogger() (Logger, error) { 168 lInfo := &LoggerInfo{ 169 DebugLvl: DefaultStdDebugLvl, 170 UseColors: DefaultStdUseColors, 171 ShowTime: DefaultStdShowTime, 172 Padding: DefaultStdPadding, 173 } 174 return &stdLogger{lInfo: lInfo}, nil 175 }