Add TraceLevel (#158)

This commit is contained in:
CrazyMax 2019-11-04 20:39:22 +01:00 committed by Olivier Poitrey
parent 43d05e8ddf
commit 4502cc1942
15 changed files with 101 additions and 20 deletions

View File

@ -125,6 +125,7 @@ func main() {
* warn (`zerolog.WarnLevel`, 2)
* info (`zerolog.InfoLevel`, 1)
* debug (`zerolog.DebugLevel`, 0)
* trace (`zerolog.TraceLevel`, -1)
You can set the Global logging level to any of these options using the `SetGlobalLevel` function in the zerolog package, passing in one of the given constants above, e.g. `zerolog.InfoLevel` would be the "info" level. Whichever level is chosen, all logs with a level greater than or equal to that level will be written. To turn off logging entirely, pass the `zerolog.Disabled` constant.

View File

@ -108,6 +108,19 @@ func ExampleLogger_Printf() {
// Output: {"level":"debug","message":"hello world"}
}
func ExampleLogger_Trace() {
dst := bytes.Buffer{}
log := New(&dst)
log.Trace().
Str("foo", "bar").
Int("n", 123).
Msg("hello world")
fmt.Println(decodeIfBinaryToString(dst.Bytes()))
// Output: {"level":"trace","foo":"bar","n":123,"message":"hello world"}
}
func ExampleLogger_Debug() {
dst := bytes.Buffer{}
log := New(&dst)

View File

@ -317,6 +317,8 @@ func consoleDefaultFormatLevel(noColor bool) Formatter {
var l string
if ll, ok := i.(string); ok {
switch ll {
case "trace":
l = colorize("TRC", colorMagenta, noColor)
case "debug":
l = colorize("DBG", colorYellow, noColor)
case "info":

1
ctx.go
View File

@ -7,6 +7,7 @@ import (
var disabledLogger *Logger
func init() {
SetGlobalLevel(TraceLevel)
l := Nop()
disabledLogger = &l
}

View File

@ -2,9 +2,9 @@ package zerolog
import (
"strconv"
"sync/atomic"
"time"
)
import "sync/atomic"
const (
// TimeFormatUnix defines a time format that makes time fields to be
@ -83,8 +83,8 @@ var (
)
var (
gLevel = new(uint32)
disableSampling = new(uint32)
gLevel = new(int32)
disableSampling = new(int32)
)
// SetGlobalLevel sets the global override for log level. If this
@ -92,23 +92,23 @@ var (
//
// To globally disable logs, set GlobalLevel to Disabled.
func SetGlobalLevel(l Level) {
atomic.StoreUint32(gLevel, uint32(l))
atomic.StoreInt32(gLevel, int32(l))
}
// GlobalLevel returns the current global log level
func GlobalLevel() Level {
return Level(atomic.LoadUint32(gLevel))
return Level(atomic.LoadInt32(gLevel))
}
// DisableSampling will disable sampling in all Loggers if true.
func DisableSampling(v bool) {
var i uint32
var i int32
if v {
i = 1
}
atomic.StoreUint32(disableSampling, i)
atomic.StoreInt32(disableSampling, i)
}
func samplingDisabled() bool {
return atomic.LoadUint32(disableSampling) == 1
return atomic.LoadInt32(disableSampling) == 1
}

View File

@ -17,12 +17,16 @@ func (h HookFunc) Run(e *Event, level Level, message string) {
// LevelHook applies a different hook for each level.
type LevelHook struct {
NoLevelHook, DebugHook, InfoHook, WarnHook, ErrorHook, FatalHook, PanicHook Hook
NoLevelHook, TraceHook, DebugHook, InfoHook, WarnHook, ErrorHook, FatalHook, PanicHook Hook
}
// Run implements the Hook interface.
func (h LevelHook) Run(e *Event, level Level, message string) {
switch level {
case TraceLevel:
if h.TraceHook != nil {
h.TraceHook.Run(e, level, message)
}
case DebugLevel:
if h.DebugHook != nil {
h.DebugHook.Run(e, level, message)

View File

@ -48,6 +48,8 @@ func levelToJPrio(zLevel string) journal.Priority {
lvl, _ := zerolog.ParseLevel(zLevel)
switch lvl {
case zerolog.TraceLevel:
return journal.PriDebug
case zerolog.DebugLevel:
return journal.PriDebug
case zerolog.InfoLevel:

19
log.go
View File

@ -107,9 +107,11 @@ import (
)
// Level defines log levels.
type Level uint8
type Level int8
const (
// TraceLevel defines trace log level.
TraceLevel Level = -1
// DebugLevel defines debug log level.
DebugLevel Level = iota
// InfoLevel defines info log level.
@ -130,6 +132,8 @@ const (
func (l Level) String() string {
switch l {
case TraceLevel:
return "trace"
case DebugLevel:
return "debug"
case InfoLevel:
@ -152,6 +156,8 @@ func (l Level) String() string {
// returns an error if the input string does not match known values.
func ParseLevel(levelStr string) (Level, error) {
switch levelStr {
case LevelFieldMarshalFunc(TraceLevel):
return TraceLevel, nil
case LevelFieldMarshalFunc(DebugLevel):
return DebugLevel, nil
case LevelFieldMarshalFunc(InfoLevel):
@ -198,7 +204,7 @@ func New(w io.Writer) Logger {
if !ok {
lw = levelWriterAdapter{w}
}
return Logger{w: lw}
return Logger{w: lw, level: TraceLevel}
}
// Nop returns a disabled logger for which all operation are no-op.
@ -268,6 +274,13 @@ func (l Logger) Hook(h Hook) Logger {
return l
}
// Trace starts a new message with trace level.
//
// You must call Msg on the returned event in order to send the event.
func (l *Logger) Trace() *Event {
return l.newEvent(TraceLevel, nil)
}
// Debug starts a new message with debug level.
//
// You must call Msg on the returned event in order to send the event.
@ -331,6 +344,8 @@ func (l *Logger) Panic() *Event {
// You must call Msg on the returned event in order to send the event.
func (l *Logger) WithLevel(level Level) *Event {
switch level {
case TraceLevel:
return l.Trace()
case DebugLevel:
return l.Debug()
case InfoLevel:

View File

@ -37,6 +37,13 @@ func Hook(h zerolog.Hook) zerolog.Logger {
return Logger.Hook(h)
}
// Trace starts a new message with trace level.
//
// You must call Msg on the returned event in order to send the event.
func Trace() *zerolog.Event {
return Logger.Trace()
}
// Debug starts a new message with debug level.
//
// You must call Msg on the returned event in order to send the event.

View File

@ -54,6 +54,14 @@ func ExampleLog() {
// Output: {"time":1199811905,"message":"hello world"}
}
// Example of a log at a particular "level" (in this case, "trace")
func ExampleTrace() {
setup()
log.Trace().Msg("hello world")
// Output: {"level":"trace","time":1199811905,"message":"hello world"}
}
// Example of a log at a particular "level" (in this case, "debug")
func ExampleDebug() {
setup()

View File

@ -95,6 +95,17 @@ func ExampleLogger_Printf() {
// Output: {"level":"debug","message":"hello world"}
}
func ExampleLogger_Trace() {
log := zerolog.New(os.Stdout)
log.Trace().
Str("foo", "bar").
Int("n", 123).
Msg("hello world")
// Output: {"level":"trace","foo":"bar","n":123,"message":"hello world"}
}
func ExampleLogger_Debug() {
log := zerolog.New(os.Stdout)

View File

@ -526,30 +526,34 @@ func TestLevelWriter(t *testing.T) {
}{},
}
log := New(lw)
log.Trace().Msg("0")
log.Debug().Msg("1")
log.Info().Msg("2")
log.Warn().Msg("3")
log.Error().Msg("4")
log.Log().Msg("nolevel-1")
log.WithLevel(DebugLevel).Msg("5")
log.WithLevel(InfoLevel).Msg("6")
log.WithLevel(WarnLevel).Msg("7")
log.WithLevel(ErrorLevel).Msg("8")
log.WithLevel(TraceLevel).Msg("5")
log.WithLevel(DebugLevel).Msg("6")
log.WithLevel(InfoLevel).Msg("7")
log.WithLevel(WarnLevel).Msg("8")
log.WithLevel(ErrorLevel).Msg("9")
log.WithLevel(NoLevel).Msg("nolevel-2")
want := []struct {
l Level
p string
}{
{TraceLevel, `{"level":"trace","message":"0"}` + "\n"},
{DebugLevel, `{"level":"debug","message":"1"}` + "\n"},
{InfoLevel, `{"level":"info","message":"2"}` + "\n"},
{WarnLevel, `{"level":"warn","message":"3"}` + "\n"},
{ErrorLevel, `{"level":"error","message":"4"}` + "\n"},
{NoLevel, `{"message":"nolevel-1"}` + "\n"},
{DebugLevel, `{"level":"debug","message":"5"}` + "\n"},
{InfoLevel, `{"level":"info","message":"6"}` + "\n"},
{WarnLevel, `{"level":"warn","message":"7"}` + "\n"},
{ErrorLevel, `{"level":"error","message":"8"}` + "\n"},
{TraceLevel, `{"level":"trace","message":"5"}` + "\n"},
{DebugLevel, `{"level":"debug","message":"6"}` + "\n"},
{InfoLevel, `{"level":"info","message":"7"}` + "\n"},
{WarnLevel, `{"level":"warn","message":"8"}` + "\n"},
{ErrorLevel, `{"level":"error","message":"9"}` + "\n"},
{NoLevel, `{"message":"nolevel-2"}` + "\n"},
}
if got := lw.ops; !reflect.DeepEqual(got, want) {

View File

@ -104,11 +104,15 @@ func (s *BurstSampler) inc() uint32 {
// LevelSampler applies a different sampler for each level.
type LevelSampler struct {
DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler
TraceSampler, DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler
}
func (s LevelSampler) Sample(lvl Level) bool {
switch lvl {
case TraceLevel:
if s.TraceSampler != nil {
return s.TraceSampler.Sample(lvl)
}
case DebugLevel:
if s.DebugSampler != nil {
return s.DebugSampler.Sample(lvl)

View File

@ -10,6 +10,7 @@ import (
// SyslogWriter is an interface matching a syslog.Writer struct.
type SyslogWriter interface {
io.Writer
Trace(m string) error
Debug(m string) error
Info(m string) error
Warning(m string) error
@ -35,6 +36,8 @@ func (sw syslogWriter) Write(p []byte) (n int, err error) {
// WriteLevel implements LevelWriter interface.
func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
switch level {
case TraceLevel:
err = sw.w.Trace(string(p))
case DebugLevel:
err = sw.w.Debug(string(p))
case InfoLevel:

View File

@ -17,6 +17,10 @@ type syslogTestWriter struct {
func (w *syslogTestWriter) Write(p []byte) (int, error) {
return 0, nil
}
func (w *syslogTestWriter) Trace(m string) error {
w.events = append(w.events, syslogEvent{"Trace", m})
return nil
}
func (w *syslogTestWriter) Debug(m string) error {
w.events = append(w.events, syslogEvent{"Debug", m})
return nil
@ -45,12 +49,14 @@ func (w *syslogTestWriter) Crit(m string) error {
func TestSyslogWriter(t *testing.T) {
sw := &syslogTestWriter{}
log := New(SyslogLevelWriter(sw))
log.Trace().Msg("trace")
log.Debug().Msg("debug")
log.Info().Msg("info")
log.Warn().Msg("warn")
log.Error().Msg("error")
log.Log().Msg("nolevel")
want := []syslogEvent{
{"Trace", `{"level":"trace","message":"trace"}` + "\n"},
{"Debug", `{"level":"debug","message":"debug"}` + "\n"},
{"Info", `{"level":"info","message":"info"}` + "\n"},
{"Warning", `{"level":"warn","message":"warn"}` + "\n"},