簡體   English   中英

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

[英]How to trace http.Client with httptrace in Go

根據此文檔,我們可以通過這種方式使用httptrace跟蹤http.Client

    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}

對於谷歌 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
}

我們想申請httptracehttp.Client的說法NewWithClient做HTTP跟蹤。

我們嘗試過的

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

func NewClientTrace(jsonKey []byte) (*Client, error) {
    cli := &http.Client{
        Transport: traceTransport,
        Timeout:   time.Duration(10) * time.Second,
    }
    cliWrapper := &ClientWrapper{defaultClient: cli}
    ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cliWrapper)

    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
}

type Client struct {
    service *androidpublisher.Service
}

func (c *Client) VerifyProduct(
    ctx context.Context,
    packageName string,
    productID string,
    token string,
) (*androidpublisher.ProductPurchase, error) {
    ps := androidpublisher.NewPurchasesProductsService(c.service)
    result, err := ps.Get(packageName, productID, token).Context(ctx).Do()

    return result, err
}

// test codes
  c, err := NewClientTrace([]byte(privateKey)) 
  if err != nil {
    return
  }

  packageName := "package.name"
  productID := "product_id"
  token := "xxxxx"
  r, err := c.VerifyProduct(context.Background(), packageName, productID, token)

但是,未能追查http.Client ,沒有任何的輸出GotConn 有人可以幫助我們找出上述代碼的問題嗎?

  1. httptrace無法追蹤來自google/oauth2httptrace 您通過context.WithValue傳遞的ClientWrapper將在這里被忽略,而 oauth2 有它自己的 http.Client ,它只是使用來自 context.Value 的*http.ClientTransport方法。

  2. 來自 androidpublisher 的請求可以通過 httptrace 跟蹤,如下所示:

ctx := httptrace.WithClientTrace(context.Background(), clientWrapperTrace)
r, err := c.VerifyProduct(ctx, packageName, productID, token)
  1. 如果您只想計算請求數,我認為覆蓋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)))
    // ....
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM