Add TraceLevel (#158)
This commit is contained in:
parent
43d05e8ddf
commit
4502cc1942
|
@ -125,6 +125,7 @@ func main() {
|
||||||
* warn (`zerolog.WarnLevel`, 2)
|
* warn (`zerolog.WarnLevel`, 2)
|
||||||
* info (`zerolog.InfoLevel`, 1)
|
* info (`zerolog.InfoLevel`, 1)
|
||||||
* debug (`zerolog.DebugLevel`, 0)
|
* 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.
|
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"}
|
// 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() {
|
func ExampleLogger_Debug() {
|
||||||
dst := bytes.Buffer{}
|
dst := bytes.Buffer{}
|
||||||
log := New(&dst)
|
log := New(&dst)
|
||||||
|
|
|
@ -317,6 +317,8 @@ func consoleDefaultFormatLevel(noColor bool) Formatter {
|
||||||
var l string
|
var l string
|
||||||
if ll, ok := i.(string); ok {
|
if ll, ok := i.(string); ok {
|
||||||
switch ll {
|
switch ll {
|
||||||
|
case "trace":
|
||||||
|
l = colorize("TRC", colorMagenta, noColor)
|
||||||
case "debug":
|
case "debug":
|
||||||
l = colorize("DBG", colorYellow, noColor)
|
l = colorize("DBG", colorYellow, noColor)
|
||||||
case "info":
|
case "info":
|
||||||
|
|
1
ctx.go
1
ctx.go
|
@ -7,6 +7,7 @@ import (
|
||||||
var disabledLogger *Logger
|
var disabledLogger *Logger
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
SetGlobalLevel(TraceLevel)
|
||||||
l := Nop()
|
l := Nop()
|
||||||
disabledLogger = &l
|
disabledLogger = &l
|
||||||
}
|
}
|
||||||
|
|
16
globals.go
16
globals.go
|
@ -2,9 +2,9 @@ package zerolog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
import "sync/atomic"
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TimeFormatUnix defines a time format that makes time fields to be
|
// TimeFormatUnix defines a time format that makes time fields to be
|
||||||
|
@ -83,8 +83,8 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gLevel = new(uint32)
|
gLevel = new(int32)
|
||||||
disableSampling = new(uint32)
|
disableSampling = new(int32)
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetGlobalLevel sets the global override for log level. If this
|
// SetGlobalLevel sets the global override for log level. If this
|
||||||
|
@ -92,23 +92,23 @@ var (
|
||||||
//
|
//
|
||||||
// To globally disable logs, set GlobalLevel to Disabled.
|
// To globally disable logs, set GlobalLevel to Disabled.
|
||||||
func SetGlobalLevel(l Level) {
|
func SetGlobalLevel(l Level) {
|
||||||
atomic.StoreUint32(gLevel, uint32(l))
|
atomic.StoreInt32(gLevel, int32(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalLevel returns the current global log level
|
// GlobalLevel returns the current global log level
|
||||||
func GlobalLevel() Level {
|
func GlobalLevel() Level {
|
||||||
return Level(atomic.LoadUint32(gLevel))
|
return Level(atomic.LoadInt32(gLevel))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableSampling will disable sampling in all Loggers if true.
|
// DisableSampling will disable sampling in all Loggers if true.
|
||||||
func DisableSampling(v bool) {
|
func DisableSampling(v bool) {
|
||||||
var i uint32
|
var i int32
|
||||||
if v {
|
if v {
|
||||||
i = 1
|
i = 1
|
||||||
}
|
}
|
||||||
atomic.StoreUint32(disableSampling, i)
|
atomic.StoreInt32(disableSampling, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func samplingDisabled() bool {
|
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.
|
// LevelHook applies a different hook for each level.
|
||||||
type LevelHook struct {
|
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.
|
// Run implements the Hook interface.
|
||||||
func (h LevelHook) Run(e *Event, level Level, message string) {
|
func (h LevelHook) Run(e *Event, level Level, message string) {
|
||||||
switch level {
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
if h.TraceHook != nil {
|
||||||
|
h.TraceHook.Run(e, level, message)
|
||||||
|
}
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
if h.DebugHook != nil {
|
if h.DebugHook != nil {
|
||||||
h.DebugHook.Run(e, level, message)
|
h.DebugHook.Run(e, level, message)
|
||||||
|
|
|
@ -48,6 +48,8 @@ func levelToJPrio(zLevel string) journal.Priority {
|
||||||
lvl, _ := zerolog.ParseLevel(zLevel)
|
lvl, _ := zerolog.ParseLevel(zLevel)
|
||||||
|
|
||||||
switch lvl {
|
switch lvl {
|
||||||
|
case zerolog.TraceLevel:
|
||||||
|
return journal.PriDebug
|
||||||
case zerolog.DebugLevel:
|
case zerolog.DebugLevel:
|
||||||
return journal.PriDebug
|
return journal.PriDebug
|
||||||
case zerolog.InfoLevel:
|
case zerolog.InfoLevel:
|
||||||
|
|
19
log.go
19
log.go
|
@ -107,9 +107,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Level defines log levels.
|
// Level defines log levels.
|
||||||
type Level uint8
|
type Level int8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// TraceLevel defines trace log level.
|
||||||
|
TraceLevel Level = -1
|
||||||
// DebugLevel defines debug log level.
|
// DebugLevel defines debug log level.
|
||||||
DebugLevel Level = iota
|
DebugLevel Level = iota
|
||||||
// InfoLevel defines info log level.
|
// InfoLevel defines info log level.
|
||||||
|
@ -130,6 +132,8 @@ const (
|
||||||
|
|
||||||
func (l Level) String() string {
|
func (l Level) String() string {
|
||||||
switch l {
|
switch l {
|
||||||
|
case TraceLevel:
|
||||||
|
return "trace"
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
return "debug"
|
return "debug"
|
||||||
case InfoLevel:
|
case InfoLevel:
|
||||||
|
@ -152,6 +156,8 @@ func (l Level) String() string {
|
||||||
// returns an error if the input string does not match known values.
|
// returns an error if the input string does not match known values.
|
||||||
func ParseLevel(levelStr string) (Level, error) {
|
func ParseLevel(levelStr string) (Level, error) {
|
||||||
switch levelStr {
|
switch levelStr {
|
||||||
|
case LevelFieldMarshalFunc(TraceLevel):
|
||||||
|
return TraceLevel, nil
|
||||||
case LevelFieldMarshalFunc(DebugLevel):
|
case LevelFieldMarshalFunc(DebugLevel):
|
||||||
return DebugLevel, nil
|
return DebugLevel, nil
|
||||||
case LevelFieldMarshalFunc(InfoLevel):
|
case LevelFieldMarshalFunc(InfoLevel):
|
||||||
|
@ -198,7 +204,7 @@ func New(w io.Writer) Logger {
|
||||||
if !ok {
|
if !ok {
|
||||||
lw = levelWriterAdapter{w}
|
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.
|
// 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
|
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.
|
// Debug starts a new message with debug level.
|
||||||
//
|
//
|
||||||
// You must call Msg on the returned event in order to send the event.
|
// 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.
|
// You must call Msg on the returned event in order to send the event.
|
||||||
func (l *Logger) WithLevel(level Level) *Event {
|
func (l *Logger) WithLevel(level Level) *Event {
|
||||||
switch level {
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
return l.Trace()
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
return l.Debug()
|
return l.Debug()
|
||||||
case InfoLevel:
|
case InfoLevel:
|
||||||
|
|
|
@ -37,6 +37,13 @@ func Hook(h zerolog.Hook) zerolog.Logger {
|
||||||
return Logger.Hook(h)
|
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.
|
// Debug starts a new message with debug level.
|
||||||
//
|
//
|
||||||
// You must call Msg on the returned event in order to send the event.
|
// 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"}
|
// 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")
|
// Example of a log at a particular "level" (in this case, "debug")
|
||||||
func ExampleDebug() {
|
func ExampleDebug() {
|
||||||
setup()
|
setup()
|
||||||
|
|
|
@ -95,6 +95,17 @@ func ExampleLogger_Printf() {
|
||||||
// Output: {"level":"debug","message":"hello world"}
|
// 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() {
|
func ExampleLogger_Debug() {
|
||||||
log := zerolog.New(os.Stdout)
|
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 := New(lw)
|
||||||
|
log.Trace().Msg("0")
|
||||||
log.Debug().Msg("1")
|
log.Debug().Msg("1")
|
||||||
log.Info().Msg("2")
|
log.Info().Msg("2")
|
||||||
log.Warn().Msg("3")
|
log.Warn().Msg("3")
|
||||||
log.Error().Msg("4")
|
log.Error().Msg("4")
|
||||||
log.Log().Msg("nolevel-1")
|
log.Log().Msg("nolevel-1")
|
||||||
log.WithLevel(DebugLevel).Msg("5")
|
log.WithLevel(TraceLevel).Msg("5")
|
||||||
log.WithLevel(InfoLevel).Msg("6")
|
log.WithLevel(DebugLevel).Msg("6")
|
||||||
log.WithLevel(WarnLevel).Msg("7")
|
log.WithLevel(InfoLevel).Msg("7")
|
||||||
log.WithLevel(ErrorLevel).Msg("8")
|
log.WithLevel(WarnLevel).Msg("8")
|
||||||
|
log.WithLevel(ErrorLevel).Msg("9")
|
||||||
log.WithLevel(NoLevel).Msg("nolevel-2")
|
log.WithLevel(NoLevel).Msg("nolevel-2")
|
||||||
|
|
||||||
want := []struct {
|
want := []struct {
|
||||||
l Level
|
l Level
|
||||||
p string
|
p string
|
||||||
}{
|
}{
|
||||||
|
{TraceLevel, `{"level":"trace","message":"0"}` + "\n"},
|
||||||
{DebugLevel, `{"level":"debug","message":"1"}` + "\n"},
|
{DebugLevel, `{"level":"debug","message":"1"}` + "\n"},
|
||||||
{InfoLevel, `{"level":"info","message":"2"}` + "\n"},
|
{InfoLevel, `{"level":"info","message":"2"}` + "\n"},
|
||||||
{WarnLevel, `{"level":"warn","message":"3"}` + "\n"},
|
{WarnLevel, `{"level":"warn","message":"3"}` + "\n"},
|
||||||
{ErrorLevel, `{"level":"error","message":"4"}` + "\n"},
|
{ErrorLevel, `{"level":"error","message":"4"}` + "\n"},
|
||||||
{NoLevel, `{"message":"nolevel-1"}` + "\n"},
|
{NoLevel, `{"message":"nolevel-1"}` + "\n"},
|
||||||
{DebugLevel, `{"level":"debug","message":"5"}` + "\n"},
|
{TraceLevel, `{"level":"trace","message":"5"}` + "\n"},
|
||||||
{InfoLevel, `{"level":"info","message":"6"}` + "\n"},
|
{DebugLevel, `{"level":"debug","message":"6"}` + "\n"},
|
||||||
{WarnLevel, `{"level":"warn","message":"7"}` + "\n"},
|
{InfoLevel, `{"level":"info","message":"7"}` + "\n"},
|
||||||
{ErrorLevel, `{"level":"error","message":"8"}` + "\n"},
|
{WarnLevel, `{"level":"warn","message":"8"}` + "\n"},
|
||||||
|
{ErrorLevel, `{"level":"error","message":"9"}` + "\n"},
|
||||||
{NoLevel, `{"message":"nolevel-2"}` + "\n"},
|
{NoLevel, `{"message":"nolevel-2"}` + "\n"},
|
||||||
}
|
}
|
||||||
if got := lw.ops; !reflect.DeepEqual(got, want) {
|
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.
|
// LevelSampler applies a different sampler for each level.
|
||||||
type LevelSampler struct {
|
type LevelSampler struct {
|
||||||
DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler
|
TraceSampler, DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s LevelSampler) Sample(lvl Level) bool {
|
func (s LevelSampler) Sample(lvl Level) bool {
|
||||||
switch lvl {
|
switch lvl {
|
||||||
|
case TraceLevel:
|
||||||
|
if s.TraceSampler != nil {
|
||||||
|
return s.TraceSampler.Sample(lvl)
|
||||||
|
}
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
if s.DebugSampler != nil {
|
if s.DebugSampler != nil {
|
||||||
return s.DebugSampler.Sample(lvl)
|
return s.DebugSampler.Sample(lvl)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
// SyslogWriter is an interface matching a syslog.Writer struct.
|
// SyslogWriter is an interface matching a syslog.Writer struct.
|
||||||
type SyslogWriter interface {
|
type SyslogWriter interface {
|
||||||
io.Writer
|
io.Writer
|
||||||
|
Trace(m string) error
|
||||||
Debug(m string) error
|
Debug(m string) error
|
||||||
Info(m string) error
|
Info(m string) error
|
||||||
Warning(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.
|
// WriteLevel implements LevelWriter interface.
|
||||||
func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
|
func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) {
|
||||||
switch level {
|
switch level {
|
||||||
|
case TraceLevel:
|
||||||
|
err = sw.w.Trace(string(p))
|
||||||
case DebugLevel:
|
case DebugLevel:
|
||||||
err = sw.w.Debug(string(p))
|
err = sw.w.Debug(string(p))
|
||||||
case InfoLevel:
|
case InfoLevel:
|
||||||
|
|
|
@ -17,6 +17,10 @@ type syslogTestWriter struct {
|
||||||
func (w *syslogTestWriter) Write(p []byte) (int, error) {
|
func (w *syslogTestWriter) Write(p []byte) (int, error) {
|
||||||
return 0, nil
|
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 {
|
func (w *syslogTestWriter) Debug(m string) error {
|
||||||
w.events = append(w.events, syslogEvent{"Debug", m})
|
w.events = append(w.events, syslogEvent{"Debug", m})
|
||||||
return nil
|
return nil
|
||||||
|
@ -45,12 +49,14 @@ func (w *syslogTestWriter) Crit(m string) error {
|
||||||
func TestSyslogWriter(t *testing.T) {
|
func TestSyslogWriter(t *testing.T) {
|
||||||
sw := &syslogTestWriter{}
|
sw := &syslogTestWriter{}
|
||||||
log := New(SyslogLevelWriter(sw))
|
log := New(SyslogLevelWriter(sw))
|
||||||
|
log.Trace().Msg("trace")
|
||||||
log.Debug().Msg("debug")
|
log.Debug().Msg("debug")
|
||||||
log.Info().Msg("info")
|
log.Info().Msg("info")
|
||||||
log.Warn().Msg("warn")
|
log.Warn().Msg("warn")
|
||||||
log.Error().Msg("error")
|
log.Error().Msg("error")
|
||||||
log.Log().Msg("nolevel")
|
log.Log().Msg("nolevel")
|
||||||
want := []syslogEvent{
|
want := []syslogEvent{
|
||||||
|
{"Trace", `{"level":"trace","message":"trace"}` + "\n"},
|
||||||
{"Debug", `{"level":"debug","message":"debug"}` + "\n"},
|
{"Debug", `{"level":"debug","message":"debug"}` + "\n"},
|
||||||
{"Info", `{"level":"info","message":"info"}` + "\n"},
|
{"Info", `{"level":"info","message":"info"}` + "\n"},
|
||||||
{"Warning", `{"level":"warn","message":"warn"}` + "\n"},
|
{"Warning", `{"level":"warn","message":"warn"}` + "\n"},
|
||||||
|
|
Loading…
Reference in New Issue