-
Couldn't load subscription status.
- Fork 11
Cobracli followup dual logger #22
Conversation
8605c81 to
02eb32f
Compare
|
Issues linked to changelog: |
| "github.com/solo-io/glooshot/pkg/version" | ||
| ) | ||
|
|
||
| var GlooshotConfig = clilog.CommandConfig{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
walkthrough: All CLIs that want to use the log util should specify this config
| } | ||
|
|
||
| //EncodeEntry implements the distinguishing features of this encoder type. | ||
| func (c cliEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
walkthrough: this is the key encoder method that implements the human-friendly console logs
| import "go.uber.org/zap/buffer" | ||
|
|
||
| var ( | ||
| _pool = buffer.NewPool() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
walkthrough: this is how zapcore does it, figured we may as well. The encoder could be simplified, but following the format of the core encoders seems like a good idea
| ctx context.Context | ||
| } | ||
|
|
||
| func (cc CommandConfig) Run() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
walkthrough: this abstracts the root error handling logic that we duplicate in most of our clis
|
|
||
| // TODO(mitchdraft) - move to go-utils https://github.com/solo-io/go-utils/issues/131 | ||
|
|
||
| func printTrimmedStack() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
walkthrough: I find this very helpful while creating tests, saves you from having to think about the Expect Offset level
| Short: "CLI for glooshot", | ||
| Version: version, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| if o.Top.Temp { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
walkthrough: this will be removed when the utils/tests are moved to go-utils
it exists as a means of executing the new console logger
|
@rickducott this introduces a few utils that will be shifted out, I added some notes to help focus your attention. Let me know if I can clarify anything |
|
regarding the simpler form of the cli encoder, I was ready to replace my implementation with: package basic_cli_encoder
import (
"go.uber.org/zap/buffer"
"go.uber.org/zap/zapcore"
"time"
)
// Unlike zap's built-in console encoder, this encoder just prints strings, in the manner of fmt.Println.
type cliEncoder struct {
printedKey string
}
// these interface methods are irrelevant to the current needs of the CLI encoder
func (c *cliEncoder) AddArray(key string, marshaler zapcore.ArrayMarshaler) error { return nil }
func (c *cliEncoder) AddObject(key string, marshaler zapcore.ObjectMarshaler) error { return nil }
func (c *cliEncoder) AddBinary(key string, value []byte) {}
func (c *cliEncoder) AddByteString(key string, value []byte) {}
func (c *cliEncoder) AddBool(key string, value bool) {}
func (c *cliEncoder) AddComplex128(key string, value complex128) {}
func (c *cliEncoder) AddComplex64(key string, value complex64) {}
func (c *cliEncoder) AddDuration(key string, value time.Duration) {}
func (c *cliEncoder) AddFloat64(key string, value float64) {}
func (c *cliEncoder) AddFloat32(key string, value float32) {}
func (c *cliEncoder) AddInt(key string, value int) {}
func (c *cliEncoder) AddInt64(key string, value int64) {}
func (c *cliEncoder) AddInt32(key string, value int32) {}
func (c *cliEncoder) AddInt16(key string, value int16) {}
func (c *cliEncoder) AddInt8(key string, value int8) {}
func (c *cliEncoder) AddTime(key string, value time.Time) {}
func (c *cliEncoder) AddString(key, val string) {}
func (c *cliEncoder) AddUint(key string, value uint) {}
func (c *cliEncoder) AddUint64(key string, value uint64) {}
func (c *cliEncoder) AddUint32(key string, value uint32) {}
func (c *cliEncoder) AddUint16(key string, value uint16) {}
func (c *cliEncoder) AddUint8(key string, value uint8) {}
func (c *cliEncoder) AddUintptr(key string, value uintptr) {}
func (c *cliEncoder) AddReflected(key string, value interface{}) error { return nil }
func (c *cliEncoder) OpenNamespace(key string) {}
func NewBasicCliEncoder(printedKey string) zapcore.Encoder {
return &cliEncoder{
printedKey: printedKey,
}
}
func (c cliEncoder) Clone() zapcore.Encoder {
return &cliEncoder{printedKey: c.printedKey}
}
func (c cliEncoder) EncodeEntry(ent zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
buf := &buffer.Buffer{}
for _, f := range fields {
if f.Key == c.printedKey {
buf.AppendString(f.String)
}
}
return buf, nil
}however it seems that zap expects the buffers to come from pools: |
|
FYI @rickducott @EItanya here is the beginning of a README for the cli logger: |
| ) | ||
| const defaultCliLogKey = "cli" | ||
|
|
||
| func CliLogError(ctx context.Context, message string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These helpers should all take variadic zap fields, it's no extra effort to allow and we likely will want to log extra information in the same command at times.
| printedKey string | ||
| } | ||
|
|
||
| // these interface methods are irrelevant to the current needs of the CLI encoder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only because we aren't trying to log extra kinds of zap fields, right? I'm not very comfortable with this tradeoff, it discourages things that would be useful for us (logging extra fields for context).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a misunderstanding
pkg/pregoutils-clilog/tester.go
Outdated
| } | ||
|
|
||
| // ExecuteCliOutErr is a helper for calling a cobra command within a test | ||
| // handleCommandError is an optional parameter that can be used for replicating the error handler that you use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this comment is out of date.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
pkg/pregoutils-clilog/tester.go
Outdated
| ct.preparedCmd.SetArgs(strings.Split(ct.TestArgs, " ")) | ||
| commandErr := ct.preparedCmd.Execute() | ||
| if commandErr != nil { | ||
| // This error handler has been specified to match the Fatalw handler used in the binary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think this comment adds much, I get that you are referring to the older implementation that wasn't as useful as a shared utility, but people using your utility don't need to know about that and just need to know we log and propagate errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
| Expect(cliOut.LoggerConsoleStderr).To(Equal(`this error log should go to file and console | ||
| `)) | ||
| // match the tags that are part of the rich log output | ||
| Expect(cliOut.LoggerFileContent).To(MatchRegexp("level")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I have not been enforcing logging in tests, only the immediate userfacing response. But for the purpose of validating the logging utilities it's a good idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, these assertions should be moved to go-utils when clilog is extracted
pkg/pregoutils-clilog/cli_encoder.go
Outdated
| return ret, nil | ||
| } | ||
|
|
||
| //EncodeEntry *Simpler* version: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove commented out stuff
| cliLogLevelWarn | ||
| cliLogLevelError | ||
| ) | ||
| const defaultCliLogKey = "cli" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have CliLoggerKey elsewhere, don't redefine it
| } | ||
|
|
||
| func CliLogErrorw(ctx context.Context, message string, keysAndValues ...interface{}) { | ||
| cliLogw(ctx, cliLogLevelError, message, defaultCliLogKey, keysAndValues...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have these, we don't need the non-"w" utilities above
BOT NOTES:
resolves #23