Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on May 21, 2025. It is now read-only.

Conversation

@mitchdraft
Copy link
Contributor

@mitchdraft mitchdraft commented Apr 18, 2019

BOT NOTES:
resolves #23

@mitchdraft mitchdraft force-pushed the cobracli-followup-dual-logger branch from 8605c81 to 02eb32f Compare April 18, 2019 00:25
@soloio-bot
Copy link

Issues linked to changelog:
#23

@solo-io solo-io deleted a comment from soloio-bot Apr 18, 2019
"github.com/solo-io/glooshot/pkg/version"
)

var GlooshotConfig = clilog.CommandConfig{
Copy link
Contributor Author

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) {
Copy link
Contributor Author

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()
Copy link
Contributor Author

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() {
Copy link
Contributor Author

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() {
Copy link
Contributor Author

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 {
Copy link
Contributor Author

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

@mitchdraft mitchdraft requested a review from rickducott April 19, 2019 21:39
@mitchdraft
Copy link
Contributor Author

@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

@mitchdraft
Copy link
Contributor Author

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:

=== RUN   TestInstall
Running Suite: Install Suite
============================
Random Seed: 1555786273
Will run 5 of 5 specs

      - image: "gcr.io/gloo-ee/glooshot-op:d2c4f0-18095644-pre"
        imagePullPolicy: Always
      imagePullSecrets:
•••fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x10667fb]

goroutine 10 [running]:
runtime.throw(0x217b534, 0x2a)
	/usr/local/Cellar/go/1.11.1/libexec/src/runtime/panic.go:608 +0x72 fp=0xc000e0a750 sp=0xc000e0a720 pc=0x102dc22
runtime.sigpanic()
	/usr/local/Cellar/go/1.11.1/libexec/src/runtime/signal_unix.go:374 +0x2f2 fp=0xc000e0a7a0 sp=0xc000e0a750 pc=0x1043ac2
sync.(*Pool).pin(0x0, 0x1)
	/usr/local/Cellar/go/1.11.1/libexec/src/sync/pool.go:186 +0x2b fp=0xc000e0a7c0 sp=0xc000e0a7a0 pc=0x10667fb
sync.(*Pool).Put(0x0, 0x20befc0, 0xc00051d1a0)
	/usr/local/Cellar/go/1.11.1/libexec/src/sync/pool.go:100 +0x3d fp=0xc000e0a820 sp=0xc000e0a7c0 pc=0x10663bd
github.com/solo-io/glooshot/vendor/go.uber.org/zap/buffer.Pool.put(0x0, 0xc00051d1a0)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/go.uber.org/zap/buffer/pool.go:48 +0x41 fp=0xc000e0a848 sp=0xc000e0a820 pc=0x114f871
github.com/solo-io/glooshot/vendor/go.uber.org/zap/buffer.(*Buffer).Free(0xc00051d1a0)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/go.uber.org/zap/buffer/buffer.go:114 +0x34 fp=0xc000e0a868 sp=0xc000e0a848 pc=0x114f6e4
github.com/solo-io/glooshot/vendor/go.uber.org/zap/zapcore.(*ioCore).Write(0xc0007564b0, 0x2, 0xbf26f869d3eb1b18, 0x15784ff8f, 0x3065680, 0x2143cd6, 0x3, 0x2171c49, 0x23, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/go.uber.org/zap/zapcore/core.go:91 +0x131 fp=0xc000e0a940 sp=0xc000e0a868 pc=0x116c351
github.com/solo-io/glooshot/vendor/go.uber.org/zap/zapcore.(*CheckedEntry).Write(0xc0001d1ce0, 0xc000804a00, 0x1, 0x1)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/go.uber.org/zap/zapcore/entry.go:215 +0xe9 fp=0xc000e0aab8 sp=0xc000e0a940 pc=0x116dc79
github.com/solo-io/glooshot/vendor/go.uber.org/zap.(*SugaredLogger).log(0xc000b6e080, 0x1fa2a02, 0x2171c49, 0x23, 0x0, 0x0, 0x0, 0xc000e0ac88, 0x1, 0x1)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/go.uber.org/zap/sugar.go:234 +0xf6 fp=0xc000e0ab08 sp=0xc000e0aab8 pc=0x131ae46
github.com/solo-io/glooshot/vendor/go.uber.org/zap.(*SugaredLogger).Errorw(0xc000b6e080, 0x2171c49, 0x23, 0xc000e0ac88, 0x1, 0x1)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/go.uber.org/zap/sugar.go:191 +0x79 fp=0xc000e0ab68 sp=0xc000e0ab08 pc=0x131ab29
github.com/solo-io/glooshot/pkg/pregoutils-clilog.ExecuteCliOutErr(0xc000a9c480, 0x23, 0x216378b, 0x18, 0x30291e0, 0x2, 0x2)
	/Users/mitch/go/src/github.com/solo-io/glooshot/pkg/pregoutils-clilog/tester.go:59 +0x8e9 fp=0xc000e0ade8 sp=0xc000e0ab68 pc=0x1dc8c69
github.com/solo-io/glooshot/pkg/pregoutils-clilog.(*CliTestConfig).callCobraCommandForTest(0xc000a9c480, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/pkg/pregoutils-clilog/runner.go:49 +0x7e fp=0xc000e0ae90 sp=0xc000e0ade8 pc=0x1dc803e
github.com/solo-io/glooshot/pkg/pregoutils-clilog.(*CommandConfig).RunForTest(0x3030fe0, 0x2143721, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/pkg/pregoutils-clilog/runner.go:31 +0xac fp=0xc000e0afa8 sp=0xc000e0ae90 pc=0x1dc7cac
github.com/solo-io/glooshot/test/install.glooshotWithLoggerOutput(0x2143721, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/test/install/cli_test.go:122 +0x9d fp=0xc000e0b0f0 sp=0xc000e0afa8 pc=0x1e46add
github.com/solo-io/glooshot/test/install.glob..func1.3.1()
	/Users/mitch/go/src/github.com/solo-io/glooshot/test/install/cli_test.go:65 +0x60 fp=0xc000e0b220 sp=0xc000e0b0f0 pc=0x1e4afa0
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/leafnodes.(*runner).runSync(0xc0001bca80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go:113 +0x9c fp=0xc000e0b268 sp=0xc000e0b220 pc=0x1dff2dc
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/leafnodes.(*runner).run(0xc0001bca80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/leafnodes/runner.go:64 +0x12c fp=0xc000e0b508 sp=0xc000e0b268 pc=0x1dfef4c
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/leafnodes.(*ItNode).Run(0xc0001be0e0, 0x22e52e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/leafnodes/it_node.go:26 +0x7f fp=0xc000e0b6a8 sp=0xc000e0b508 pc=0x1dfe2af
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/spec.(*Spec).runSample(0xc0000e8690, 0x0, 0x22e52e0, 0xc00003a880)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/spec/spec.go:215 +0x636 fp=0xc000e0bae8 sp=0xc000e0b6a8 pc=0x1e05c26
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/spec.(*Spec).Run(0xc0000e8690, 0x22e52e0, 0xc00003a880)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/spec/spec.go:138 +0xf7 fp=0xc000e0bb20 sp=0xc000e0bae8 pc=0x1e05437
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).runSpec(0xc0003aa780, 0xc0000e8690, 0x0)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go:200 +0x10f fp=0xc000e0bb78 sp=0xc000e0bb20 pc=0x1e0a6cf
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).runSpecs(0xc0003aa780, 0x1)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go:170 +0x328 fp=0xc000e0bc10 sp=0xc000e0bb78 pc=0x1e0a3d8
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/specrunner.(*SpecRunner).Run(0xc0003aa780, 0xd)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/specrunner/spec_runner.go:66 +0x11f fp=0xc000e0bc50 sp=0xc000e0bc10 pc=0x1e099ff
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/suite.(*Suite).Run(0xc000100690, 0x46c1018, 0xc0003ae400, 0x21548cc, 0xd, 0xc0003fc280, 0x1, 0x1, 0x2308ba0, 0xc00003a880, ...)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/internal/suite/suite.go:62 +0x28f fp=0xc000e0bd90 sp=0xc000e0bc50 pc=0x1e0beaf
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo.RunSpecsWithCustomReporters(0x22e6240, 0xc0003ae400, 0x21548cc, 0xd, 0xc000083ef8, 0x1, 0x1, 0xc000418420)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go:221 +0x247 fp=0xc000e0beb8 sp=0xc000e0bd90 pc=0x1e0e2d7
github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo.RunSpecs(0x22e6240, 0xc0003ae400, 0x21548cc, 0xd, 0x2)
	/Users/mitch/go/src/github.com/solo-io/glooshot/vendor/github.com/onsi/ginkgo/ginkgo_dsl.go:202 +0x89 fp=0xc000e0bf18 sp=0xc000e0beb8 pc=0x1e0e069
github.com/solo-io/glooshot/test/install.TestInstall(0xc0003ae400)
	/Users/mitch/go/src/github.com/solo-io/glooshot/test/install/install_suite_test.go:44 +0x277 fp=0xc000e0bfa8 sp=0xc000e0bf18 pc=0x1e46f27
testing.tRunner(0xc0003ae400, 0x21e6398)
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:827 +0xbf fp=0xc000e0bfd0 sp=0xc000e0bfa8 pc=0x10f8eef
runtime.goexit()
	/usr/local/Cellar/go/1.11.1/libexec/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc000e0bfd8 sp=0xc000e0bfd0 pc=0x105dd71
created by testing.(*T).Run
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:878 +0x353

goroutine 1 [chan receive]:
testing.(*T).Run(0xc0003ae400, 0x2151ef5, 0xb, 0x21e6398, 0x107e046)
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:879 +0x37a
testing.runTests.func1(0xc0003ae300)
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:1119 +0x78
testing.tRunner(0xc0003ae300, 0xc00064be08)
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:827 +0xbf
testing.runTests(0xc000215a00, 0x3028620, 0x1, 0x1, 0x100da8f)
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:1117 +0x2aa
testing.(*M).Run(0xc0003f8000, 0x0)
	/usr/local/Cellar/go/1.11.1/libexec/src/testing/testing.go:1034 +0x165
main.main()
	_testmain.go:42 +0x13d

etc...

@mitchdraft
Copy link
Contributor Author

FYI @rickducott @EItanya here is the beginning of a README for the cli logger:
https://github.com/solo-io/go-utils/blob/ae31d9d16fff25eb44b2150e02236c6d79d846cb/clicore/README.md
I will expand with notes on the convenience methods when ready for extraction
(in this eventual pr: https://github.com/solo-io/go-utils/blob/ae31d9d16fff25eb44b2150e02236c6d79d846cb/clicore/README.md)

)
const defaultCliLogKey = "cli"

func CliLogError(ctx context.Context, message string) {

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

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).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a misunderstanding

}

// 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

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

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.

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.

Copy link
Contributor Author

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"))

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

Copy link
Contributor Author

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

return ret, nil
}

//EncodeEntry *Simpler* version:

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"

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...)

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

@soloio-bulldozer soloio-bulldozer bot merged commit 9373581 into master Apr 22, 2019
@soloio-bulldozer soloio-bulldozer bot deleted the cobracli-followup-dual-logger branch April 22, 2019 18:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

harmonize human-friendly and debugable error logging

4 participants