Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for iso8601 timestamps #1529

Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a236758
add support for iso8601 timestamps
otakumike Jun 7, 2019
104ad86
Update pkg/log/zap/flags.go
ironmike-au Jun 12, 2019
09ef1c9
Merge branch 'master' of https://github.com/operator-framework/operat…
otakumike Jun 12, 2019
233c09a
Merge branch 'master' into feature/add-iso8601-timestamp-support
otakumike Jun 12, 2019
0d01734
timeformat flag accepts zapcore formats
otakumike Jun 13, 2019
99d3d68
add --zap-timeformat usage doc
otakumike Jun 13, 2019
318a7dc
Update pkg/log/zap/flags.go
ironmike-au Jun 13, 2019
bcb2c7f
expand log encoder support functional options and passing multiple en…
otakumike Jun 13, 2019
ffc3558
fix encoder references in tests
otakumike Jun 13, 2019
599d633
fix encoder references in tests
otakumike Jun 13, 2019
69d4514
Update doc/user/logging.md
ironmike-au Jun 13, 2019
a6cc1b1
set the encoder in both the json and console cases
otakumike Jun 13, 2019
1e5dfee
use zap's time encoding UnmarshalText functionality to avoid manually…
otakumike Jun 13, 2019
448d1c8
rename timeformat to timeencoding/er so that it is consistent with za…
otakumike Jun 13, 2019
d4ffca5
rename timeformat to timeencoding/er so that it is consistent with za…
otakumike Jun 13, 2019
291452c
add basic tests for zap time encoding
otakumike Jun 14, 2019
62e63ff
Merge branch 'master' into feature/add-iso8601-timestamp-support
ironmike-au Jun 25, 2019
e08a62e
Merge branch 'master' into feature/add-iso8601-timestamp-support
joelanford Jul 31, 2019
12a0110
pkg/log/zap/*: test improvements for sampling and encoders
joelanford Jul 31, 2019
77dfc60
pkg/log/zap/flags*: timeEncoder Unmarshal comments/improvements
joelanford Jul 31, 2019
2a09af3
doc/user/logging.md: fix zap-time-encoding flag name
joelanford Jul 31, 2019
e108039
CHANGELOG.md,doc/user/logging.md: doc updates
joelanford Jul 31, 2019
c993d21
Merge branch 'master' into feature/add-iso8601-timestamp-support
joelanford Aug 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/user/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ By default, `zap.Logger()` will return a logger that is ready for production use
* `--zap-encoder` string - Sets the zap log encoding (`json` or `console`)
* `--zap-level` string or integer - Sets the zap log level (`debug`, `info`, `error`, or an integer value greater than 0). If 4 or greater the verbosity of client-go will be set to this level.
* `--zap-sample` - Enables zap's sampling mode. Sampling will be disabled for integer log levels greater than 1.
* `--zap-timeformat` string - Sets the zap time format ('epoch', 'millis', 'nano', or 'iso8601')


## Creating a structured log statement
Expand Down
75 changes: 63 additions & 12 deletions pkg/log/zap/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ import (
var (
zapFlagSet *pflag.FlagSet

development bool
encoderVal encoderValue
levelVal levelValue
sampleVal sampleValue
development bool
encoderVal encoderValue
levelVal levelValue
sampleVal sampleValue
timeformatVal timeformatValue
)

func init() {
Expand All @@ -41,26 +42,29 @@ func init() {
zapFlagSet.Var(&encoderVal, "zap-encoder", "Zap log encoding ('json' or 'console')")
zapFlagSet.Var(&levelVal, "zap-level", "Zap log level (one of 'debug', 'info', 'error' or any integer value > 0)")
zapFlagSet.Var(&sampleVal, "zap-sample", "Enable zap log sampling. Sampling will be disabled for integer log levels > 1")
zapFlagSet.Var(&timeformatVal, "zap-timeformat", "Sets the zap time format ('epoch', 'millis', 'nano', or 'iso8601')")
}

// FlagSet - The zap logging flagset.
func FlagSet() *pflag.FlagSet {
return zapFlagSet
}

type encoderConfigFunc func(*zapcore.EncoderConfig)

type encoderValue struct {
set bool
encoder zapcore.Encoder
str string
set bool
newEncoder func(...encoderConfigFunc) zapcore.Encoder
str string
}

func (v *encoderValue) Set(e string) error {
v.set = true
switch e {
case "json":
v.encoder = jsonEncoder()
v.newEncoder = newJSONEncoder
case "console":
v.encoder = consoleEncoder()
v.newEncoder = newConsoleEncoder
default:
return fmt.Errorf("unknown encoder \"%s\"", e)
}
Expand All @@ -76,13 +80,19 @@ func (v encoderValue) Type() string {
return "encoder"
}

func jsonEncoder() zapcore.Encoder {
func newJSONEncoder(ecfs ...encoderConfigFunc) zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
for _, f := range ecfs {
f(&encoderConfig)
}
joelanford marked this conversation as resolved.
Show resolved Hide resolved
return zapcore.NewJSONEncoder(encoderConfig)
}

func consoleEncoder() zapcore.Encoder {
encoderConfig := zap.NewDevelopmentEncoderConfig()
func newConsoleEncoder(ecfs ...encoderConfigFunc) zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
for _, f := range ecfs {
f(&encoderConfig)
}
return zapcore.NewConsoleEncoder(encoderConfig)
}

Expand Down Expand Up @@ -158,3 +168,44 @@ func (v sampleValue) IsBoolFlag() bool {
func (v sampleValue) Type() string {
return "sample"
}

type timeformatValue struct {
joelanford marked this conversation as resolved.
Show resolved Hide resolved
set bool
timeEncoder zapcore.TimeEncoder
str string
}

func (v *timeformatValue) Set(s string) error {
v.set = true

switch string(s) {
case "iso8601", "ISO8601":
v.timeEncoder = zapcore.ISO8601TimeEncoder
case "millis":
v.timeEncoder = zapcore.EpochMillisTimeEncoder
case "nanos":
v.timeEncoder = zapcore.EpochNanosTimeEncoder
default:
v.timeEncoder = zapcore.EpochTimeEncoder
}

joelanford marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

func (v timeformatValue) String() string {
return v.str
}

func (v timeformatValue) IsBoolFlag() bool {
return false
}

func (v timeformatValue) Type() string {
return "string"
joelanford marked this conversation as resolved.
Show resolved Hide resolved
}

func withTimeFormat(te zapcore.TimeEncoder) encoderConfigFunc {
joelanford marked this conversation as resolved.
Show resolved Hide resolved
return func(ec *zapcore.EncoderConfig) {
ec.EncodeTime = te
}
}
6 changes: 3 additions & 3 deletions pkg/log/zap/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ func TestEncoder(t *testing.T) {
input: "json",
expStr: "json",
expSet: true,
expEncoder: jsonEncoder(),
expEncoder: newJSONEncoder(),
},
{
name: "console encoder",
input: "console",
expStr: "console",
expSet: true,
expEncoder: consoleEncoder(),
expEncoder: newConsoleEncoder(),
},
{
name: "unknown encoder",
Expand All @@ -196,7 +196,7 @@ func TestEncoder(t *testing.T) {
assert.Equal(t, tc.expSet, encoder.set)
assert.Equal(t, "encoder", encoder.Type())
assert.Equal(t, tc.expStr, encoder.String())
assert.ObjectsAreEqual(tc.expEncoder, encoder.encoder)
assert.ObjectsAreEqual(tc.expEncoder, encoder.newEncoder)
})
}
}
18 changes: 14 additions & 4 deletions pkg/log/zap/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

"github.com/go-logr/logr"
"github.com/go-logr/zapr"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
Expand Down Expand Up @@ -56,23 +57,32 @@ type config struct {
func getConfig() config {
var c config

var newEncoder func(...encoderConfigFunc) zapcore.Encoder

// Set the defaults depending on the log mode (development vs. production)
if development {
c.encoder = consoleEncoder()
newEncoder = newConsoleEncoder
c.level = zap.NewAtomicLevelAt(zap.DebugLevel)
c.opts = append(c.opts, zap.Development(), zap.AddStacktrace(zap.ErrorLevel))
c.sample = false
} else {
c.encoder = jsonEncoder()
newEncoder = newJSONEncoder
c.level = zap.NewAtomicLevelAt(zap.InfoLevel)
c.opts = append(c.opts, zap.AddStacktrace(zap.WarnLevel))
c.sample = true
}

// Override the defaults if the flags were set explicitly on the command line
if encoderVal.set {
c.encoder = encoderVal.encoder
var ecfs []encoderConfigFunc
if encoderVal.String() == "console" {
newEncoder = newConsoleEncoder
}
joelanford marked this conversation as resolved.
Show resolved Hide resolved
if timeformatVal.set {
ecfs = append(ecfs, withTimeFormat(timeformatVal.timeEncoder))
}

c.encoder = newEncoder(ecfs...)

if levelVal.set {
c.level = zap.NewAtomicLevelAt(levelVal.level)
}
Expand Down
16 changes: 8 additions & 8 deletions pkg/log/zap/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestGetConfig(t *testing.T) {
set: false,
},
expected: config{
encoder: consoleEncoder(),
encoder: newConsoleEncoder(),
level: zap.NewAtomicLevelAt(zap.DebugLevel),
opts: append(opts, zap.Development(), zap.AddStacktrace(zap.ErrorLevel)),
sample: false,
Expand All @@ -71,7 +71,7 @@ func TestGetConfig(t *testing.T) {
set: false,
},
expected: config{
encoder: jsonEncoder(),
encoder: newJSONEncoder(),
level: zap.NewAtomicLevelAt(zap.InfoLevel),
opts: append(opts, zap.AddStacktrace(zap.WarnLevel)),
sample: true,
Expand All @@ -81,8 +81,8 @@ func TestGetConfig(t *testing.T) {
name: "set encoder",
inDevel: false,
inEncoder: encoderValue{
set: true,
encoder: consoleEncoder(),
set: true,
newEncoder: newConsoleEncoder,
},
inLevel: levelValue{
set: false,
Expand All @@ -91,7 +91,7 @@ func TestGetConfig(t *testing.T) {
set: false,
},
expected: config{
encoder: jsonEncoder(),
encoder: newJSONEncoder(),
level: zap.NewAtomicLevelAt(zap.InfoLevel),
opts: append(opts, zap.AddStacktrace(zap.WarnLevel)),
sample: true,
Expand All @@ -111,7 +111,7 @@ func TestGetConfig(t *testing.T) {
set: false,
},
expected: config{
encoder: jsonEncoder(),
encoder: newJSONEncoder(),
level: zap.NewAtomicLevelAt(zap.ErrorLevel),
opts: append(opts, zap.AddStacktrace(zap.WarnLevel)),
sample: true,
Expand All @@ -131,7 +131,7 @@ func TestGetConfig(t *testing.T) {
set: false,
},
expected: config{
encoder: jsonEncoder(),
encoder: newJSONEncoder(),
level: zap.NewAtomicLevelAt(zapcore.Level(-10)),
opts: append(opts, zap.AddStacktrace(zap.WarnLevel)),
sample: false,
Expand All @@ -152,7 +152,7 @@ func TestGetConfig(t *testing.T) {
sample: true,
},
expected: config{
encoder: jsonEncoder(),
encoder: newJSONEncoder(),
level: zap.NewAtomicLevelAt(zapcore.Level(-10)),
opts: append(opts, zap.AddStacktrace(zap.WarnLevel)),
sample: false,
joelanford marked this conversation as resolved.
Show resolved Hide resolved
Expand Down