Skip to content

Commit a4ef374

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

File tree

3 files changed

+87
-9
lines changed

3 files changed

+87
-9
lines changed

hack/tools/go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
307307
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
308308
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
309309
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
310+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
310311
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
311312
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
312313
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=

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+
var encoder zapcore.TimeEncoder
110+
val := strings.ToLower(flagValue)
111+
switch val {
112+
case "iso8601", "rfc3339", "rfc3339nano", "millis", "nanos", "epoch":
113+
if err := encoder.UnmarshalText([]byte(val)); err != nil {
114+
return fmt.Errorf("unable to unmarshal, \"%s\"", val)
115+
}
116+
default:
117+
return fmt.Errorf("invalid value for time encoder, \"%s\"", val)
118+
}
119+
ev.setFunc(encoder)
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: 35 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.
@@ -98,6 +100,14 @@ func Encoder(encoder zapcore.Encoder) func(o *Options) {
98100
}
99101
}
100102

103+
// TimeEncoder configures how the logger will encode time format.
104+
// See Options.TimeEncoder
105+
func TimeEncoder(timeEncoder zapcore.TimeEncoder) func(o *Options) {
106+
return func(o *Options) {
107+
o.TimeEncoder = timeEncoder
108+
}
109+
}
110+
101111
// Level sets the the minimum enabled logging level e.g Debug, Info
102112
// See Options.Level
103113
func Level(level *zap.AtomicLevel) func(o *Options) {
@@ -132,6 +142,8 @@ type Options struct {
132142
// Encoder configures how Zap will encode the output. Defaults to
133143
// console when Development is true and JSON otherwise
134144
Encoder zapcore.Encoder
145+
// TimeEncoder configures the zap time format. Defaults to epoch.
146+
TimeEncoder zapcore.TimeEncoder
135147
// DestWritter controls the destination of the log output. Defaults to
136148
// os.Stderr.
137149
DestWritter io.Writer
@@ -155,8 +167,10 @@ func (o *Options) addDefaults() {
155167

156168
if o.Development {
157169
if o.Encoder == nil {
158-
encCfg := zap.NewDevelopmentEncoderConfig()
159-
o.Encoder = zapcore.NewConsoleEncoder(encCfg)
170+
if o.TimeEncoder != nil {
171+
ecfs = append(ecfs, withTimeEncoding(o.TimeEncoder))
172+
}
173+
o.Encoder = newConsoleEncoder(ecfs)
160174
}
161175
if o.Level == nil {
162176
lvl := zap.NewAtomicLevelAt(zap.DebugLevel)
@@ -170,8 +184,10 @@ func (o *Options) addDefaults() {
170184

171185
} else {
172186
if o.Encoder == nil {
173-
encCfg := zap.NewProductionEncoderConfig()
174-
o.Encoder = zapcore.NewJSONEncoder(encCfg)
187+
if o.TimeEncoder != nil {
188+
ecfs = append(ecfs, withTimeEncoding(o.TimeEncoder))
189+
}
190+
o.Encoder = newJSONEncoder(ecfs)
175191
}
176192
if o.Level == nil {
177193
lvl := zap.NewAtomicLevelAt(zap.InfoLevel)
@@ -223,8 +239,14 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
223239
"Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). "+
224240
"Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)")
225241

242+
// Set TimeEncoder value
243+
var timeEncVal timeEncoderFlag
244+
timeEncVal.setFunc = func(fromFlag zapcore.TimeEncoder) {
245+
o.TimeEncoder = fromFlag
246+
}
247+
fs.Var(&timeEncVal, "zap-time-encoder", "Zap time encoding format('rfc3339', 'rfc339nanos', 'epoch', 'millis', 'nano', or 'iso8601')")
248+
226249
// Set Encoder value
227-
var encVal encoderFlag
228250
encVal.setFunc = func(fromFlag zapcore.Encoder) {
229251
o.Encoder = fromFlag
230252
}
@@ -255,6 +277,14 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
255277
func UseFlagOptions(in *Options) Opts {
256278
return func(o *Options) {
257279
*o = *in
280+
if o.Encoder != nil && o.TimeEncoder != nil {
281+
ecfs = append(ecfs, withTimeEncoding(o.TimeEncoder))
282+
if encVal.value == "json" {
283+
o.Encoder = newJSONEncoder(ecfs)
284+
} else {
285+
o.Encoder = newConsoleEncoder(ecfs)
286+
}
287+
}
258288
o.addDefaults()
259289
}
260290
}

0 commit comments

Comments
 (0)