impr(verbose): using package httpretty to log requests on DEBUG.#306
Conversation
|
Thanks, it's intriguing! Can you talk about why enabling |
|
Hi @vilmibm, I think I created confusion by sending both commits on the same pull-request. They were to be intended to be on separate pull-requests. The concurrency concerns on httpretty involve mostly two things:
It's a good practice to always add One important thing to realize is that the data race detector isn't deterministic, so one thing I usually do when I work on something that is more risky is to run this command I have as a alias to #!/bin/bash
set -euo pipefail
IFS=$'\n\t'
ARGS=${1:-""}
counter=0
while true
do
counter=$((counter+1))
go test $(go list ./... | grep -v /vendor/) -count=1 $ARGS # count=1 is a bypass to test caching
if [ $counter -eq 1 ] ; then
echo "$counter time"
else
echo "$counter times"
fi
doneand to quickly run the binary with data race condition in a straight-forward way, I have an alias to something else, like a single-letter #!/bin/bash
set -euo pipefail
IFS=$'\n\t'
cd $GOPATH/src/github.com/cli/cli/cmd/gh
go install -race
cd ~- # cd without printingThanks to this I can just save a file and immediately run a command. Say, instead of PS: There is a currently data race condition affecting everyone using net/http in Go doing concurrent requests, but it shouldn't be cause for concern for this pull-request because it's already affecting everyone: net/http: data race when response is returned before the full request's body is written #30597 |
There was a problem hiding this comment.
I was aware of the race detector and its importance; I was just confused as to whether or not your commit adding it was related to using httpretty.
I definitely like the httpretty output! If you could split out the -race commit into another PR and then restore parity with inspectableMIMEType I'd be happy to merge 👍
There was a problem hiding this comment.
Hi, this looks great! Some feedback:
- Blocking: TLS info (somewhat noisy) is printed even with
TLS: false - Blocking: please remove the changes to our test runner
- Minor: not all request headers seem printed with
RequestHeader: true - Nice-to-have: a way to avoid certain request/response headers being printed; perhaps accept a func that takes a header name and returns a boolean that indicates whether to print or not?
Thank you for this tool!
de0b013 to
e7c88d0
Compare
|
Hi, @vilmibm, I have restored parity with inspectableMIMEType by adding a body filter. @mislav, thanks for letting me know about the issue on the TLS param. I just noticed after your comment. Fixed it. Regarding some headers not being printed it's because the VerboseLog middleware is added after, say, Authorization, User-Agent, Accept, and other headers (that are being added in a middleware manner right now). I see two options: we can move it to the front or leave as is. If we move it to the front, these headers will be added (Authorization would be sanitized, though). Besides all this, the Go standard library might add headers (such as the User-Agent, if you don't set one), and httpretty currently doesn't have a mode to display it (but I intend to have). I'll also open an issue to remember about doing a function to easily control unwanted headers. Something else that might be a good idea: color support. Right now, the util/color doesn't expose a way I can check to set the Colors field, and this would be neat. |
- log headers only in DEBUG=api mode - enable color output on stderr - hide little-useful TLS debbuging info - ensure all request headers are logged
There was a problem hiding this comment.
Thank you! I've moved middleware around and added color support.
One more small feature request for the future: we'd like to define our own formatter for GraphQL requests (basically, make a more specialized JSON formatter for GraphQL), but the current interface for a Formatter allows only matching per mime type, which for GraphQL requests is always application/json. Since the formatter doesn't have access to other information about a request, such as request path, we cannot distinguish GraphQL requests from other JSON requests.
|
Thanks, @mislav. I'm trying to think about what other signature Match could have (and more importantly, what could go inside). Or maybe Match could be gone and a special error value used to indicate matching errors and skip to the next formatter. Would something like this be an okay-ish tradeoff for now? // GraphQLFormatter helps you read unreadable GraphQL queries,
// with fallback to regular JSON documents.
type GraphQLFormatter struct {
j httpretty.JSONFormatter
}
// Match JSON media type.
func (g *GraphQLFormatter) Match(mediatype string) bool {
return g.j.Match(mediatype)
}
// Format GraphQL query, falling back to JSON if GraphQL is not identified.
func (g *GraphQLFormatter) Format(dst *bytes.Buffer, src []byte) (err error) {
if e := g.j.Format(dst, src); e != nil {
return e
}
src = dst.Bytes() // dst here isn't empty and holds JSON formatted output
if isGraphQL(src) {
return nil
}
defer func() {
if err != nil {
dst.Reset()
// clear returned error to get JSON pretty-printed, but print error feedback:
fmt.Fprintf(dst, "* cannot format GraphQL: %v\n", err)
dst.Write(src)
err = nil
}
}()
dst.Reset()
return formatGraphQL(dst, src)
}
|
|
Ideally, I wanted to detect GraphQL requests based on their request URI, not the JSON contents. But it's possible to detect them using JSON contents; a GraphQL payload usually has only Another thing that surprised me: that |
Hi, a few days ago I released this package called httpretty that I think would be useful for debugging the GitHub CLI instead of the burden of dealing with it directly.
What do you think about it? If you like the idea, I probably need to add support for skipping content so that the inspectableMIMEType can still be used.
btw, I was the main maintainer of NodeGH for a while (written using NodeJS years ago) but I've since moved to Go (and spent a quite a while working with Go + cobra + git for deployments), and I'm really excited seeing this CLI written in Go o/ :)
Feel free to ask anything!