Issue #682: convert logs package to RFC5424 logging levels.
Showing
8 changed files
with
137 additions
and
72 deletions
| ... | @@ -48,7 +48,7 @@ func (c *ConnWriter) Init(jsonconfig string) error { | ... | @@ -48,7 +48,7 @@ func (c *ConnWriter) Init(jsonconfig string) error { |
| 48 | // write message in connection. | 48 | // write message in connection. |
| 49 | // if connection is down, try to re-connect. | 49 | // if connection is down, try to re-connect. |
| 50 | func (c *ConnWriter) WriteMsg(msg string, level int) error { | 50 | func (c *ConnWriter) WriteMsg(msg string, level int) error { |
| 51 | if level < c.Level { | 51 | if level > c.Level { |
| 52 | return nil | 52 | return nil |
| 53 | } | 53 | } |
| 54 | if c.neddedConnectOnMsg() { | 54 | if c.neddedConnectOnMsg() { | ... | ... |
| ... | @@ -16,5 +16,5 @@ import ( | ... | @@ -16,5 +16,5 @@ import ( |
| 16 | func TestConn(t *testing.T) { | 16 | func TestConn(t *testing.T) { |
| 17 | log := NewLogger(1000) | 17 | log := NewLogger(1000) |
| 18 | log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`) | 18 | log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`) |
| 19 | log.Info("info") | 19 | log.Informational("informational") |
| 20 | } | 20 | } | ... | ... |
| ... | @@ -27,12 +27,14 @@ func NewBrush(color string) Brush { | ... | @@ -27,12 +27,14 @@ func NewBrush(color string) Brush { |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | var colors = []Brush{ | 29 | var colors = []Brush{ |
| 30 | NewBrush("1;36"), // Trace cyan | 30 | NewBrush("1;37"), // Emergency white |
| 31 | NewBrush("1;34"), // Debug blue | 31 | NewBrush("1;36"), // Alert cyan |
| 32 | NewBrush("1;32"), // Info green | 32 | NewBrush("1;35"), // Critical magenta |
| 33 | NewBrush("1;33"), // Warn yellow | ||
| 34 | NewBrush("1;31"), // Error red | 33 | NewBrush("1;31"), // Error red |
| 35 | NewBrush("1;35"), // Critical purple | 34 | NewBrush("1;33"), // Warning yellow |
| 35 | NewBrush("1;32"), // Notice green | ||
| 36 | NewBrush("1;34"), // Informational green | ||
| 37 | NewBrush("1;30"), // Debug black | ||
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | // ConsoleWriter implements LoggerInterface and writes messages to terminal. | 40 | // ConsoleWriter implements LoggerInterface and writes messages to terminal. |
| ... | @@ -45,7 +47,7 @@ type ConsoleWriter struct { | ... | @@ -45,7 +47,7 @@ type ConsoleWriter struct { |
| 45 | func NewConsole() LoggerInterface { | 47 | func NewConsole() LoggerInterface { |
| 46 | cw := new(ConsoleWriter) | 48 | cw := new(ConsoleWriter) |
| 47 | cw.lg = log.New(os.Stdout, "", log.Ldate|log.Ltime) | 49 | cw.lg = log.New(os.Stdout, "", log.Ldate|log.Ltime) |
| 48 | cw.Level = LevelTrace | 50 | cw.Level = LevelDebug |
| 49 | return cw | 51 | return cw |
| 50 | } | 52 | } |
| 51 | 53 | ||
| ... | @@ -64,7 +66,7 @@ func (c *ConsoleWriter) Init(jsonconfig string) error { | ... | @@ -64,7 +66,7 @@ func (c *ConsoleWriter) Init(jsonconfig string) error { |
| 64 | 66 | ||
| 65 | // write message in console. | 67 | // write message in console. |
| 66 | func (c *ConsoleWriter) WriteMsg(msg string, level int) error { | 68 | func (c *ConsoleWriter) WriteMsg(msg string, level int) error { |
| 67 | if level < c.Level { | 69 | if level > c.Level { |
| 68 | return nil | 70 | return nil |
| 69 | } | 71 | } |
| 70 | if goos := runtime.GOOS; goos == "windows" { | 72 | if goos := runtime.GOOS; goos == "windows" { | ... | ... |
| ... | @@ -13,22 +13,29 @@ import ( | ... | @@ -13,22 +13,29 @@ import ( |
| 13 | "testing" | 13 | "testing" |
| 14 | ) | 14 | ) |
| 15 | 15 | ||
| 16 | // Try each log level in decreasing order of priority. | ||
| 17 | func testConsoleCalls(bl *BeeLogger) { | ||
| 18 | bl.Emergency("emergency") | ||
| 19 | bl.Alert("alert") | ||
| 20 | bl.Critical("critical") | ||
| 21 | bl.Error("error") | ||
| 22 | bl.Warning("warning") | ||
| 23 | bl.Notice("notice") | ||
| 24 | bl.Informational("informational") | ||
| 25 | bl.Debug("debug") | ||
| 26 | } | ||
| 27 | |||
| 28 | // Test console logging by visually comparing the lines being output with and | ||
| 29 | // without a log level specification. | ||
| 16 | func TestConsole(t *testing.T) { | 30 | func TestConsole(t *testing.T) { |
| 17 | log := NewLogger(10000) | 31 | log1 := NewLogger(10000) |
| 18 | log.EnableFuncCallDepth(true) | 32 | log1.EnableFuncCallDepth(true) |
| 19 | log.SetLogger("console", "") | 33 | log1.SetLogger("console", "") |
| 20 | log.Trace("trace") | 34 | testConsoleCalls(log1) |
| 21 | log.Info("info") | 35 | |
| 22 | log.Warn("warning") | ||
| 23 | log.Debug("debug") | ||
| 24 | log.Critical("critical") | ||
| 25 | log2 := NewLogger(100) | 36 | log2 := NewLogger(100) |
| 26 | log2.SetLogger("console", `{"level":1}`) | 37 | log2.SetLogger("console", `{"level":3}`) |
| 27 | log.Trace("trace") | 38 | testConsoleCalls(log2) |
| 28 | log.Info("info") | ||
| 29 | log.Warn("warning") | ||
| 30 | log.Debug("debug") | ||
| 31 | log.Critical("critical") | ||
| 32 | } | 39 | } |
| 33 | 40 | ||
| 34 | func BenchmarkConsole(b *testing.B) { | 41 | func BenchmarkConsole(b *testing.B) { |
| ... | @@ -36,6 +43,6 @@ func BenchmarkConsole(b *testing.B) { | ... | @@ -36,6 +43,6 @@ func BenchmarkConsole(b *testing.B) { |
| 36 | log.EnableFuncCallDepth(true) | 43 | log.EnableFuncCallDepth(true) |
| 37 | log.SetLogger("console", "") | 44 | log.SetLogger("console", "") |
| 38 | for i := 0; i < b.N; i++ { | 45 | for i := 0; i < b.N; i++ { |
| 39 | log.Trace("trace") | 46 | log.Debug("debug") |
| 40 | } | 47 | } |
| 41 | } | 48 | } | ... | ... |
| ... | @@ -141,7 +141,7 @@ func (w *FileLogWriter) docheck(size int) { | ... | @@ -141,7 +141,7 @@ func (w *FileLogWriter) docheck(size int) { |
| 141 | 141 | ||
| 142 | // write logger message into file. | 142 | // write logger message into file. |
| 143 | func (w *FileLogWriter) WriteMsg(msg string, level int) error { | 143 | func (w *FileLogWriter) WriteMsg(msg string, level int) error { |
| 144 | if level < w.Level { | 144 | if level > w.Level { |
| 145 | return nil | 145 | return nil |
| 146 | } | 146 | } |
| 147 | n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] " | 147 | n := 24 + len(msg) // 24 stand for the length "2013/06/23 21:00:22 [T] " | ... | ... |
| ... | @@ -13,6 +13,7 @@ import ( | ... | @@ -13,6 +13,7 @@ import ( |
| 13 | "bufio" | 13 | "bufio" |
| 14 | "fmt" | 14 | "fmt" |
| 15 | "os" | 15 | "os" |
| 16 | "strconv" | ||
| 16 | "testing" | 17 | "testing" |
| 17 | "time" | 18 | "time" |
| 18 | ) | 19 | ) |
| ... | @@ -20,12 +21,14 @@ import ( | ... | @@ -20,12 +21,14 @@ import ( |
| 20 | func TestFile(t *testing.T) { | 21 | func TestFile(t *testing.T) { |
| 21 | log := NewLogger(10000) | 22 | log := NewLogger(10000) |
| 22 | log.SetLogger("file", `{"filename":"test.log"}`) | 23 | log.SetLogger("file", `{"filename":"test.log"}`) |
| 23 | log.Trace("test") | ||
| 24 | log.Info("info") | ||
| 25 | log.Debug("debug") | 24 | log.Debug("debug") |
| 26 | log.Warn("warning") | 25 | log.Informational("info") |
| 26 | log.Notice("notice") | ||
| 27 | log.Warning("warning") | ||
| 27 | log.Error("error") | 28 | log.Error("error") |
| 29 | log.Alert("alert") | ||
| 28 | log.Critical("critical") | 30 | log.Critical("critical") |
| 31 | log.Emergency("emergency") | ||
| 29 | time.Sleep(time.Second * 4) | 32 | time.Sleep(time.Second * 4) |
| 30 | f, err := os.Open("test.log") | 33 | f, err := os.Open("test.log") |
| 31 | if err != nil { | 34 | if err != nil { |
| ... | @@ -42,21 +45,24 @@ func TestFile(t *testing.T) { | ... | @@ -42,21 +45,24 @@ func TestFile(t *testing.T) { |
| 42 | linenum++ | 45 | linenum++ |
| 43 | } | 46 | } |
| 44 | } | 47 | } |
| 45 | if linenum != 6 { | 48 | var expected = LevelDebug + 1 |
| 46 | t.Fatal(linenum, "not line 6") | 49 | if linenum != expected { |
| 50 | t.Fatal(linenum, "not "+strconv.Itoa(expected)+" lines") | ||
| 47 | } | 51 | } |
| 48 | os.Remove("test.log") | 52 | os.Remove("test.log") |
| 49 | } | 53 | } |
| 50 | 54 | ||
| 51 | func TestFile2(t *testing.T) { | 55 | func TestFile2(t *testing.T) { |
| 52 | log := NewLogger(10000) | 56 | log := NewLogger(10000) |
| 53 | log.SetLogger("file", `{"filename":"test2.log","level":2}`) | 57 | log.SetLogger("file", fmt.Sprintf(`{"filename":"test2.log","level":%d}`, LevelError)) |
| 54 | log.Trace("test") | ||
| 55 | log.Info("info") | ||
| 56 | log.Debug("debug") | 58 | log.Debug("debug") |
| 57 | log.Warn("warning") | 59 | log.Info("info") |
| 60 | log.Notice("notice") | ||
| 61 | log.Warning("warning") | ||
| 58 | log.Error("error") | 62 | log.Error("error") |
| 63 | log.Alert("alert") | ||
| 59 | log.Critical("critical") | 64 | log.Critical("critical") |
| 65 | log.Emergency("emergency") | ||
| 60 | time.Sleep(time.Second * 4) | 66 | time.Sleep(time.Second * 4) |
| 61 | f, err := os.Open("test2.log") | 67 | f, err := os.Open("test2.log") |
| 62 | if err != nil { | 68 | if err != nil { |
| ... | @@ -73,8 +79,9 @@ func TestFile2(t *testing.T) { | ... | @@ -73,8 +79,9 @@ func TestFile2(t *testing.T) { |
| 73 | linenum++ | 79 | linenum++ |
| 74 | } | 80 | } |
| 75 | } | 81 | } |
| 76 | if linenum != 4 { | 82 | var expected = LevelError + 1 |
| 77 | t.Fatal(linenum, "not line 4") | 83 | if linenum != expected { |
| 84 | t.Fatal(linenum, "not "+strconv.Itoa(expected)+" lines") | ||
| 78 | } | 85 | } |
| 79 | os.Remove("test2.log") | 86 | os.Remove("test2.log") |
| 80 | } | 87 | } |
| ... | @@ -82,17 +89,19 @@ func TestFile2(t *testing.T) { | ... | @@ -82,17 +89,19 @@ func TestFile2(t *testing.T) { |
| 82 | func TestFileRotate(t *testing.T) { | 89 | func TestFileRotate(t *testing.T) { |
| 83 | log := NewLogger(10000) | 90 | log := NewLogger(10000) |
| 84 | log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`) | 91 | log.SetLogger("file", `{"filename":"test3.log","maxlines":4}`) |
| 85 | log.Trace("test") | ||
| 86 | log.Info("info") | ||
| 87 | log.Debug("debug") | 92 | log.Debug("debug") |
| 88 | log.Warn("warning") | 93 | log.Info("info") |
| 94 | log.Notice("notice") | ||
| 95 | log.Warning("warning") | ||
| 89 | log.Error("error") | 96 | log.Error("error") |
| 97 | log.Alert("alert") | ||
| 90 | log.Critical("critical") | 98 | log.Critical("critical") |
| 99 | log.Emergency("emergency") | ||
| 91 | time.Sleep(time.Second * 4) | 100 | time.Sleep(time.Second * 4) |
| 92 | rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) | 101 | rotatename := "test3.log" + fmt.Sprintf(".%s.%03d", time.Now().Format("2006-01-02"), 1) |
| 93 | b, err := exists(rotatename) | 102 | b, err := exists(rotatename) |
| 94 | if !b || err != nil { | 103 | if !b || err != nil { |
| 95 | t.Fatal("rotate not gen") | 104 | t.Fatal("rotate not generated") |
| 96 | } | 105 | } |
| 97 | os.Remove(rotatename) | 106 | os.Remove(rotatename) |
| 98 | os.Remove("test3.log") | 107 | os.Remove("test3.log") |
| ... | @@ -113,7 +122,7 @@ func BenchmarkFile(b *testing.B) { | ... | @@ -113,7 +122,7 @@ func BenchmarkFile(b *testing.B) { |
| 113 | log := NewLogger(100000) | 122 | log := NewLogger(100000) |
| 114 | log.SetLogger("file", `{"filename":"test4.log"}`) | 123 | log.SetLogger("file", `{"filename":"test4.log"}`) |
| 115 | for i := 0; i < b.N; i++ { | 124 | for i := 0; i < b.N; i++ { |
| 116 | log.Trace("trace") | 125 | log.Debug("debug") |
| 117 | } | 126 | } |
| 118 | os.Remove("test4.log") | 127 | os.Remove("test4.log") |
| 119 | } | 128 | } | ... | ... |
| ... | @@ -16,14 +16,25 @@ import ( | ... | @@ -16,14 +16,25 @@ import ( |
| 16 | "sync" | 16 | "sync" |
| 17 | ) | 17 | ) |
| 18 | 18 | ||
| 19 | // RFC5424 log message levels. | ||
| 19 | const ( | 20 | const ( |
| 20 | // log message levels | 21 | LevelEmergency = iota |
| 21 | LevelTrace = iota | 22 | LevelAlert |
| 22 | LevelDebug | ||
| 23 | LevelInfo | ||
| 24 | LevelWarn | ||
| 25 | LevelError | ||
| 26 | LevelCritical | 23 | LevelCritical |
| 24 | LevelError | ||
| 25 | LevelWarning | ||
| 26 | LevelNotice | ||
| 27 | LevelInformational | ||
| 28 | LevelDebug | ||
| 29 | ) | ||
| 30 | |||
| 31 | // Legacy loglevel constants to ensure backwards compatibility. | ||
| 32 | // | ||
| 33 | // Deprecated: will be removed in 1.5.0. | ||
| 34 | const ( | ||
| 35 | LevelInfo = LevelInformational | ||
| 36 | LevelTrace = LevelDebug | ||
| 37 | LevelWarn = LevelWarning | ||
| 27 | ) | 38 | ) |
| 28 | 39 | ||
| 29 | type loggerType func() LoggerInterface | 40 | type loggerType func() LoggerInterface |
| ... | @@ -72,6 +83,7 @@ type logMsg struct { | ... | @@ -72,6 +83,7 @@ type logMsg struct { |
| 72 | // if the buffering chan is full, logger adapters write to file or other way. | 83 | // if the buffering chan is full, logger adapters write to file or other way. |
| 73 | func NewLogger(channellen int64) *BeeLogger { | 84 | func NewLogger(channellen int64) *BeeLogger { |
| 74 | bl := new(BeeLogger) | 85 | bl := new(BeeLogger) |
| 86 | bl.level = LevelDebug | ||
| 75 | bl.loggerFuncCallDepth = 2 | 87 | bl.loggerFuncCallDepth = 2 |
| 76 | bl.msg = make(chan *logMsg, channellen) | 88 | bl.msg = make(chan *logMsg, channellen) |
| 77 | bl.outputs = make(map[string]LoggerInterface) | 89 | bl.outputs = make(map[string]LoggerInterface) |
| ... | @@ -113,7 +125,7 @@ func (bl *BeeLogger) DelLogger(adaptername string) error { | ... | @@ -113,7 +125,7 @@ func (bl *BeeLogger) DelLogger(adaptername string) error { |
| 113 | } | 125 | } |
| 114 | 126 | ||
| 115 | func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { | 127 | func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { |
| 116 | if bl.level > loglevel { | 128 | if loglevel > bl.level { |
| 117 | return nil | 129 | return nil |
| 118 | } | 130 | } |
| 119 | lm := new(logMsg) | 131 | lm := new(logMsg) |
| ... | @@ -133,8 +145,10 @@ func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { | ... | @@ -133,8 +145,10 @@ func (bl *BeeLogger) writerMsg(loglevel int, msg string) error { |
| 133 | return nil | 145 | return nil |
| 134 | } | 146 | } |
| 135 | 147 | ||
| 136 | // set log message level. | 148 | // Set log message level. |
| 137 | // if message level (such as LevelTrace) is less than logger level (such as LevelWarn), ignore message. | 149 | // |
| 150 | // If message level (such as LevelDebug) is higher than logger level (such as LevelWarning), | ||
| 151 | // log providers will not even be sent the message. | ||
| 138 | func (bl *BeeLogger) SetLevel(l int) { | 152 | func (bl *BeeLogger) SetLevel(l int) { |
| 139 | bl.level = l | 153 | bl.level = l |
| 140 | } | 154 | } |
| ... | @@ -162,40 +176,73 @@ func (bl *BeeLogger) startLogger() { | ... | @@ -162,40 +176,73 @@ func (bl *BeeLogger) startLogger() { |
| 162 | } | 176 | } |
| 163 | } | 177 | } |
| 164 | 178 | ||
| 165 | // log trace level message. | 179 | // Log EMERGENCY level message. |
| 166 | func (bl *BeeLogger) Trace(format string, v ...interface{}) { | 180 | func (bl *BeeLogger) Emergency(format string, v ...interface{}) { |
| 167 | msg := fmt.Sprintf("[T] "+format, v...) | 181 | msg := fmt.Sprintf("[D] "+format, v...) |
| 168 | bl.writerMsg(LevelTrace, msg) | 182 | bl.writerMsg(LevelEmergency, msg) |
| 169 | } | 183 | } |
| 170 | 184 | ||
| 171 | // log debug level message. | 185 | // Log ALERT level message. |
| 172 | func (bl *BeeLogger) Debug(format string, v ...interface{}) { | 186 | func (bl *BeeLogger) Alert(format string, v ...interface{}) { |
| 173 | msg := fmt.Sprintf("[D] "+format, v...) | 187 | msg := fmt.Sprintf("[D] "+format, v...) |
| 174 | bl.writerMsg(LevelDebug, msg) | 188 | bl.writerMsg(LevelAlert, msg) |
| 175 | } | 189 | } |
| 176 | 190 | ||
| 177 | // log info level message. | 191 | // Log CRITICAL level message. |
| 178 | func (bl *BeeLogger) Info(format string, v ...interface{}) { | 192 | func (bl *BeeLogger) Critical(format string, v ...interface{}) { |
| 193 | msg := fmt.Sprintf("[C] "+format, v...) | ||
| 194 | bl.writerMsg(LevelCritical, msg) | ||
| 195 | } | ||
| 196 | |||
| 197 | // Log ERROR level message. | ||
| 198 | func (bl *BeeLogger) Error(format string, v ...interface{}) { | ||
| 199 | msg := fmt.Sprintf("[E] "+format, v...) | ||
| 200 | bl.writerMsg(LevelError, msg) | ||
| 201 | } | ||
| 202 | |||
| 203 | // Log WARNING level message. | ||
| 204 | func (bl *BeeLogger) Warning(format string, v ...interface{}) { | ||
| 205 | msg := fmt.Sprintf("[W] "+format, v...) | ||
| 206 | bl.writerMsg(LevelWarning, msg) | ||
| 207 | } | ||
| 208 | |||
| 209 | // Log NOTICE level message. | ||
| 210 | func (bl *BeeLogger) Notice(format string, v ...interface{}) { | ||
| 211 | msg := fmt.Sprintf("[W] "+format, v...) | ||
| 212 | bl.writerMsg(LevelNotice, msg) | ||
| 213 | } | ||
| 214 | |||
| 215 | // Log INFORMATIONAL level message. | ||
| 216 | func (bl *BeeLogger) Informational(format string, v ...interface{}) { | ||
| 179 | msg := fmt.Sprintf("[I] "+format, v...) | 217 | msg := fmt.Sprintf("[I] "+format, v...) |
| 180 | bl.writerMsg(LevelInfo, msg) | 218 | bl.writerMsg(LevelInformational, msg) |
| 181 | } | 219 | } |
| 182 | 220 | ||
| 183 | // log warn level message. | 221 | // Log DEBUG level message. |
| 222 | func (bl *BeeLogger) Debug(format string, v ...interface{}) { | ||
| 223 | msg := fmt.Sprintf("[D] "+format, v...) | ||
| 224 | bl.writerMsg(LevelDebug, msg) | ||
| 225 | } | ||
| 226 | |||
| 227 | // Log WARN level message. | ||
| 228 | // | ||
| 229 | // Deprecated: compatibility alias for Warning(), Will be removed in 1.5.0. | ||
| 184 | func (bl *BeeLogger) Warn(format string, v ...interface{}) { | 230 | func (bl *BeeLogger) Warn(format string, v ...interface{}) { |
| 185 | msg := fmt.Sprintf("[W] "+format, v...) | 231 | bl.Warning(format, v...) |
| 186 | bl.writerMsg(LevelWarn, msg) | ||
| 187 | } | 232 | } |
| 188 | 233 | ||
| 189 | // log error level message. | 234 | // Log INFO level message. |
| 190 | func (bl *BeeLogger) Error(format string, v ...interface{}) { | 235 | // |
| 191 | msg := fmt.Sprintf("[E] "+format, v...) | 236 | // Deprecated: compatibility alias for Informational(), Will be removed in 1.5.0. |
| 192 | bl.writerMsg(LevelError, msg) | 237 | func (bl *BeeLogger) Info(format string, v ...interface{}) { |
| 238 | bl.Informational(format, v...) | ||
| 193 | } | 239 | } |
| 194 | 240 | ||
| 195 | // log critical level message. | 241 | // Log TRACE level message. |
| 196 | func (bl *BeeLogger) Critical(format string, v ...interface{}) { | 242 | // |
| 197 | msg := fmt.Sprintf("[C] "+format, v...) | 243 | // Deprecated: compatibility alias for Debug(), Will be removed in 1.5.0. |
| 198 | bl.writerMsg(LevelCritical, msg) | 244 | func (bl *BeeLogger) Trace(format string, v ...interface{}) { |
| 245 | bl.Debug(format, v...) | ||
| 199 | } | 246 | } |
| 200 | 247 | ||
| 201 | // flush all chan data. | 248 | // flush all chan data. | ... | ... |
| ... | @@ -57,7 +57,7 @@ func (s *SmtpWriter) Init(jsonconfig string) error { | ... | @@ -57,7 +57,7 @@ func (s *SmtpWriter) Init(jsonconfig string) error { |
| 57 | // write message in smtp writer. | 57 | // write message in smtp writer. |
| 58 | // it will send an email with subject and only this message. | 58 | // it will send an email with subject and only this message. |
| 59 | func (s *SmtpWriter) WriteMsg(msg string, level int) error { | 59 | func (s *SmtpWriter) WriteMsg(msg string, level int) error { |
| 60 | if level < s.Level { | 60 | if level > s.Level { |
| 61 | return nil | 61 | return nil |
| 62 | } | 62 | } |
| 63 | 63 | ... | ... |
-
Please register or sign in to post a comment