Skip to content

Commit ff1599a

Browse files
Added TimeEncoder flag and helper funcs
1 parent add0b64 commit ff1599a

File tree

5 files changed

+228
-28
lines changed

5 files changed

+228
-28
lines changed

go.mod

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@ require (
1717
github.com/onsi/gomega v1.10.1
1818
github.com/prometheus/client_golang v1.0.0
1919
github.com/prometheus/client_model v0.2.0
20-
github.com/prometheus/procfs v0.0.11 // indirect
2120
github.com/spf13/pflag v1.0.5
2221
go.uber.org/atomic v1.4.0 // indirect
23-
go.uber.org/zap v1.10.0
24-
golang.org/x/text v0.3.3 // indirect
2522
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
2623
gomodules.xyz/jsonpatch/v2 v2.0.1
2724
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko
2626
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
2727
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
2828
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
29+
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
2930
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
31+
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
3032
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
3133
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
3234
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@@ -221,6 +223,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
221223
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
222224
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
223225
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
226+
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
224227
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
225228
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
226229
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=

pkg/log/zap/flags.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ limitations under the License.
1919
package zap
2020

2121
import (
22+
"flag"
2223
"fmt"
2324
"strconv"
2425
"strings"
2526

26-
"github.com/spf13/pflag"
2727
"go.uber.org/zap"
2828
"go.uber.org/zap/zapcore"
2929
)
@@ -42,11 +42,11 @@ var levelStrings = map[string]zapcore.Level{
4242
}
4343

4444
type encoderFlag struct {
45-
setFunc func(zapcore.Encoder)
45+
setFunc func(NewEncoderFunc)
4646
value string
4747
}
4848

49-
var _ pflag.Value = &encoderFlag{}
49+
var _ flag.Value = &encoderFlag{}
5050

5151
func (ev *encoderFlag) String() string {
5252
return ev.value
@@ -60,32 +60,47 @@ func (ev *encoderFlag) Set(flagValue string) error {
6060
val := strings.ToLower(flagValue)
6161
switch val {
6262
case "json":
63-
ev.setFunc(newJSONEncoder())
63+
ev.setFunc(newJSONEncoder)
6464
case "console":
65-
ev.setFunc(newConsoleEncoder())
65+
ev.setFunc(newConsoleEncoder)
6666
default:
6767
return fmt.Errorf("invalid encoder value \"%s\"", flagValue)
6868
}
6969
ev.value = flagValue
7070
return nil
7171
}
7272

73-
func newJSONEncoder() zapcore.Encoder {
74-
encoderConfig := zap.NewProductionEncoderConfig()
75-
return zapcore.NewJSONEncoder(encoderConfig)
73+
type timeEncoderFlag struct {
74+
setFunc func(zapcore.TimeEncoder)
75+
value string
76+
}
77+
78+
var _ flag.Value = &timeEncoderFlag{}
79+
80+
func (ev *timeEncoderFlag) String() string {
81+
return ev.value
7682
}
7783

78-
func newConsoleEncoder() zapcore.Encoder {
79-
encoderConfig := zap.NewDevelopmentEncoderConfig()
80-
return zapcore.NewConsoleEncoder(encoderConfig)
84+
func (ev *timeEncoderFlag) Type() string {
85+
return "timeencoder"
86+
}
87+
88+
func (ev *timeEncoderFlag) Set(flagValue string) error {
89+
var encoder zapcore.TimeEncoder
90+
if err := encoder.UnmarshalText([]byte(flagValue)); err != nil {
91+
return fmt.Errorf("unable to unmarshal, \"%s\"", flagValue)
92+
}
93+
ev.setFunc(encoder)
94+
ev.value = flagValue
95+
return nil
8196
}
8297

8398
type levelFlag struct {
8499
setFunc func(zapcore.LevelEnabler)
85100
value string
86101
}
87102

88-
var _ pflag.Value = &levelFlag{}
103+
var _ flag.Value = &levelFlag{}
89104

90105
func (ev *levelFlag) Set(flagValue string) error {
91106
level, validLevel := levelStrings[strings.ToLower(flagValue)]
@@ -119,7 +134,7 @@ type stackTraceFlag struct {
119134
value string
120135
}
121136

122-
var _ pflag.Value = &stackTraceFlag{}
137+
var _ flag.Value = &stackTraceFlag{}
123138

124139
func (ev *stackTraceFlag) Set(flagValue string) error {
125140
level, validLevel := levelStrings[strings.ToLower(flagValue)]

pkg/log/zap/zap.go

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

33+
// EncoderConfigOption is being used to pass options
34+
// for configuring console/json encoder.
35+
type EncoderConfigOption func(*zapcore.EncoderConfig)
36+
37+
// NewEncoderFunc is a function that creates an Encoder using the provided EncoderConfigOptions.
38+
type NewEncoderFunc func(...EncoderConfigOption) zapcore.Encoder
39+
3340
// New returns a brand new Logger configured with Opts. It
3441
// uses KubeAwareEncoder which adds Type information and
3542
// Namespace/Name to the log.
@@ -98,6 +105,33 @@ func Encoder(encoder zapcore.Encoder) func(o *Options) {
98105
}
99106
}
100107

108+
func newJSONEncoder(ecfs ...EncoderConfigOption) zapcore.Encoder {
109+
encoderConfig := zap.NewProductionEncoderConfig()
110+
for _, f := range ecfs {
111+
f(&encoderConfig)
112+
}
113+
return zapcore.NewJSONEncoder(encoderConfig)
114+
}
115+
116+
func newConsoleEncoder(ecfs ...EncoderConfigOption) zapcore.Encoder {
117+
encoderConfig := zap.NewDevelopmentEncoderConfig()
118+
for _, f := range ecfs {
119+
f(&encoderConfig)
120+
}
121+
return zapcore.NewConsoleEncoder(encoderConfig)
122+
}
123+
124+
// TimeEncoder configures how the logger will encode time format.
125+
// See Options.EncoderConfigOptions
126+
func TimeEncoder(timeEncoder zapcore.TimeEncoder) func(o *Options) {
127+
return func(o *Options) {
128+
f := func(ec *zapcore.EncoderConfig) {
129+
ec.EncodeTime = timeEncoder
130+
}
131+
o.EncoderConfigOptions = append(o.EncoderConfigOptions, f)
132+
}
133+
}
134+
101135
// Level sets the the minimum enabled logging level e.g Debug, Info
102136
// See Options.Level
103137
func Level(level zapcore.LevelEnabler) func(o *Options) {
@@ -132,6 +166,14 @@ type Options struct {
132166
// Encoder configures how Zap will encode the output. Defaults to
133167
// console when Development is true and JSON otherwise
134168
Encoder zapcore.Encoder
169+
// EncoderConfigOptions can modify the EncoderConfig needed to initialize an Encoder.
170+
// See https://godoc.org/go.uber.org/zap/zapcore#EncoderConfig for the list of options
171+
// that can be configured.
172+
// Note that the EncoderConfigOptions are not applied when the Encoder option is already set.
173+
EncoderConfigOptions []EncoderConfigOption
174+
// NewEncoder configures Encoder using the provided EncoderConfigOptions.
175+
// Note that the NewEncoder function is not used when the Encoder option is already set.
176+
NewEncoder NewEncoderFunc
135177
// DestWritter controls the destination of the log output. Defaults to
136178
// os.Stderr.
137179
DestWritter io.Writer
@@ -154,9 +196,8 @@ func (o *Options) addDefaults() {
154196
}
155197

156198
if o.Development {
157-
if o.Encoder == nil {
158-
encCfg := zap.NewDevelopmentEncoderConfig()
159-
o.Encoder = zapcore.NewConsoleEncoder(encCfg)
199+
if o.NewEncoder == nil {
200+
o.NewEncoder = newConsoleEncoder
160201
}
161202
if o.Level == nil {
162203
lvl := zap.NewAtomicLevelAt(zap.DebugLevel)
@@ -169,9 +210,8 @@ func (o *Options) addDefaults() {
169210
o.ZapOpts = append(o.ZapOpts, zap.Development())
170211

171212
} else {
172-
if o.Encoder == nil {
173-
encCfg := zap.NewProductionEncoderConfig()
174-
o.Encoder = zapcore.NewJSONEncoder(encCfg)
213+
if o.NewEncoder == nil {
214+
o.NewEncoder = newJSONEncoder
175215
}
176216
if o.Level == nil {
177217
lvl := zap.NewAtomicLevelAt(zap.InfoLevel)
@@ -186,7 +226,9 @@ func (o *Options) addDefaults() {
186226
return zapcore.NewSampler(core, time.Second, 100, 100)
187227
}))
188228
}
189-
229+
if o.Encoder == nil {
230+
o.Encoder = o.NewEncoder(o.EncoderConfigOptions...)
231+
}
190232
o.ZapOpts = append(o.ZapOpts, zap.AddStacktrace(o.StacktraceLevel))
191233
}
192234

@@ -212,7 +254,8 @@ func NewRaw(opts ...Opts) *zap.Logger {
212254
// BindFlags will parse the given flagset for zap option flags and set the log options accordingly
213255
// zap-devel: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn)
214256
// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)
215-
// zap-encoder: Zap log encoding ('json' or 'console')
257+
// zap-encoder: Zap log encoding (Eg., 'json' or 'console')
258+
// zap-time-encoder: Zap time encoding format, defaults to 'epoch'.
216259
// zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error',
217260
// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity")
218261
// zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'warn' or 'error')
@@ -223,12 +266,20 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
223266
"Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). "+
224267
"Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)")
225268

269+
// Set TimeEncoder value
270+
var timeEncVal timeEncoderFlag
271+
timeEncVal.setFunc = func(fromFlag zapcore.TimeEncoder) {
272+
// Set o.EncoderConfigOptions with zap-time-encoder
273+
TimeEncoder(fromFlag)(o)
274+
}
275+
fs.Var(&timeEncVal, "zap-time-encoder", "Zap time encoding format, defaults to 'epoch'")
276+
226277
// Set Encoder value
227278
var encVal encoderFlag
228-
encVal.setFunc = func(fromFlag zapcore.Encoder) {
229-
o.Encoder = fromFlag
279+
encVal.setFunc = func(fromFlag NewEncoderFunc) {
280+
o.NewEncoder = fromFlag
230281
}
231-
fs.Var(&encVal, "zap-encoder", "Zap log encoding ('json' or 'console')")
282+
fs.Var(&encVal, "zap-encoder", "Zap log encoding (Eg., 'json' or 'console')")
232283

233284
// Set the Log Level
234285
var levelVal levelFlag
@@ -251,10 +302,10 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
251302
// UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI.
252303
// opts := zap.Options{}
253304
// opts.BindFlags(flag.CommandLine)
305+
// flag.Parse()
254306
// log := zap.New(zap.UseFlagOptions(&opts))
255307
func UseFlagOptions(in *Options) Opts {
256308
return func(o *Options) {
257309
*o = *in
258-
o.addDefaults()
259310
}
260311
}

0 commit comments

Comments
 (0)