Improve context.Context logging

This commit is contained in:
Olivier Poitrey 2017-05-20 00:22:37 -07:00
parent 4f55c107b9
commit 3f54be8716
5 changed files with 42 additions and 20 deletions

View File

@ -190,6 +190,16 @@ sampled.Info().Msg("will be logged every 10 messages")
// Output: {"time":1494567715,"sample":10,"message":"will be logged every 10 messages"} // Output: {"time":1494567715,"sample":10,"message":"will be logged every 10 messages"}
``` ```
### Pass a sub-logger by context
```go
ctx := log.With("component", "module").Logger().FromContext(ctx)
log.Ctx(ctx).Info().Msg("hello world")
// Output: {"component":"module","level":"info","message":"hello world"}
```
## Global Settings ## Global Settings
Some settings can be changed and will by applied to all loggers: Some settings can be changed and will by applied to all loggers:
@ -202,7 +212,7 @@ Some settings can be changed and will by applied to all loggers:
* `zerolog.MessageFieldName`: Can be set to customize message field name. * `zerolog.MessageFieldName`: Can be set to customize message field name.
* `zerolog.ErrorFieldName`: Can be set to customize `Err` field name. * `zerolog.ErrorFieldName`: Can be set to customize `Err` field name.
* `zerolog.SampleFieldName`: Can be set to customize the field name added when sampling is enabled. * `zerolog.SampleFieldName`: Can be set to customize the field name added when sampling is enabled.
* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. * `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with an empty string, times are formated as UNIX timestamp.
## Field Types ## Field Types
@ -216,7 +226,10 @@ Some settings can be changed and will by applied to all loggers:
### Advanced Fields ### Advanced Fields
* `Timestamp`: Insert UNIX timestamp field with `zerolog.TimestampFieldName` field name.
* `Time`: Add a field with the time formated with the `zerolog.TimeFieldFormat`.
* `Err`: Takes an `error` and render it as a string using the `zerolog.ErrorFieldName` field name. * `Err`: Takes an `error` and render it as a string using the `zerolog.ErrorFieldName` field name.
* `Timestamp`: Insert a timestamp field with `zerolog.TimestampFieldName` field name and formatted using `zerolog.TimeFieldFormat`.
* `Time`: Adds a field with the time formated with the `zerolog.TimeFieldFormat`.
* `Dur`: Adds a field with a `time.Duration` formatted as a `float`. For `int` value, use `DurInt`.
* `Dict`: Adds a sub-key/value as a field of the event.
* `Interface`: Uses reflection to marshal the type.

18
ctx.go
View File

@ -1,6 +1,11 @@
package zerolog package zerolog
import "context" import (
"context"
"io/ioutil"
)
var disabledLogger = New(ioutil.Discard).Level(Disabled)
type ctxKey struct{} type ctxKey struct{}
@ -9,8 +14,11 @@ func (l Logger) WithContext(ctx context.Context) context.Context {
return context.WithValue(ctx, ctxKey{}, l) return context.WithValue(ctx, ctxKey{}, l)
} }
// FromContext returns the Logger associated with the ctx. // Ctx returns the Logger associated with the ctx. If no logger
func FromContext(ctx context.Context) (l Logger, ok bool) { // is associated, a disabled logger is returned.
l, ok = ctx.Value(ctxKey{}).(Logger) func Ctx(ctx context.Context) Logger {
return if l, ok := ctx.Value(ctxKey{}).(Logger); ok {
return l
}
return disabledLogger
} }

View File

@ -10,19 +10,13 @@ import (
func TestCtx(t *testing.T) { func TestCtx(t *testing.T) {
log := New(ioutil.Discard) log := New(ioutil.Discard)
ctx := log.WithContext(context.Background()) ctx := log.WithContext(context.Background())
log2, ok := FromContext(ctx) log2 := Ctx(ctx)
if !ok {
t.Error("Expected ok=true from FromContext")
}
if !reflect.DeepEqual(log, log2) { if !reflect.DeepEqual(log, log2) {
t.Error("FromContext did not return the expected logger") t.Error("Ctx did not return the expected logger")
} }
log2, ok = FromContext(context.Background()) log2 = Ctx(context.Background())
if ok { if !reflect.DeepEqual(log2, disabledLogger) {
t.Error("Expected ok=false from FromContext") t.Error("Ctx did not return the expected logger")
}
if !reflect.DeepEqual(log2, Logger{}) {
t.Error("FromContext did not return the expected logger")
} }
} }

View File

@ -89,7 +89,7 @@ func (e *Event) Msgf(format string, v ...interface{}) (n int, err error) {
return e.write() return e.write()
} }
// Dict adds the field key with a dict to the *Event context. // Dict adds the field key with a dict to the event context.
// Use zerolog.Dict() to create the dictionary. // Use zerolog.Dict() to create the dictionary.
func (e *Event) Dict(key string, dict *Event) *Event { func (e *Event) Dict(key string, dict *Event) *Event {
if !e.enabled { if !e.enabled {

View File

@ -2,6 +2,7 @@
package log package log
import ( import (
"context"
"os" "os"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -76,3 +77,9 @@ func Panic() *zerolog.Event {
func Log() *zerolog.Event { func Log() *zerolog.Event {
return Logger.Log() return Logger.Log()
} }
// Ctx returns the Logger associated with the ctx. If no logger
// is associated, a disabled logger is returned.
func Ctx(ctx context.Context) zerolog.Logger {
return zerolog.Ctx(ctx)
}