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
相关产品推荐
相关产品推荐

