Skip to content

Commit eccba7c

Browse files
Added EncoderConfigOptions field in Options struct.
1 parent fb0577a commit eccba7c

File tree

5 files changed

+130
-37
lines changed

5 files changed

+130
-37
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
21-
github.com/spf13/pflag v1.0.5
2220
go.uber.org/atomic v1.4.0 // indirect
2321
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 & 6 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=
@@ -295,8 +298,6 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
295298
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
296299
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
297300
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
298-
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
299-
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
300301
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
301302
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
302303
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -414,17 +415,13 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
414415
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7 h1:HmbHVPwrPEKPGLAcHSrMe6+hqSUlvZU0rab6x5EXfGU=
415416
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
416417
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
417-
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e h1:LwyF2AFISC9nVbS6MgzsaQNSUsRXI49GS+YQ5KX/QH0=
418-
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
419418
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
420419
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
421420
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
422421
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
423422
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
424423
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
425424
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
426-
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
427-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
428425
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
429426
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
430427
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=

pkg/log/zap/flags.go

Lines changed: 7 additions & 17 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 stackLevelStrings = 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,22 @@ 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)
76-
}
77-
78-
func newConsoleEncoder() zapcore.Encoder {
79-
encoderConfig := zap.NewDevelopmentEncoderConfig()
80-
return zapcore.NewConsoleEncoder(encoderConfig)
81-
}
82-
8373
type levelFlag struct {
8474
setFunc func(zapcore.LevelEnabler)
8575
value string
8676
}
8777

88-
var _ pflag.Value = &levelFlag{}
78+
var _ flag.Value = &levelFlag{}
8979

9080
func (ev *levelFlag) Set(flagValue string) error {
9181
level, validLevel := levelStrings[strings.ToLower(flagValue)]
@@ -120,7 +110,7 @@ type stackTraceFlag struct {
120110
value string
121111
}
122112

123-
var _ pflag.Value = &stackTraceFlag{}
113+
var _ flag.Value = &stackTraceFlag{}
124114

125115
func (ev *stackTraceFlag) Set(flagValue string) error {
126116
level, validLevel := stackLevelStrings[strings.ToLower(flagValue)]

pkg/log/zap/zap.go

Lines changed: 43 additions & 11 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,22 @@ 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+
101124
// Level sets the the minimum enabled logging level e.g Debug, Info
102125
// See Options.Level
103126
func Level(level zapcore.LevelEnabler) func(o *Options) {
@@ -132,6 +155,14 @@ type Options struct {
132155
// Encoder configures how Zap will encode the output. Defaults to
133156
// console when Development is true and JSON otherwise
134157
Encoder zapcore.Encoder
158+
// EncoderConfigOptions can modify the EncoderConfig needed to initialize an Encoder.
159+
// See https://godoc.org/go.uber.org/zap/zapcore#EncoderConfig for the list of options
160+
// that can be configured.
161+
// Note that the EncoderConfigOptions are not applied when the Encoder option is already set.
162+
EncoderConfigOptions []EncoderConfigOption
163+
// NewEncoder configures Encoder using the provided EncoderConfigOptions.
164+
// Note that the NewEncoder function is not used when the Encoder option is already set.
165+
NewEncoder NewEncoderFunc
135166
// DestWritter controls the destination of the log output. Defaults to
136167
// os.Stderr.
137168
DestWritter io.Writer
@@ -154,9 +185,8 @@ func (o *Options) addDefaults() {
154185
}
155186

156187
if o.Development {
157-
if o.Encoder == nil {
158-
encCfg := zap.NewDevelopmentEncoderConfig()
159-
o.Encoder = zapcore.NewConsoleEncoder(encCfg)
188+
if o.NewEncoder == nil {
189+
o.NewEncoder = newConsoleEncoder
160190
}
161191
if o.Level == nil {
162192
lvl := zap.NewAtomicLevelAt(zap.DebugLevel)
@@ -169,9 +199,8 @@ func (o *Options) addDefaults() {
169199
o.ZapOpts = append(o.ZapOpts, zap.Development())
170200

171201
} else {
172-
if o.Encoder == nil {
173-
encCfg := zap.NewProductionEncoderConfig()
174-
o.Encoder = zapcore.NewJSONEncoder(encCfg)
202+
if o.NewEncoder == nil {
203+
o.NewEncoder = newJSONEncoder
175204
}
176205
if o.Level == nil {
177206
lvl := zap.NewAtomicLevelAt(zap.InfoLevel)
@@ -190,6 +219,9 @@ func (o *Options) addDefaults() {
190219
}))
191220
}
192221
}
222+
if o.Encoder == nil {
223+
o.Encoder = o.NewEncoder(o.EncoderConfigOptions...)
224+
}
193225
o.ZapOpts = append(o.ZapOpts, zap.AddStacktrace(o.StacktraceLevel))
194226
}
195227

@@ -215,7 +247,7 @@ func NewRaw(opts ...Opts) *zap.Logger {
215247
// BindFlags will parse the given flagset for zap option flags and set the log options accordingly
216248
// zap-devel: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn)
217249
// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)
218-
// zap-encoder: Zap log encoding ('json' or 'console')
250+
// zap-encoder: Zap log encoding (Eg., 'json' or 'console')
219251
// zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error',
220252
// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity")
221253
// zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'info' or 'error')
@@ -228,10 +260,10 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
228260

229261
// Set Encoder value
230262
var encVal encoderFlag
231-
encVal.setFunc = func(fromFlag zapcore.Encoder) {
232-
o.Encoder = fromFlag
263+
encVal.setFunc = func(fromFlag NewEncoderFunc) {
264+
o.NewEncoder = fromFlag
233265
}
234-
fs.Var(&encVal, "zap-encoder", "Zap log encoding ('json' or 'console')")
266+
fs.Var(&encVal, "zap-encoder", "Zap log encoding (Eg., 'json' or 'console')")
235267

236268
// Set the Log Level
237269
var levelVal levelFlag
@@ -254,10 +286,10 @@ func (o *Options) BindFlags(fs *flag.FlagSet) {
254286
// UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI.
255287
// opts := zap.Options{}
256288
// opts.BindFlags(flag.CommandLine)
289+
// flag.Parse()
257290
// log := zap.New(zap.UseFlagOptions(&opts))
258291
func UseFlagOptions(in *Options) Opts {
259292
return func(o *Options) {
260293
*o = *in
261-
o.addDefaults()
262294
}
263295
}

pkg/log/zap/zap_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,4 +459,81 @@ var _ = Describe("Zap log level flag options setup", func() {
459459

460460
})
461461

462+
Context("with only -zap-devel flag provided", func() {
463+
It("Should set dev=true.", func() {
464+
args := []string{"--zap-devel=true"}
465+
fromFlags.BindFlags(&fs)
466+
if err := fs.Parse(args); err != nil {
467+
Expect(err).ToNot(HaveOccurred())
468+
}
469+
out := Options{}
470+
UseFlagOptions(&fromFlags)(&out)
471+
472+
Expect(out.Development).To(BeTrue())
473+
Expect(out.Encoder).To(BeNil())
474+
Expect(out.Level).To(BeNil())
475+
Expect(out.StacktraceLevel).To(BeNil())
476+
Expect(out.EncoderConfigOptions).To(BeNil())
477+
})
478+
It("Should set dev=false with log options.", func() {
479+
args := []string{"--zap-log-level=2"}
480+
fromFlags.BindFlags(&fs)
481+
if err := fs.Parse(args); err != nil {
482+
Expect(err).ToNot(HaveOccurred())
483+
}
484+
out := Options{}
485+
UseFlagOptions(&fromFlags)(&out)
486+
487+
Expect(out.Development).To(BeFalse())
488+
Expect(out.Level.Enabled(zapcore.ErrorLevel)).To(BeTrue())
489+
490+
})
491+
})
492+
493+
Context("with encoder options provided programmatically.", func() {
494+
495+
It("Should set Console Encoder, with given Nanos TimEncoder option.", func() {
496+
logOut := new(bytes.Buffer)
497+
f := func(ec *zapcore.EncoderConfig) {
498+
if err := ec.EncodeTime.UnmarshalText([]byte("nanos")); err != nil {
499+
Expect(err).ToNot(HaveOccurred())
500+
}
501+
}
502+
opts := func(o *Options) {
503+
o.EncoderConfigOptions = append(o.EncoderConfigOptions, f)
504+
}
505+
log := New(UseDevMode(true), WriteTo(logOut), opts)
506+
log.Info("This is a test message")
507+
outRaw := logOut.Bytes()
508+
// Assert for Console Encoder
509+
res := map[string]interface{}{}
510+
Expect(json.Unmarshal(outRaw, &res)).ToNot(Succeed())
511+
// Assert for Epoch Nanos TimeEncoder
512+
Expect(string(outRaw)).ShouldNot(ContainSubstring("."))
513+
514+
})
515+
It("Should set JSON Encoder, with given Millis TimEncoder option, and MessageKey", func() {
516+
logOut := new(bytes.Buffer)
517+
f := func(ec *zapcore.EncoderConfig) {
518+
ec.MessageKey = "MillisTimeFormat"
519+
if err := ec.EncodeTime.UnmarshalText([]byte("millis")); err != nil {
520+
Expect(err).ToNot(HaveOccurred())
521+
}
522+
}
523+
opts := func(o *Options) {
524+
o.EncoderConfigOptions = append(o.EncoderConfigOptions, f)
525+
}
526+
log := New(UseDevMode(false), WriteTo(logOut), opts)
527+
log.Info("This is a test message")
528+
outRaw := logOut.Bytes()
529+
// Assert for JSON Encoder
530+
res := map[string]interface{}{}
531+
Expect(json.Unmarshal(outRaw, &res)).To(Succeed())
532+
// Assert for Epoch Nanos TimeEncoder
533+
Expect(string(outRaw)).Should(ContainSubstring("."))
534+
// Assert for MessageKey
535+
Expect(string(outRaw)).Should(ContainSubstring("MillisTimeFormat"))
536+
})
537+
538+
})
462539
})

0 commit comments

Comments
 (0)