mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
cli: add --debug-http flag (#7192)
This makes it easier to help debug client issues.
This commit is contained in:
+13
@@ -364,6 +364,13 @@ func (r *RootCmd) Command(subcommands []*clibase.Cmd) (*clibase.Cmd, error) {
|
||||
Value: clibase.BoolOf(&r.verbose),
|
||||
Group: globalGroup,
|
||||
},
|
||||
{
|
||||
Flag: "debug-http",
|
||||
Description: "Debug codersdk HTTP requests.",
|
||||
Value: clibase.BoolOf(&r.debugHTTP),
|
||||
Group: globalGroup,
|
||||
Hidden: true,
|
||||
},
|
||||
{
|
||||
Flag: config.FlagName,
|
||||
Env: "CODER_CONFIG_DIR",
|
||||
@@ -412,6 +419,7 @@ type RootCmd struct {
|
||||
forceTTY bool
|
||||
noOpen bool
|
||||
verbose bool
|
||||
debugHTTP bool
|
||||
|
||||
noVersionCheck bool
|
||||
noFeatureWarning bool
|
||||
@@ -464,6 +472,11 @@ func (r *RootCmd) InitClient(client *codersdk.Client) clibase.MiddlewareFunc {
|
||||
|
||||
client.SetSessionToken(r.token)
|
||||
|
||||
if r.debugHTTP {
|
||||
client.PlainLogger = os.Stderr
|
||||
client.LogBodies = true
|
||||
}
|
||||
|
||||
// We send these requests in parallel to minimize latency.
|
||||
var (
|
||||
versionErr = make(chan error)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"mime"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -90,6 +91,10 @@ type Client struct {
|
||||
// LogBodies can be enabled to print request and response bodies to the logger.
|
||||
LogBodies bool
|
||||
|
||||
// PlainLogger may be set to log HTTP traffic in a human-readable form.
|
||||
// It uses the LogBodies option.
|
||||
PlainLogger io.Writer
|
||||
|
||||
// Trace can be enabled to propagate tracing spans to the Coder API.
|
||||
// This is useful for tracking a request end-to-end.
|
||||
Trace bool
|
||||
@@ -109,6 +114,16 @@ func (c *Client) SetSessionToken(token string) {
|
||||
c.sessionToken = token
|
||||
}
|
||||
|
||||
func prefixLines(prefix, s []byte) []byte {
|
||||
ss := bytes.NewBuffer(make([]byte, 0, len(s)*2))
|
||||
for _, line := range bytes.Split(s, []byte("\n")) {
|
||||
_, _ = ss.Write(prefix)
|
||||
_, _ = ss.Write(line)
|
||||
_ = ss.WriteByte('\n')
|
||||
}
|
||||
return ss.Bytes()
|
||||
}
|
||||
|
||||
// Request performs a HTTP request with the body provided. The caller is
|
||||
// responsible for closing the response body.
|
||||
func (c *Client) Request(ctx context.Context, method, path string, body interface{}, opts ...RequestOption) (*http.Response, error) {
|
||||
@@ -155,6 +170,15 @@ func (c *Client) Request(ctx context.Context, method, path string, body interfac
|
||||
return nil, xerrors.Errorf("create request: %w", err)
|
||||
}
|
||||
|
||||
if c.PlainLogger != nil {
|
||||
out, err := httputil.DumpRequest(req, c.LogBodies)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("dump request: %w", err)
|
||||
}
|
||||
out = prefixLines([]byte("http --> "), out)
|
||||
_, _ = c.PlainLogger.Write(out)
|
||||
}
|
||||
|
||||
tokenHeader := c.SessionTokenHeader
|
||||
if tokenHeader == "" {
|
||||
tokenHeader = SessionTokenHeader
|
||||
@@ -192,6 +216,15 @@ func (c *Client) Request(ctx context.Context, method, path string, body interfac
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.PlainLogger != nil {
|
||||
out, err := httputil.DumpResponse(resp, c.LogBodies)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("dump response: %w", err)
|
||||
}
|
||||
out = prefixLines([]byte("http <-- "), out)
|
||||
_, _ = c.PlainLogger.Write(out)
|
||||
}
|
||||
|
||||
span.SetAttributes(httpconv.ClientResponse(resp)...)
|
||||
span.SetStatus(httpconv.ClientStatus(resp.StatusCode))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user