zerolog icon indicating copy to clipboard operation
zerolog copied to clipboard

Console formatting for duration

Open mitar opened this issue 9 months ago • 1 comments

Console output is meant to be human-readable, but durations are shown as floats (e.g., in seconds or milliseconds) which is far from human-readable for non-simple durations. I know that the issue is that console output is interpreting data in JSON, and in JSON the fact that a field was a duration is lost, is just a number, but I still think some solution to this should be provided.

One way would be to use FormatFieldValue but sadly it does not get field name as a parameter, so one cannot hard-code it to (known/used) duration field names to convert float to formatted duration string.

Maybe DurationFields could get a list of duration field names?

Currently, it looks that the only workaround is to use FormatPrepare which can do some preprocessing based on (known/used) field names.

Any other suggestion how to tackle this?

mitar avatar Feb 16 '25 09:02 mitar

It seems there is now also FormatPartValueByName to allow formatting per field name, but this is still tricky as you have to maintain what are names of duration fields.

mitar avatar Feb 22 '25 23:02 mitar

EDIT: bit nonsense I wrote (Original below)

So the simplest solution would be to add a Global DurationFieldFormat, deprecate DurationFieldInteger and have the DurationFieldFormat by default on float. Then DurationFieldFormat could be: "float", "integer", "string" (best define a enum for that?).

WDYT @rs?

I could prepare a PR for that.

Original nonsense:

~I have the same problem. It basically applies for time.Time and time.Duration. The way zerolog works is that is calls json.AppendDuration in Dur and Time etc.~

// Dur adds the field key with duration d stored as zerolog.DurationFieldUnit.
// If zerolog.DurationFieldInteger is true, durations are rendered as integer
// instead of float.
func (e *Event) Dur(key string, d time.Duration) *Event {
	if e == nil {
		return e
	}
	e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger, FloatingPointPrecision)
	return e
}

~so the only way I see atm is to add a feature request for a global TimeMarshalFunc and DurMarshalFunc similar to InterfaceMarshalFunc.~

sruehl avatar Oct 22 '25 09:10 sruehl

sgtm

rs avatar Oct 23 '25 00:10 rs

#733 should solve this by setting DurationFieldFormat to DurationFormatString

sruehl avatar Oct 23 '25 14:10 sruehl