Skip to content

Commit 596e050

Browse files
Added TimeEncoder flag and helper funcs
1 parent 8d8953d commit 596e050

File tree

2 files changed

+78
-9
lines changed

2 files changed

+78
-9
lines changed

pkg/log/zap/flags.go

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ var levelStrings = map[string]zapcore.Level{
4141
"fatal": zap.FatalLevel,
4242
}
4343

44+
type encoderConfigFunc func(*zapcore.EncoderConfig)
45+
46+
var ecfs []encoderConfigFunc
47+
4448
type encoderFlag struct {
4549
setFunc func(zapcore.Encoder)
4650
value string
@@ -60,26 +64,69 @@ func (ev *encoderFlag) Set(flagValue string) error {
6064
val := strings.ToLower(flagValue)
6165
switch val {
6266
case "json":
63-
ev.setFunc(newJSONEncoder())
67+
ev.setFunc(newJSONEncoder(ecfs))
6468
case "console":
65-
ev.setFunc(newConsoleEncoder())
69+
ev.setFunc(newConsoleEncoder(ecfs))
6670
default:
6771
return fmt.Errorf("invalid encoder value \"%s\"", flagValue)
6872
}
6973
ev.value = flagValue
7074
return nil
7175
}
7276

73-
func newJSONEncoder() zapcore.Encoder {
77+
func newJSONEncoder(ecfs []encoderConfigFunc) zapcore.Encoder {
7478
encoderConfig := zap.NewProductionEncoderConfig()
79+
for _, f := range ecfs {
80+
f(&encoderConfig)
81+
}
7582
return zapcore.NewJSONEncoder(encoderConfig)
7683
}
7784

78-
func newConsoleEncoder() zapcore.Encoder {
85+
func newConsoleEncoder(ecfs []encoderConfigFunc) zapcore.Encoder {
7986
encoderConfig := zap.NewDevelopmentEncoderConfig()
87+
for _, f := range ecfs {
88+
f(&encoderConfig)
89+
}
8090
return zapcore.NewConsoleEncoder(encoderConfig)
8191
}
8292

93+
type timeEncoderFlag struct {
94+
setFunc func(zapcore.TimeEncoder)
95+
value string
96+
}
97+
98+
var _ pflag.Value = &timeEncoderFlag{}
99+
100+
func (ev *timeEncoderFlag) String() string {
101+
return ev.value
102+
}
103+
104+
func (ev *timeEncoderFlag) Type() string {
105+
return "timeEncoder"
106+
}
107+
108+
func (ev *timeEncoderFlag) Set(flagValue string) error {
109+
val := strings.ToLower(flagValue)
110+
var timeEnc zapcore.TimeEncoder
111+
switch val {
112+
case "iso8601", "rfc3339", "rfc3339nano", "millis", "nanos", "epoch":
113+
if err := timeEnc.UnmarshalText([]byte(val)); err != nil {
114+
return fmt.Errorf("not able to unmarshal time encoder value \"%s\"", val)
115+
}
116+
ev.setFunc(timeEnc)
117+
default:
118+
return fmt.Errorf("invalid time encoder value \"%s\"", flagValue)
119+
}
120+
ev.value = flagValue
121+
return nil
122+
}
123+
124+
func withTimeEncoding(te zapcore.TimeEncoder) encoderConfigFunc {
125+
return func(ec *zapcore.EncoderConfig) {
126+
ec.EncodeTime = te
127+
}
128+
}
129+
83130
type levelFlag struct {
84131
setFunc func(zap.AtomicLevel)
85132
value string

pkg/log/zap/zap.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import (
3030
"go.uber.org/zap/zapcore"
3131
)
3232

33+
var encVal encoderFlag
34+
3335
// New returns a brand new Logger configured with Opts. It
3436
// uses KubeAwareEncoder which adds Type information and
3537
// Namespace/Name to the log.
@@ -132,6 +134,8 @@ type Options struct {
132134
// Encoder configures how Zap will encode the output. Defaults to
133135
// console when Development is true and JSON otherwise
134136
Encoder zapcore.Encoder
137+
// TimeEncoder configures the zap time format. Defaults to epoch.
138+
TimeEncoder zapcore.TimeEncoder
135139
// DestWritter controls the destination of the log output. Defaults to
136140
// os.Stderr.
137141
DestWritter io.Writer
@@ -155,8 +159,10 @@ func (o *Options) addDefaults() {
155159

156160
if o.Development {
157161
if o.Encoder == nil {
158-
encCfg := zap.NewDevelopmentEncoderConfig()
159-
o.Encoder = zapcore.NewConsoleEncoder(encCfg)
162+
if o.TimeEncoder != nil {
163+
ecfs = append(ecfs, withTimeEncoding(o.TimeEncoder))
164+
}
165+
o.Encoder = newConsoleEncoder(ecfs)
160166
}
161167
if o.Level == nil {
162168
lvl := zap.NewAtomicLevelAt(zap.DebugLevel)
@@ -170,8 +176,10 @@ func (o *Options) addDefaults() {
170176

171177
} else {
172178
if o.Encoder == nil {
173-
encCfg := zap.NewProductionEncoderConfig()
174-
o.Encoder = zapcore.NewJSONEncoder(encCfg)
179+
if o.TimeEncoder != nil {
180+
ecfs = append(ecfs, withTimeEncoding(o.TimeEncoder))
181+
}
182+
o.Encoder = newJSONEncoder(ecfs)
175183
}
176184
if o.Level == nil {
177185
lvl := zap.NewAtomicLevelAt(zap.InfoLevel)
@@ -223,8 +231,14 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
223231
"Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). "+
224232
"Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)")
225233

234+
// Set TimeEncoder value
235+
var timeEncVal timeEncoderFlag
236+
timeEncVal.setFunc = func(fromFlag zapcore.TimeEncoder) {
237+
o.TimeEncoder = fromFlag
238+
}
239+
fs.Var(&timeEncVal, "zap-time-encoder", "Zap time encoding format('rfc3339', 'rfc339nanos', 'epoch', 'millis', 'nano', or 'iso8601')")
240+
226241
// Set Encoder value
227-
var encVal encoderFlag
228242
encVal.setFunc = func(fromFlag zapcore.Encoder) {
229243
o.Encoder = fromFlag
230244
}
@@ -255,6 +269,14 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
255269
func UseFlagOptions(in *Options) Opts {
256270
return func(o *Options) {
257271
*o = *in
272+
if o.Encoder != nil && o.TimeEncoder != nil {
273+
ecfs = append(ecfs, withTimeEncoding(o.TimeEncoder))
274+
if encVal.value == "json" {
275+
o.Encoder = newJSONEncoder(ecfs)
276+
} else {
277+
o.Encoder = newConsoleEncoder(ecfs)
278+
}
279+
}
258280
o.addDefaults()
259281
}
260282
}

0 commit comments

Comments
 (0)