Skip to content

Commit

Permalink
Add TraceLevel (rs#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
crazy-max authored and rs committed Nov 4, 2019
1 parent 43d05e8 commit 4502cc1
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
13 changes: 13 additions & 0 deletions binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions console.go
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down
1 change: 1 addition & 0 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
var disabledLogger *Logger

func init() {
SetGlobalLevel(TraceLevel)
l := Nop()
disabledLogger = &l
}
Expand Down
16 changes: 8 additions & 8 deletions globals.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -83,32 +83,32 @@ var (
)

var (
gLevel = new(uint32)
disableSampling = new(uint32)
gLevel = new(int32)
disableSampling = new(int32)
)

// SetGlobalLevel sets the global override for log level. If this
// values is raised, all Loggers will use at least this value.
//
// 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
}
6 changes: 5 additions & 1 deletion hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions journald/journald.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
19 changes: 17 additions & 2 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -130,6 +132,8 @@ const (

func (l Level) String() string {
switch l {
case TraceLevel:
return "trace"
case DebugLevel:
return "debug"
case InfoLevel:
Expand All @@ -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):
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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:
Expand Down
7 changes: 7 additions & 0 deletions log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions log/log_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
11 changes: 11 additions & 0 deletions log_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
20 changes: 12 additions & 8 deletions log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 5 additions & 1 deletion sampler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions syslog.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
6 changes: 6 additions & 0 deletions syslog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"},
Expand Down

0 comments on commit 4502cc1

Please sign in to comment.