Commit 6af4fbe1 authored by Alessio Caiazza's avatar Alessio Caiazza

Upgrade logrus

parent 0177466a
......@@ -555,12 +555,15 @@
revision = "abf152e5f3e97f2fafac028d2cc06c1feb87ffa5"
[[projects]]
digest = "1:a3c8a86c096cb57ce6224ad9bf558fd15d11371f84f1f93cb2226b9de95445fc"
branch = "master"
digest = "1:bd1ebbb301e1a33a22f5e8026d64c7b48d8ed105790ab01f4ad8d3a9c28d8abf"
name = "github.com/sirupsen/logrus"
packages = ["."]
packages = [
".",
"hooks/test",
]
pruneopts = "N"
revision = "3e01752db0189b9157070a0e1668a620f9a85da2"
version = "v1.0.6"
revision = "78fa2915c1fa231f62e0438da493688c21ca678e"
[[projects]]
digest = "1:e86042cb61313f9315878e33f2713cc1a1a1c29feeb04b64c164ed55266822d9"
......@@ -1028,6 +1031,7 @@
"github.com/prometheus/client_golang/prometheus/promhttp",
"github.com/prometheus/client_model/go",
"github.com/sirupsen/logrus",
"github.com/sirupsen/logrus/hooks/test",
"github.com/stretchr/testify/assert",
"github.com/stretchr/testify/mock",
"github.com/stretchr/testify/require",
......@@ -1044,6 +1048,7 @@
"k8s.io/apimachinery/pkg/runtime",
"k8s.io/apimachinery/pkg/runtime/schema",
"k8s.io/apimachinery/pkg/runtime/serializer",
"k8s.io/apimachinery/pkg/util/runtime",
"k8s.io/client-go/kubernetes",
"k8s.io/client-go/kubernetes/scheme",
"k8s.io/client-go/plugin/pkg/client/auth",
......
......@@ -32,7 +32,7 @@ ignored = ["test", "appengine"]
[[constraint]]
name = "github.com/sirupsen/logrus"
version = "1.0.6"
branch = "master"
[[constraint]]
branch = "master"
......
......@@ -137,9 +137,9 @@ func (entry *Entry) fireHooks() {
}
func (entry *Entry) write() {
serialized, err := entry.Logger.Formatter.Format(entry)
entry.Logger.mu.Lock()
defer entry.Logger.mu.Unlock()
serialized, err := entry.Logger.Formatter.Format(entry)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
} else {
......@@ -151,7 +151,7 @@ func (entry *Entry) write() {
}
func (entry *Entry) Debug(args ...interface{}) {
if entry.Logger.level() >= DebugLevel {
if entry.Logger.IsLevelEnabled(DebugLevel) {
entry.log(DebugLevel, fmt.Sprint(args...))
}
}
......@@ -161,13 +161,13 @@ func (entry *Entry) Print(args ...interface{}) {
}
func (entry *Entry) Info(args ...interface{}) {
if entry.Logger.level() >= InfoLevel {
if entry.Logger.IsLevelEnabled(InfoLevel) {
entry.log(InfoLevel, fmt.Sprint(args...))
}
}
func (entry *Entry) Warn(args ...interface{}) {
if entry.Logger.level() >= WarnLevel {
if entry.Logger.IsLevelEnabled(WarnLevel) {
entry.log(WarnLevel, fmt.Sprint(args...))
}
}
......@@ -177,20 +177,20 @@ func (entry *Entry) Warning(args ...interface{}) {
}
func (entry *Entry) Error(args ...interface{}) {
if entry.Logger.level() >= ErrorLevel {
if entry.Logger.IsLevelEnabled(ErrorLevel) {
entry.log(ErrorLevel, fmt.Sprint(args...))
}
}
func (entry *Entry) Fatal(args ...interface{}) {
if entry.Logger.level() >= FatalLevel {
if entry.Logger.IsLevelEnabled(FatalLevel) {
entry.log(FatalLevel, fmt.Sprint(args...))
}
Exit(1)
}
func (entry *Entry) Panic(args ...interface{}) {
if entry.Logger.level() >= PanicLevel {
if entry.Logger.IsLevelEnabled(PanicLevel) {
entry.log(PanicLevel, fmt.Sprint(args...))
}
panic(fmt.Sprint(args...))
......@@ -199,13 +199,13 @@ func (entry *Entry) Panic(args ...interface{}) {
// Entry Printf family functions
func (entry *Entry) Debugf(format string, args ...interface{}) {
if entry.Logger.level() >= DebugLevel {
if entry.Logger.IsLevelEnabled(DebugLevel) {
entry.Debug(fmt.Sprintf(format, args...))
}
}
func (entry *Entry) Infof(format string, args ...interface{}) {
if entry.Logger.level() >= InfoLevel {
if entry.Logger.IsLevelEnabled(InfoLevel) {
entry.Info(fmt.Sprintf(format, args...))
}
}
......@@ -215,7 +215,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) {
}
func (entry *Entry) Warnf(format string, args ...interface{}) {
if entry.Logger.level() >= WarnLevel {
if entry.Logger.IsLevelEnabled(WarnLevel) {
entry.Warn(fmt.Sprintf(format, args...))
}
}
......@@ -225,20 +225,20 @@ func (entry *Entry) Warningf(format string, args ...interface{}) {
}
func (entry *Entry) Errorf(format string, args ...interface{}) {
if entry.Logger.level() >= ErrorLevel {
if entry.Logger.IsLevelEnabled(ErrorLevel) {
entry.Error(fmt.Sprintf(format, args...))
}
}
func (entry *Entry) Fatalf(format string, args ...interface{}) {
if entry.Logger.level() >= FatalLevel {
if entry.Logger.IsLevelEnabled(FatalLevel) {
entry.Fatal(fmt.Sprintf(format, args...))
}
Exit(1)
}
func (entry *Entry) Panicf(format string, args ...interface{}) {
if entry.Logger.level() >= PanicLevel {
if entry.Logger.IsLevelEnabled(PanicLevel) {
entry.Panic(fmt.Sprintf(format, args...))
}
}
......@@ -246,13 +246,13 @@ func (entry *Entry) Panicf(format string, args ...interface{}) {
// Entry Println family functions
func (entry *Entry) Debugln(args ...interface{}) {
if entry.Logger.level() >= DebugLevel {
if entry.Logger.IsLevelEnabled(DebugLevel) {
entry.Debug(entry.sprintlnn(args...))
}
}
func (entry *Entry) Infoln(args ...interface{}) {
if entry.Logger.level() >= InfoLevel {
if entry.Logger.IsLevelEnabled(InfoLevel) {
entry.Info(entry.sprintlnn(args...))
}
}
......@@ -262,7 +262,7 @@ func (entry *Entry) Println(args ...interface{}) {
}
func (entry *Entry) Warnln(args ...interface{}) {
if entry.Logger.level() >= WarnLevel {
if entry.Logger.IsLevelEnabled(WarnLevel) {
entry.Warn(entry.sprintlnn(args...))
}
}
......@@ -272,20 +272,20 @@ func (entry *Entry) Warningln(args ...interface{}) {
}
func (entry *Entry) Errorln(args ...interface{}) {
if entry.Logger.level() >= ErrorLevel {
if entry.Logger.IsLevelEnabled(ErrorLevel) {
entry.Error(entry.sprintlnn(args...))
}
}
func (entry *Entry) Fatalln(args ...interface{}) {
if entry.Logger.level() >= FatalLevel {
if entry.Logger.IsLevelEnabled(FatalLevel) {
entry.Fatal(entry.sprintlnn(args...))
}
Exit(1)
}
func (entry *Entry) Panicln(args ...interface{}) {
if entry.Logger.level() >= PanicLevel {
if entry.Logger.IsLevelEnabled(PanicLevel) {
entry.Panic(entry.sprintlnn(args...))
}
}
......
......@@ -21,30 +21,27 @@ func SetOutput(out io.Writer) {
// SetFormatter sets the standard logger formatter.
func SetFormatter(formatter Formatter) {
std.mu.Lock()
defer std.mu.Unlock()
std.Formatter = formatter
std.SetFormatter(formatter)
}
// SetLevel sets the standard logger level.
func SetLevel(level Level) {
std.mu.Lock()
defer std.mu.Unlock()
std.SetLevel(level)
}
// GetLevel returns the standard logger level.
func GetLevel() Level {
std.mu.Lock()
defer std.mu.Unlock()
return std.level()
return std.GetLevel()
}
// IsLevelEnabled checks if the log level of the standard logger is greater than the level param
func IsLevelEnabled(level Level) bool {
return std.IsLevelEnabled(level)
}
// AddHook adds a hook to the standard logger hooks.
func AddHook(hook Hook) {
std.mu.Lock()
defer std.mu.Unlock()
std.Hooks.Add(hook)
std.AddHook(hook)
}
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
......
package logrus
import (
"bytes"
"encoding/json"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type TestHook struct {
......@@ -85,6 +88,46 @@ func TestCanFireMultipleHooks(t *testing.T) {
})
}
type SingleLevelModifyHook struct {
ModifyHook
}
func (h *SingleLevelModifyHook) Levels() []Level {
return []Level{InfoLevel}
}
func TestHookEntryIsPristine(t *testing.T) {
l := New()
b := &bytes.Buffer{}
l.Formatter = &JSONFormatter{}
l.Out = b
l.AddHook(&SingleLevelModifyHook{})
l.Error("error message")
data := map[string]string{}
err := json.Unmarshal(b.Bytes(), &data)
require.NoError(t, err)
_, ok := data["wow"]
require.False(t, ok)
b.Reset()
l.Info("error message")
data = map[string]string{}
err = json.Unmarshal(b.Bytes(), &data)
require.NoError(t, err)
_, ok = data["wow"]
require.True(t, ok)
b.Reset()
l.Error("error message")
data = map[string]string{}
err = json.Unmarshal(b.Bytes(), &data)
require.NoError(t, err)
_, ok = data["wow"]
require.False(t, ok)
b.Reset()
}
type ErrorHook struct {
Fired bool
}
......
package logrus
import (
"bytes"
"encoding/json"
"fmt"
)
......@@ -81,9 +82,15 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
serialized, err := json.Marshal(data)
var b *bytes.Buffer
if entry.Buffer != nil {
b = entry.Buffer
} else {
b = &bytes.Buffer{}
}
err := json.NewEncoder(b).Encode(data)
if err != nil {
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
}
return append(serialized, '\n'), nil
return b.Bytes(), nil
}
......@@ -11,7 +11,7 @@ import (
type Logger struct {
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
// file, or leave it default which is `os.Stderr`. You can also set this to
// something more adventorous, such as logging to Kafka.
// something more adventurous, such as logging to Kafka.
Out io.Writer
// Hooks for the logger instance. These allow firing events based on logging
// levels and log entries. For example, to send errors to an error tracking
......@@ -85,6 +85,7 @@ func (logger *Logger) newEntry() *Entry {
}
func (logger *Logger) releaseEntry(entry *Entry) {
entry.Data = map[string]interface{}{}
logger.entryPool.Put(entry)
}
......@@ -121,7 +122,7 @@ func (logger *Logger) WithTime(t time.Time) *Entry {
}
func (logger *Logger) Debugf(format string, args ...interface{}) {
if logger.level() >= DebugLevel {
if logger.IsLevelEnabled(DebugLevel) {
entry := logger.newEntry()
entry.Debugf(format, args...)
logger.releaseEntry(entry)
......@@ -129,7 +130,7 @@ func (logger *Logger) Debugf(format string, args ...interface{}) {
}
func (logger *Logger) Infof(format string, args ...interface{}) {
if logger.level() >= InfoLevel {
if logger.IsLevelEnabled(InfoLevel) {
entry := logger.newEntry()
entry.Infof(format, args...)
logger.releaseEntry(entry)
......@@ -143,7 +144,7 @@ func (logger *Logger) Printf(format string, args ...interface{}) {
}
func (logger *Logger) Warnf(format string, args ...interface{}) {
if logger.level() >= WarnLevel {
if logger.IsLevelEnabled(WarnLevel) {
entry := logger.newEntry()
entry.Warnf(format, args...)
logger.releaseEntry(entry)
......@@ -151,7 +152,7 @@ func (logger *Logger) Warnf(format string, args ...interface{}) {
}
func (logger *Logger) Warningf(format string, args ...interface{}) {
if logger.level() >= WarnLevel {
if logger.IsLevelEnabled(WarnLevel) {
entry := logger.newEntry()
entry.Warnf(format, args...)
logger.releaseEntry(entry)
......@@ -159,7 +160,7 @@ func (logger *Logger) Warningf(format string, args ...interface{}) {
}
func (logger *Logger) Errorf(format string, args ...interface{}) {
if logger.level() >= ErrorLevel {
if logger.IsLevelEnabled(ErrorLevel) {
entry := logger.newEntry()
entry.Errorf(format, args...)
logger.releaseEntry(entry)
......@@ -167,7 +168,7 @@ func (logger *Logger) Errorf(format string, args ...interface{}) {
}
func (logger *Logger) Fatalf(format string, args ...interface{}) {
if logger.level() >= FatalLevel {
if logger.IsLevelEnabled(FatalLevel) {
entry := logger.newEntry()
entry.Fatalf(format, args...)
logger.releaseEntry(entry)
......@@ -176,7 +177,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) {
}
func (logger *Logger) Panicf(format string, args ...interface{}) {
if logger.level() >= PanicLevel {
if logger.IsLevelEnabled(PanicLevel) {
entry := logger.newEntry()
entry.Panicf(format, args...)
logger.releaseEntry(entry)
......@@ -184,7 +185,7 @@ func (logger *Logger) Panicf(format string, args ...interface{}) {
}
func (logger *Logger) Debug(args ...interface{}) {
if logger.level() >= DebugLevel {
if logger.IsLevelEnabled(DebugLevel) {
entry := logger.newEntry()
entry.Debug(args...)
logger.releaseEntry(entry)
......@@ -192,7 +193,7 @@ func (logger *Logger) Debug(args ...interface{}) {
}
func (logger *Logger) Info(args ...interface{}) {
if logger.level() >= InfoLevel {
if logger.IsLevelEnabled(InfoLevel) {
entry := logger.newEntry()
entry.Info(args...)
logger.releaseEntry(entry)
......@@ -206,7 +207,7 @@ func (logger *Logger) Print(args ...interface{}) {
}
func (logger *Logger) Warn(args ...interface{}) {
if logger.level() >= WarnLevel {
if logger.IsLevelEnabled(WarnLevel) {
entry := logger.newEntry()
entry.Warn(args...)
logger.releaseEntry(entry)
......@@ -214,7 +215,7 @@ func (logger *Logger) Warn(args ...interface{}) {
}
func (logger *Logger) Warning(args ...interface{}) {
if logger.level() >= WarnLevel {
if logger.IsLevelEnabled(WarnLevel) {
entry := logger.newEntry()
entry.Warn(args...)
logger.releaseEntry(entry)
......@@ -222,7 +223,7 @@ func (logger *Logger) Warning(args ...interface{}) {
}
func (logger *Logger) Error(args ...interface{}) {
if logger.level() >= ErrorLevel {
if logger.IsLevelEnabled(ErrorLevel) {
entry := logger.newEntry()
entry.Error(args...)
logger.releaseEntry(entry)
......@@ -230,7 +231,7 @@ func (logger *Logger) Error(args ...interface{}) {
}
func (logger *Logger) Fatal(args ...interface{}) {
if logger.level() >= FatalLevel {
if logger.IsLevelEnabled(FatalLevel) {
entry := logger.newEntry()
entry.Fatal(args...)
logger.releaseEntry(entry)
......@@ -239,7 +240,7 @@ func (logger *Logger) Fatal(args ...interface{}) {
}
func (logger *Logger) Panic(args ...interface{}) {
if logger.level() >= PanicLevel {
if logger.IsLevelEnabled(PanicLevel) {
entry := logger.newEntry()
entry.Panic(args...)
logger.releaseEntry(entry)
......@@ -247,7 +248,7 @@ func (logger *Logger) Panic(args ...interface{}) {
}
func (logger *Logger) Debugln(args ...interface{}) {
if logger.level() >= DebugLevel {
if logger.IsLevelEnabled(DebugLevel) {
entry := logger.newEntry()
entry.Debugln(args...)
logger.releaseEntry(entry)
......@@ -255,7 +256,7 @@ func (logger *Logger) Debugln(args ...interface{}) {
}
func (logger *Logger) Infoln(args ...interface{}) {
if logger.level() >= InfoLevel {
if logger.IsLevelEnabled(InfoLevel) {
entry := logger.newEntry()
entry.Infoln(args...)
logger.releaseEntry(entry)
......@@ -269,7 +270,7 @@ func (logger *Logger) Println(args ...interface{}) {
}
func (logger *Logger) Warnln(args ...interface{}) {
if logger.level() >= WarnLevel {
if logger.IsLevelEnabled(WarnLevel) {
entry := logger.newEntry()
entry.Warnln(args...)
logger.releaseEntry(entry)
......@@ -277,7 +278,7 @@ func (logger *Logger) Warnln(args ...interface{}) {
}
func (logger *Logger) Warningln(args ...interface{}) {
if logger.level() >= WarnLevel {
if logger.IsLevelEnabled(WarnLevel) {
entry := logger.newEntry()
entry.Warnln(args...)
logger.releaseEntry(entry)
......@@ -285,7 +286,7 @@ func (logger *Logger) Warningln(args ...interface{}) {
}
func (logger *Logger) Errorln(args ...interface{}) {
if logger.level() >= ErrorLevel {
if logger.IsLevelEnabled(ErrorLevel) {
entry := logger.newEntry()
entry.Errorln(args...)
logger.releaseEntry(entry)
......@@ -293,7 +294,7 @@ func (logger *Logger) Errorln(args ...interface{}) {
}
func (logger *Logger) Fatalln(args ...interface{}) {
if logger.level() >= FatalLevel {
if logger.IsLevelEnabled(FatalLevel) {
entry := logger.newEntry()
entry.Fatalln(args...)
logger.releaseEntry(entry)
......@@ -302,7 +303,7 @@ func (logger *Logger) Fatalln(args ...interface{}) {
}
func (logger *Logger) Panicln(args ...interface{}) {
if logger.level() >= PanicLevel {
if logger.IsLevelEnabled(PanicLevel) {
entry := logger.newEntry()
entry.Panicln(args...)
logger.releaseEntry(entry)
......@@ -320,18 +321,47 @@ func (logger *Logger) level() Level {
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
}
// SetLevel sets the logger level.
func (logger *Logger) SetLevel(level Level) {
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
}
func (logger *Logger) SetOutput(out io.Writer) {
logger.mu.Lock()
defer logger.mu.Unlock()
logger.Out = out
// GetLevel returns the logger level.
func (logger *Logger) GetLevel() Level {
return logger.level()
}
// AddHook adds a hook to the logger hooks.
func (logger *Logger) AddHook(hook Hook) {
logger.mu.Lock()
defer logger.mu.Unlock()
logger.Hooks.Add(hook)
}
// IsLevelEnabled checks if the log level of the logger is greater than the level param
func (logger *Logger) IsLevelEnabled(level Level) bool {
return logger.level() >= level
}
// SetFormatter sets the logger formatter.
func (logger *Logger) SetFormatter(formatter Formatter) {
logger.mu.Lock()
defer logger.mu.Unlock()
logger.Formatter = formatter
}
// SetOutput sets the logger output.
func (logger *Logger) SetOutput(output io.Writer) {
logger.mu.Lock()
defer logger.mu.Unlock()
logger.Out = output
}
// ReplaceHooks replaces the logger hooks and returns the old ones
func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
logger.mu.Lock()
oldHooks := logger.Hooks
logger.Hooks = hooks
logger.mu.Unlock()
return oldHooks
}
package logrus
import (
"io/ioutil"
"os"
"testing"
)
......@@ -59,3 +60,26 @@ func doLoggerBenchmarkNoLock(b *testing.B, out *os.File, formatter Formatter, fi
}
})
}
func BenchmarkLoggerJSONFormatter(b *testing.B) {
doLoggerBenchmarkWithFormatter(b, &JSONFormatter{})
}
func BenchmarkLoggerTextFormatter(b *testing.B) {
doLoggerBenchmarkWithFormatter(b, &TextFormatter{})
}
func doLoggerBenchmarkWithFormatter(b *testing.B, f Formatter) {
b.SetParallelism(100)
log := New()
log.Formatter = f
log.Out = ioutil.Discard
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
log.
WithField("foo1", "bar1").
WithField("foo2", "bar2").
Info("this is a dummy log")
}
})
}
......@@ -140,4 +140,11 @@ type FieldLogger interface {
Errorln(args ...interface{})
Fatalln(args ...interface{})
Panicln(args ...interface{})
// IsDebugEnabled() bool
// IsInfoEnabled() bool
// IsWarnEnabled() bool
// IsErrorEnabled() bool
// IsFatalEnabled() bool
// IsPanicEnabled() bool
}
......@@ -3,6 +3,7 @@ package logrus
import (
"bytes"
"encoding/json"
"io/ioutil"
"strconv"
"strings"
"sync"
......@@ -403,6 +404,45 @@ func TestLoggingRace(t *testing.T) {
wg.Wait()
}
func TestLoggingRaceWithHooksOnEntry(t *testing.T) {
logger := New()
hook := new(ModifyHook)
logger.AddHook(hook)
entry := logger.WithField("context", "clue")
var wg sync.WaitGroup
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
entry.Info("info")
wg.Done()
}()
}
wg.Wait()
}
func TestReplaceHooks(t *testing.T) {
old, cur := &TestHook{}, &TestHook{}
logger := New()
logger.SetOutput(ioutil.Discard)
logger.AddHook(old)
hooks := make(LevelHooks)
hooks.Add(cur)
replaced := logger.ReplaceHooks(hooks)
logger.Info("test")
assert.Equal(t, old.Fired, false)
assert.Equal(t, cur.Fired, true)
logger.ReplaceHooks(replaced)
logger.Info("test")
assert.Equal(t, old.Fired, true)
}
// Compile test
func TestLogrusInterface(t *testing.T) {
var buffer bytes.Buffer
......@@ -444,3 +484,54 @@ func TestEntryWriter(t *testing.T) {
assert.Equal(t, fields["foo"], "bar")
assert.Equal(t, fields["level"], "warning")
}
func TestLogLevelEnabled(t *testing.T) {
log := New()
log.SetLevel(PanicLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
assert.Equal(t, false, log.IsLevelEnabled(FatalLevel))
assert.Equal(t, false, log.IsLevelEnabled(ErrorLevel))
assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
log.SetLevel(FatalLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
assert.Equal(t, false, log.IsLevelEnabled(ErrorLevel))
assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))
log.SetLevel(ErrorLevel)
assert.Equal(t, true, log.IsLevelEnabled(PanicLevel))
assert.Equal(t, true, log.IsLevelEnabled(FatalLevel))
assert.Equal(t, true, log.IsLevelEnabled(ErrorLevel))
assert.Equal(t, false, log.IsLevelEnabled(WarnLevel))
assert.Equal(t, false, log.IsLevelEnabled(InfoLevel))
assert.Equal(t, false, log.IsLevelEnabled(DebugLevel))