如何在 Go 中使用 httptrace 跟踪 http.Client

根据这个文档,我们可以http.Clienthttptrace这种方式追踪

 t := &transport{}


    req, _ := http.NewRequest("GET", "https://google.com", nil)

    trace := &httptrace.ClientTrace{

        GotConn: t.GotConn,

    }

    req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))


    client := &http.Client{Transport: t}

对于google API 客户端,这里是一个包装代码

func NewWithClient(jsonKey []byte, cli *http.Client) (*Client, error) {

    if cli == nil {

        return nil, fmt.Errorf("client is nil")

    }


    ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cli)


    conf, err := google.JWTConfigFromJSON(jsonKey, androidpublisher.AndroidpublisherScope)

    if err != nil {

        return nil, err

    }


    service, err := androidpublisher.NewService(ctx, option.WithHTTPClient(conf.Client(ctx)))

    if err != nil {

        return nil, err

    }


    return &Client{service}, err

}

我们要应用到做 HTTP 跟踪httptrace的http.Client参数。NewWithClient


我们尝试过的


type TraceTransport struct {

}


var traceTransport = &TraceTransport{}


var trace = &httptrace.ClientTrace{

    GotConn: traceTransport.GotConn,

}


func (t *TraceTransport) RoundTrip(req *http.Request) (*http.Response, error) {

    return http.DefaultTransport.RoundTrip(req)

}


func (t *TraceTransport) GotConn(info httptrace.GotConnInfo) {

    fmt.Printf("Connection reused for %v \n", info.Reused)

}


type ClientWrapper struct {

    defaultClient *http.Client

}


var clientWrapperTrace = &httptrace.ClientTrace{GotConn: traceTransport.GotConn}


func (c *ClientWrapper) Do(req *http.Request) (*http.Response, error) {

    req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientWrapperTrace))

    return c.defaultClient.Do(req)

}


但是,追踪失败http.Client,没有输出GotConn。有人可以帮助我们找出上述代码的问题吗?


http去谷歌API安卓发布者


繁星coding
浏览 195回答 1
1回答

慕慕森

来自的请求无法google/oauth2被 追踪httptrace。您ClientWrapper传递的 withcontext.WithValue将在这里被忽略,并且 oauth2 有它自己的 http.Client,它只是使用from context.Value的Transport方法。*http.Client来自 androidpublisher 的请求可以通过 httptrace 跟踪,如下所示:ctx := httptrace.WithClientTrace(context.Background(), clientWrapperTrace)r, err := c.VerifyProduct(ctx, packageName, productID, token)如果您只想计算请求,我认为覆盖http.Client.Transport是一种简单的方法。type TraceTransport struct {}func (t *TraceTransport) RoundTrip(req *http.Request) (*http.Response, error) {    fmt.Printf("RoundTrip hook %v\n", req.URL)    return http.DefaultTransport.RoundTrip(req)}func NewClientTrace(jsonKey []byte) (*Client, error) {    cli := &http.Client{Transport: &TraceTransport{}}    ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cli)    // ...    service, err := androidpublisher.NewService(ctx, option.WithHTTPClient(conf.Client(ctx)))    // ....}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go