Skip to content

Commit 16b8425

Browse files
committed
Add zap-time-encoding flag
Adds the --zap-time-encoding flag to specify the output format of the log timestamp. Allows: epoch (floating-point number of seconds since the Unix epoch), nanos (integer of nanoseconds since the Unix epoch), millis (floating-point number of milliseconds since the Unix epoch), iso8601 (ISO8601-formatted string with millisecond precision), rfc3339 (RFC3339-formatted string) and rfc3339nano (RFC3339-formatted string with nanosecond precision). Signed-off-by: Christoph Stäbler <cstabler@redhat.com>
1 parent e1880f5 commit 16b8425

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

pkg/log/zap/flags.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,41 @@ func (ev *stackTraceFlag) String() string {
128128
func (ev *stackTraceFlag) Type() string {
129129
return "level"
130130
}
131+
132+
type timeEncodingFlag struct {
133+
setFunc func(zapcore.TimeEncoder)
134+
value string
135+
}
136+
137+
var _ flag.Value = &timeEncodingFlag{}
138+
139+
func (ev *timeEncodingFlag) String() string {
140+
return ev.value
141+
}
142+
143+
func (ev *timeEncodingFlag) Type() string {
144+
return "time-encoder"
145+
}
146+
147+
func (ev *timeEncodingFlag) Set(flagValue string) error {
148+
val := strings.ToLower(flagValue)
149+
switch val {
150+
case "rfc3339nano":
151+
ev.setFunc(zapcore.RFC3339NanoTimeEncoder)
152+
case "rfc3339":
153+
ev.setFunc(zapcore.RFC3339TimeEncoder)
154+
case "iso8601":
155+
ev.setFunc(zapcore.ISO8601TimeEncoder)
156+
case "millis":
157+
ev.setFunc(zapcore.EpochMillisTimeEncoder)
158+
case "nanos":
159+
ev.setFunc(zapcore.EpochNanosTimeEncoder)
160+
case "epoch":
161+
ev.setFunc(zapcore.EpochTimeEncoder)
162+
default:
163+
return fmt.Errorf("invalid time-encoder value \"%s\"", flagValue)
164+
}
165+
166+
ev.value = flagValue
167+
return nil
168+
}

pkg/log/zap/zap.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
273273
}
274274
fs.Var(&stackVal, "zap-stacktrace-level",
275275
"Zap Level at and above which stacktraces are captured (one of 'info', 'error', 'panic').")
276+
277+
// Set the time encoding
278+
var timeEncoderVal timeEncodingFlag
279+
timeEncoderVal.setFunc = func(fromFlag zapcore.TimeEncoder) {
280+
o.EncoderConfigOptions = append(o.EncoderConfigOptions, func(ec *zapcore.EncoderConfig) {
281+
ec.EncodeTime = fromFlag
282+
})
283+
}
284+
fs.Var(&timeEncoderVal, "zap-time-encoding", "Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano')")
276285
}
277286

278287
// UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI.

pkg/log/zap/zap_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,38 @@ var _ = Describe("Zap log level flag options setup", func() {
472472
})
473473
})
474474

475+
Context("with zap-time-encoding flag provided", func() {
476+
477+
It("Should use ISO8601TimeEncoder, with iso8601 as time encoding specified", func() {
478+
// zaps ISO8601TimeEncoder uses 2006-01-02T15:04:05.000Z0700 as pattern for iso8601 encoding
479+
iso8601Pattern := `^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}\+[0-9]{4}$`
480+
481+
args := []string{"--zap-time-encoding=iso8601"}
482+
fromFlags.BindFlags(&fs)
483+
err := fs.Parse(args)
484+
Expect(err).ToNot(HaveOccurred())
485+
logOut := new(bytes.Buffer)
486+
487+
logger := New(UseFlagOptions(&fromFlags), WriteTo(logOut))
488+
logger.Info("This is a test message")
489+
490+
outRaw := logOut.Bytes()
491+
492+
res := map[string]interface{}{}
493+
Expect(json.Unmarshal(outRaw, &res)).To(Succeed())
494+
Expect(res["ts"]).Should(MatchRegexp(iso8601Pattern))
495+
})
496+
497+
It("Should return an error message, with unknown time-encoding", func() {
498+
fs = *flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
499+
args := []string{"--zap-time-encoding=foobar"}
500+
fromFlags.BindFlags(&fs)
501+
err := fs.Parse(args)
502+
Expect(err).To(HaveOccurred())
503+
})
504+
505+
})
506+
475507
Context("with encoder options provided programmatically", func() {
476508

477509
It("Should set Console Encoder, with given Nanos TimeEncoder option.", func() {

0 commit comments

Comments
 (0)