Print size of the message in very verbose mode (#181)
Adds -vv flag for "very verbose". Includes estimated message size when enabled. The size is an estimate because it is the canonical size for the proto message, but not necessarily its actual on-the-wire size.
This commit is contained in:
parent
41a6ac0479
commit
e544b9e66f
|
|
@ -135,6 +135,8 @@ var (
|
||||||
When describing messages, show a template of input data.`))
|
When describing messages, show a template of input data.`))
|
||||||
verbose = flags.Bool("v", false, prettify(`
|
verbose = flags.Bool("v", false, prettify(`
|
||||||
Enable verbose output.`))
|
Enable verbose output.`))
|
||||||
|
veryVerbose = flags.Bool("vv", false, prettify(`
|
||||||
|
Enable very verbose output.`))
|
||||||
serverName = flags.String("servername", "", prettify(`
|
serverName = flags.String("servername", "", prettify(`
|
||||||
Override server name when validating TLS certificate. This flag is
|
Override server name when validating TLS certificate. This flag is
|
||||||
ignored if -plaintext or -insecure is used.
|
ignored if -plaintext or -insecure is used.
|
||||||
|
|
@ -316,6 +318,14 @@ func main() {
|
||||||
invoke = true
|
invoke = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verbosityLevel := 0
|
||||||
|
if *verbose {
|
||||||
|
verbosityLevel = 1
|
||||||
|
}
|
||||||
|
if *veryVerbose {
|
||||||
|
verbosityLevel = 2
|
||||||
|
}
|
||||||
|
|
||||||
var symbol string
|
var symbol string
|
||||||
if invoke {
|
if invoke {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
|
|
@ -651,7 +661,7 @@ func main() {
|
||||||
// if not verbose output, then also include record delimiters
|
// if not verbose output, then also include record delimiters
|
||||||
// between each message, so output could potentially be piped
|
// between each message, so output could potentially be piped
|
||||||
// to another grpcurl process
|
// to another grpcurl process
|
||||||
includeSeparators := !*verbose
|
includeSeparators := verbosityLevel == 0
|
||||||
options := grpcurl.FormatOptions{
|
options := grpcurl.FormatOptions{
|
||||||
EmitJSONDefaultFields: *emitDefaults,
|
EmitJSONDefaultFields: *emitDefaults,
|
||||||
IncludeTextSeparator: includeSeparators,
|
IncludeTextSeparator: includeSeparators,
|
||||||
|
|
@ -661,7 +671,11 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fail(err, "Failed to construct request parser and formatter for %q", *format)
|
fail(err, "Failed to construct request parser and formatter for %q", *format)
|
||||||
}
|
}
|
||||||
h := grpcurl.NewDefaultEventHandler(os.Stdout, descSource, formatter, *verbose)
|
h := &grpcurl.DefaultEventHandler{
|
||||||
|
Out: os.Stdout,
|
||||||
|
Formatter: formatter,
|
||||||
|
VerbosityLevel: verbosityLevel,
|
||||||
|
}
|
||||||
|
|
||||||
err = grpcurl.InvokeRPC(ctx, descSource, cc, symbol, append(addlHeaders, rpcHeaders...), h, rf.Next)
|
err = grpcurl.InvokeRPC(ctx, descSource, cc, symbol, append(addlHeaders, rpcHeaders...), h, rf.Next)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -676,7 +690,7 @@ func main() {
|
||||||
if h.NumResponses != 1 {
|
if h.NumResponses != 1 {
|
||||||
respSuffix = "s"
|
respSuffix = "s"
|
||||||
}
|
}
|
||||||
if *verbose {
|
if verbosityLevel > 0 {
|
||||||
fmt.Printf("Sent %d request%s and received %d response%s\n", reqCount, reqSuffix, h.NumResponses, respSuffix)
|
fmt.Printf("Sent %d request%s and received %d response%s\n", reqCount, reqSuffix, h.NumResponses, respSuffix)
|
||||||
}
|
}
|
||||||
if h.Status.Code() != codes.OK {
|
if h.Status.Code() != codes.OK {
|
||||||
|
|
|
||||||
57
format.go
57
format.go
|
|
@ -409,10 +409,12 @@ func RequestParserAndFormatterFor(format Format, descSource DescriptorSource, em
|
||||||
// safe for use with InvokeRPC as long as NumResponses and Status are not read
|
// safe for use with InvokeRPC as long as NumResponses and Status are not read
|
||||||
// until the call to InvokeRPC completes.
|
// until the call to InvokeRPC completes.
|
||||||
type DefaultEventHandler struct {
|
type DefaultEventHandler struct {
|
||||||
out io.Writer
|
Out io.Writer
|
||||||
descSource DescriptorSource
|
Formatter Formatter
|
||||||
formatter func(proto.Message) (string, error)
|
// 0 = default
|
||||||
verbose bool
|
// 1 = verbose
|
||||||
|
// 2 = very verbose
|
||||||
|
VerbosityLevel int
|
||||||
|
|
||||||
// NumResponses is the number of responses that have been received.
|
// NumResponses is the number of responses that have been received.
|
||||||
NumResponses int
|
NumResponses int
|
||||||
|
|
@ -424,54 +426,65 @@ type DefaultEventHandler struct {
|
||||||
// NewDefaultEventHandler returns an InvocationEventHandler that logs events to
|
// NewDefaultEventHandler returns an InvocationEventHandler that logs events to
|
||||||
// the given output. If verbose is true, all events are logged. Otherwise, only
|
// the given output. If verbose is true, all events are logged. Otherwise, only
|
||||||
// response messages are logged.
|
// response messages are logged.
|
||||||
|
//
|
||||||
|
// Deprecated: NewDefaultEventHandler exists for compatability.
|
||||||
|
// It doesn't allow fine control over the `VerbosityLevel`
|
||||||
|
// and provides only 0 and 1 options (which corresponds to the `verbose` argument).
|
||||||
|
// Use DefaultEventHandler{} initializer directly.
|
||||||
func NewDefaultEventHandler(out io.Writer, descSource DescriptorSource, formatter Formatter, verbose bool) *DefaultEventHandler {
|
func NewDefaultEventHandler(out io.Writer, descSource DescriptorSource, formatter Formatter, verbose bool) *DefaultEventHandler {
|
||||||
|
verbosityLevel := 0
|
||||||
|
if verbose {
|
||||||
|
verbosityLevel = 1
|
||||||
|
}
|
||||||
return &DefaultEventHandler{
|
return &DefaultEventHandler{
|
||||||
out: out,
|
Out: out,
|
||||||
descSource: descSource,
|
Formatter: formatter,
|
||||||
formatter: formatter,
|
VerbosityLevel: verbosityLevel,
|
||||||
verbose: verbose,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ InvocationEventHandler = (*DefaultEventHandler)(nil)
|
var _ InvocationEventHandler = (*DefaultEventHandler)(nil)
|
||||||
|
|
||||||
func (h *DefaultEventHandler) OnResolveMethod(md *desc.MethodDescriptor) {
|
func (h *DefaultEventHandler) OnResolveMethod(md *desc.MethodDescriptor) {
|
||||||
if h.verbose {
|
if h.VerbosityLevel > 0 {
|
||||||
txt, err := GetDescriptorText(md, h.descSource)
|
txt, err := GetDescriptorText(md, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Fprintf(h.out, "\nResolved method descriptor:\n%s\n", txt)
|
fmt.Fprintf(h.Out, "\nResolved method descriptor:\n%s\n", txt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DefaultEventHandler) OnSendHeaders(md metadata.MD) {
|
func (h *DefaultEventHandler) OnSendHeaders(md metadata.MD) {
|
||||||
if h.verbose {
|
if h.VerbosityLevel > 0 {
|
||||||
fmt.Fprintf(h.out, "\nRequest metadata to send:\n%s\n", MetadataToString(md))
|
fmt.Fprintf(h.Out, "\nRequest metadata to send:\n%s\n", MetadataToString(md))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DefaultEventHandler) OnReceiveHeaders(md metadata.MD) {
|
func (h *DefaultEventHandler) OnReceiveHeaders(md metadata.MD) {
|
||||||
if h.verbose {
|
if h.VerbosityLevel > 0 {
|
||||||
fmt.Fprintf(h.out, "\nResponse headers received:\n%s\n", MetadataToString(md))
|
fmt.Fprintf(h.Out, "\nResponse headers received:\n%s\n", MetadataToString(md))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DefaultEventHandler) OnReceiveResponse(resp proto.Message) {
|
func (h *DefaultEventHandler) OnReceiveResponse(resp proto.Message) {
|
||||||
h.NumResponses++
|
h.NumResponses++
|
||||||
if h.verbose {
|
if h.VerbosityLevel > 1 {
|
||||||
fmt.Fprint(h.out, "\nResponse contents:\n")
|
fmt.Fprintf(h.Out, "\nEstimated response size: %d bytes\n", proto.Size(resp))
|
||||||
}
|
}
|
||||||
if respStr, err := h.formatter(resp); err != nil {
|
if h.VerbosityLevel > 0 {
|
||||||
fmt.Fprintf(h.out, "Failed to format response message %d: %v\n", h.NumResponses, err)
|
fmt.Fprint(h.Out, "\nResponse contents:\n")
|
||||||
|
}
|
||||||
|
if respStr, err := h.Formatter(resp); err != nil {
|
||||||
|
fmt.Fprintf(h.Out, "Failed to format response message %d: %v\n", h.NumResponses, err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintln(h.out, respStr)
|
fmt.Fprintln(h.Out, respStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *DefaultEventHandler) OnReceiveTrailers(stat *status.Status, md metadata.MD) {
|
func (h *DefaultEventHandler) OnReceiveTrailers(stat *status.Status, md metadata.MD) {
|
||||||
h.Status = stat
|
h.Status = stat
|
||||||
if h.verbose {
|
if h.VerbosityLevel > 0 {
|
||||||
fmt.Fprintf(h.out, "\nResponse trailers received:\n%s\n", MetadataToString(md))
|
fmt.Fprintf(h.Out, "\nResponse trailers received:\n%s\n", MetadataToString(md))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,12 +120,14 @@ func TestHandler(t *testing.T) {
|
||||||
|
|
||||||
for _, format := range []Format{FormatJSON, FormatText} {
|
for _, format := range []Format{FormatJSON, FormatText} {
|
||||||
for _, numMessages := range []int{1, 3} {
|
for _, numMessages := range []int{1, 3} {
|
||||||
for _, verbose := range []bool{true, false} {
|
for verbosityLevel := 0; verbosityLevel <= 2; verbosityLevel++ {
|
||||||
name := fmt.Sprintf("%s, %d message(s)", format, numMessages)
|
name := fmt.Sprintf("%s, %d message(s)", format, numMessages)
|
||||||
if verbose {
|
if verbosityLevel > 0 {
|
||||||
name += ", verbose"
|
name += fmt.Sprintf(", verbosityLevel=%d", verbosityLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verbose := verbosityLevel > 0
|
||||||
|
|
||||||
_, formatter, err := RequestParserAndFormatter(format, source, nil, FormatOptions{IncludeTextSeparator: !verbose})
|
_, formatter, err := RequestParserAndFormatter(format, source, nil, FormatOptions{IncludeTextSeparator: !verbose})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to create parser and formatter: %v", err)
|
t.Errorf("Failed to create parser and formatter: %v", err)
|
||||||
|
|
@ -133,7 +135,11 @@ func TestHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
h := NewDefaultEventHandler(&buf, source, formatter, verbose)
|
h := &DefaultEventHandler{
|
||||||
|
Out: &buf,
|
||||||
|
Formatter: formatter,
|
||||||
|
VerbosityLevel: verbosityLevel,
|
||||||
|
}
|
||||||
|
|
||||||
h.OnResolveMethod(md)
|
h.OnResolveMethod(md)
|
||||||
h.OnSendHeaders(reqHeaders)
|
h.OnSendHeaders(reqHeaders)
|
||||||
|
|
@ -148,6 +154,9 @@ func TestHandler(t *testing.T) {
|
||||||
expectedOutput += verbosePrefix
|
expectedOutput += verbosePrefix
|
||||||
}
|
}
|
||||||
for i := 0; i < numMessages; i++ {
|
for i := 0; i < numMessages; i++ {
|
||||||
|
if verbosityLevel > 1 {
|
||||||
|
expectedOutput += verboseResponseSize
|
||||||
|
}
|
||||||
if verbose {
|
if verbose {
|
||||||
expectedOutput += verboseResponseHeader
|
expectedOutput += verboseResponseHeader
|
||||||
}
|
}
|
||||||
|
|
@ -226,6 +235,9 @@ Response trailers received:
|
||||||
a: 1
|
a: 1
|
||||||
b: 2
|
b: 2
|
||||||
c: 3
|
c: 3
|
||||||
|
`
|
||||||
|
verboseResponseSize = `
|
||||||
|
Estimated response size: 100 bytes
|
||||||
`
|
`
|
||||||
verboseResponseHeader = `
|
verboseResponseHeader = `
|
||||||
Response contents:
|
Response contents:
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -365,6 +365,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
|
|
@ -444,6 +445,7 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA=
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue