This adds the Func log method to log using an anonymous function
only if the level is currently enabled.
The use case is for when you don't own an object and therefore can't
create your own marshaller but need to do some translation prior to
logging.
For example, this:
msg := log.Debug()
if msg.Enabled() {
msg.Str("complicated_thing", makeBinaryThingLoggable(thing))
}
msg.Msg("Sending complicated thing")
Turns into this:
log.Debug().
Func(func(e *Event) { e.Str("complicated_thing", makeBinaryThingLoggable(thing)) }).
Msg("Sending complicated thing")
* Add event.CallerSkipFrame(skip int)
This indicates that, for this event, we should skip an additional
specified number of frames.
This is cumulative, calling it twice for the same event will add both
numbers together, and this is in addition to any skip frame settings set
through the context, or globally.
The indended purpose is for wrappers to Msg or Msgf, so that the actual
caller is always printed correctly.
* Use CallerSkipFrame for Print, Printf, and Write.
This allows us to use the correct caller when using these 3 functions.
Co-authored-by: Zephaniah E. Loss-Cutler-Hull <warp@aehallh.com>
The current usage of sync.Pool is leaky because it stores an arbitrary
sized buffer into the pool. However, sync.Pool assumes that all items in the
pool are interchangeable from a memory cost perspective. Due to the unbounded
size of a buffer that may be added, it is possible for the pool to eventually
pin arbitrarily large amounts of memory in a live-lock situation.
As a simple fix, we just set a maximum size that we permit back into the pool.
The Discard method has been added to the Event type so it can be called
from a hook to prevent the event from behing printed. This new method
works outside of the context of a hook too.
Fixes#90
As per https://github.com/rs/zerolog/issues/9 and to offer a different approach from https://github.com/rs/zerolog/pull/11 and https://github.com/rs/zerolog/pull/35 this PR introduces custom error serialization with sane defaults without breaking the existing APIs.
This is just a first draft and is missing tests. Also, a bit of code duplication which I feel could be reduced but it serves to get the idea across.
It provides global error marshalling by exposing a `var ErrorMarshalFunc func(error) interface{}` in zerolog package that by default is a function that returns the passed argument. It should be overriden if you require custom error marshalling.
Then in every function that accept error or array of errors `ErrorMarshalFunc` is called on the error and then the result of it is processed like this:
- if it implements `LogObjectMarshaler`, serialize it as an object
- if it is a string serialize as a string
- if it is an error, serialize as a string with the result of `Error()`
- else serialize it as an interface
The side effect of this change is that the encoders don't need the `AppendError/s` methods anymore, as the errors are serialized directly to other types.
* Fix for a bug in cbor decodeFloat
* Add EmbedObject() method
* knob to change the depth of caller frames to skip
* removed EmbedObj() for array - since it is same as Object()
Low-level optimizations to help the compiler generate better code
when logging is disabled. Measured improvement is ~30% on amd64
(from 21 ns/op to 16 ns/op).
When error happen, there is nothing the caller can really do and it is
not practicle to handle logging errors. Print an error on the standard
error instead.