You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言如何为Google API客户端的http.Client添加httptrace追踪

问题根因

1. 自定义的ClientWrapper.Do方法完全未执行

你将cliWrapper注入到context的oauth2.HTTPClient键中,但google.JWTConfigFromJSON返回的配置调用Client(ctx)时,只会提取传入client的Transport作为oauth2传输层的底层实现,不会复用整个client的Do方法逻辑。你用来给请求上下文注入httptrace的代码根本没有运行,自然不会触发GotConn回调。

2. trace注入逻辑位置错误

不需要额外封装ClientWrapper,只要把注入trace的逻辑移到自定义TraceTransport的RoundTrip方法里,所有经过该传输层的请求都会被自动注入trace,不会被上层的oauth2封装逻辑跳过。

3. 全局实例存在并发风险

你用全局变量定义traceTransport、clientWrapperTrace,如果有并发请求会出现trace回调互相干扰的问题。


修复后的代码示例

type TraceTransport struct {
	Base http.RoundTripper
}

func (t *TraceTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	// 直接在RoundTrip中给当前请求注入独立的trace
	trace := &httptrace.ClientTrace{
		GotConn: t.GotConn,
	}
	req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
	// 没有指定底层传输层就用默认实现
	base := t.Base
	if base == nil {
		base = http.DefaultTransport
	}
	return base.RoundTrip(req)
}

func (t *TraceTransport) GotConn(info httptrace.GotConnInfo) {
	fmt.Printf("Connection reused for %v \n", info.Reused)
}

func NewClientTrace(jsonKey []byte) (*Client, error) {
	// 先构造oauth2配置
	conf, err := google.JWTConfigFromJSON(jsonKey, androidpublisher.AndroidpublisherScope)
	if err != nil {
		return nil, err
	}
	// 构造带trace的传输层,底层用oauth2的token传输层处理鉴权
	traceTransport := &TraceTransport{
		Base: &oauth2.Transport{
			Source: conf.TokenSource(context.Background()),
		},
	}
	// 构造最终使用的http client
	cli := &http.Client{
		Transport: traceTransport,
		Timeout:   10 * time.Second,
	}
	// 直接把带trace的client传给google service
	service, err := androidpublisher.NewService(context.Background(), option.WithHTTPClient(cli))
	if err != nil {
		return nil, err
	}
	return &Client{service}, err
}

内容的提问来源于stack exchange,提问作者zangw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:06:03