Add TraceLevel (#158)
This commit is contained in:
parent
43d05e8ddf
commit
4502cc1942
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
1
ctx.go
|
@ -7,6 +7,7 @@ import (
|
|||
var disabledLogger *Logger
|
||||
|
||||
func init() {
|
||||
SetGlobalLevel(TraceLevel)
|
||||
l := Nop()
|
||||
disabledLogger = &l
|
||||
}
|
||||
|
|
16
globals.go
16
globals.go
|
@ -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
|
||||
}
|
||||
|
|
6
hook.go
6
hook.go
|
@ -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)
|
||||
|
|
|
@ -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
19
log.go
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
20
log_test.go
20
log_test.go
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"},
|
||||
|
|
Loading…
Reference in New Issue