Skip to content

Commit 5aca8b7

Browse files
authored
Merge pull request kubernetes-sigs#767 from bharathi-tenneti/master
✨ Add helpers to configure logger options via pflags
2 parents 5747307 + 4ced175 commit 5aca8b7

File tree

4 files changed

+192
-3
lines changed

4 files changed

+192
-3
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require (
1313
github.com/onsi/gomega v1.8.1
1414
github.com/prometheus/client_golang v1.0.0
1515
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
16-
go.uber.org/atomic v1.4.0 // indirect
16+
github.com/spf13/pflag v1.0.5
1717
go.uber.org/zap v1.10.0
1818
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
1919
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 // indirect

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,6 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
319319
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
320320
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
321321
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
322-
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
323-
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
324322
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
325323
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
326324
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=

pkg/log/zap/flags.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package zap contains helpers for setting up a new logr.Logger instance
18+
// using the Zap logging framework.
19+
package zap
20+
21+
import (
22+
"fmt"
23+
"strconv"
24+
"strings"
25+
26+
"github.com/spf13/pflag"
27+
"go.uber.org/zap"
28+
"go.uber.org/zap/zapcore"
29+
)
30+
31+
var levelStrings = map[string]zapcore.Level{
32+
"debug": zap.DebugLevel,
33+
"-1": zap.DebugLevel,
34+
"info": zap.InfoLevel,
35+
"0": zap.InfoLevel,
36+
"error": zap.ErrorLevel,
37+
"2": zap.ErrorLevel,
38+
"dpanic": zap.DPanicLevel,
39+
"panic": zap.PanicLevel,
40+
"warn": zap.WarnLevel,
41+
"fatal": zap.FatalLevel,
42+
}
43+
44+
type encoderFlag struct {
45+
setFunc func(zapcore.Encoder)
46+
value string
47+
}
48+
49+
var _ pflag.Value = &encoderFlag{}
50+
51+
func (ev *encoderFlag) String() string {
52+
return ev.value
53+
}
54+
55+
func (ev *encoderFlag) Type() string {
56+
return "encoder"
57+
}
58+
59+
func (ev *encoderFlag) Set(flagValue string) error {
60+
val := strings.ToLower(flagValue)
61+
switch val {
62+
case "json":
63+
ev.setFunc(newJSONEncoder())
64+
case "console":
65+
ev.setFunc(newConsoleEncoder())
66+
default:
67+
return fmt.Errorf("invalid encoder value \"%s\"", flagValue)
68+
}
69+
ev.value = flagValue
70+
return nil
71+
}
72+
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+
83+
type levelFlag struct {
84+
setFunc func(zap.AtomicLevel)
85+
value string
86+
}
87+
88+
var _ pflag.Value = &levelFlag{}
89+
90+
func (ev *levelFlag) Set(flagValue string) error {
91+
level, validLevel := levelStrings[strings.ToLower(flagValue)]
92+
if !validLevel {
93+
logLevel, err := strconv.Atoi(flagValue)
94+
if err != nil {
95+
return fmt.Errorf("invalid log level \"%s\"", flagValue)
96+
}
97+
if logLevel > 0 {
98+
intLevel := -1 * logLevel
99+
ev.setFunc(zap.NewAtomicLevelAt(zapcore.Level(int8(intLevel))))
100+
} else {
101+
return fmt.Errorf("invalid log level \"%s\"", flagValue)
102+
}
103+
}
104+
ev.setFunc(zap.NewAtomicLevelAt(level))
105+
ev.value = flagValue
106+
return nil
107+
}
108+
109+
func (ev *levelFlag) String() string {
110+
return ev.value
111+
}
112+
113+
func (ev *levelFlag) Type() string {
114+
return "level"
115+
}
116+
117+
type stackTraceFlag struct {
118+
setFunc func(zap.AtomicLevel)
119+
value string
120+
}
121+
122+
var _ pflag.Value = &stackTraceFlag{}
123+
124+
func (ev *stackTraceFlag) Set(flagValue string) error {
125+
level, validLevel := levelStrings[strings.ToLower(flagValue)]
126+
if !validLevel {
127+
return fmt.Errorf("invalid stacktrace level \"%s\"", flagValue)
128+
}
129+
ev.setFunc(zap.NewAtomicLevelAt(level))
130+
ev.value = flagValue
131+
return nil
132+
}
133+
134+
func (ev *stackTraceFlag) String() string {
135+
return ev.value
136+
}
137+
138+
func (ev *stackTraceFlag) Type() string {
139+
return "level"
140+
}

pkg/log/zap/zap.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ limitations under the License.
1919
package zap
2020

2121
import (
22+
"flag"
2223
"io"
2324
"os"
2425
"time"
@@ -207,3 +208,53 @@ func NewRaw(opts ...Opts) *zap.Logger {
207208
log = log.WithOptions(o.ZapOpts...)
208209
return log
209210
}
211+
212+
// BindFlags will parse the given flagset for zap option flags and set the log options accordingly
213+
// zap-devel: Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn)
214+
// Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)
215+
// zap-encoder: Zap log encoding ('json' or 'console')
216+
// zap-log-level: Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error',
217+
// or any integer value > 0 which corresponds to custom debug levels of increasing verbosity")
218+
// zap-stacktrace-level: Zap Level at and above which stacktraces are captured (one of 'warn' or 'error')
219+
func (o *Options) BindFlags(fs *flag.FlagSet) {
220+
221+
// Set Development mode value
222+
fs.BoolVar(&o.Development, "zap-devel", false,
223+
"Development Mode defaults(encoder=consoleEncoder,logLevel=Debug,stackTraceLevel=Warn). "+
224+
"Production Mode defaults(encoder=jsonEncoder,logLevel=Info,stackTraceLevel=Error)")
225+
226+
// Set Encoder value
227+
var encVal encoderFlag
228+
encVal.setFunc = func(fromFlag zapcore.Encoder) {
229+
o.Encoder = fromFlag
230+
}
231+
fs.Var(&encVal, "zap-encoder", "Zap log encoding ('json' or 'console')")
232+
233+
// Set the Log Level
234+
var levelVal levelFlag
235+
levelVal.setFunc = func(fromFlag zap.AtomicLevel) {
236+
o.Level = &fromFlag
237+
}
238+
fs.Var(&levelVal, "zap-log-level",
239+
"Zap Level to configure the verbosity of logging. Can be one of 'debug', 'info', 'error', "+
240+
"or any integer value > 0 which corresponds to custom debug levels of increasing verbosity")
241+
242+
// Set the StrackTrace Level
243+
var stackVal stackTraceFlag
244+
stackVal.setFunc = func(fromFlag zap.AtomicLevel) {
245+
o.StacktraceLevel = &fromFlag
246+
}
247+
fs.Var(&stackVal, "zap-stacktrace-level",
248+
"Zap Level at and above which stacktraces are captured (one of 'warn' or 'error')")
249+
}
250+
251+
// UseFlagOptions configures the logger to use the Options set by parsing zap option flags from the CLI.
252+
// opts := zap.Options{}
253+
// opts.BindFlags(flag.CommandLine)
254+
// log := zap.New(zap.UseFlagOptions(&opts))
255+
func UseFlagOptions(in *Options) Opts {
256+
return func(o *Options) {
257+
*o = *in
258+
o.addDefaults()
259+
}
260+
}

0 commit comments

Comments
 (0)