Artigo de Dave Burke, publicado originalmente pelo Android Security Team. A tradução foi feita pela Redação iMasters com autorização.
Introdução
Na Go 1.7, introduzimos o rastreamento HTTP, uma facilidade para reunir informações finas ao longo do ciclo de vida de uma solicitação de cliente HTTP. O suporte para o rastreamento HTTP é fornecido pelo pacote net/http/httptrace. As informações coletadas podem ser usadas para depurar problemas de latência, monitoramento de serviços, sistemas de adaptação de escrita, e muito mais.
Eventos HTTP
O pacote httptrace fornece um número de hooks para coletar informações durante uma viagem de ida e volta HTTP sobre uma variedade de eventos. Esses eventos incluem:
- Criação de conexão
- Reutilização da conexão
- Pesquisas DNS
- Escrevendo o pedido para o fio
- Lendo a resposta
Rastreamento de eventos
Você pode habilitar o rastreamento HTTP colocando um *httptrace.ClientTrace contendo funções de hook no context.Context de uma solicitação. Várias implementações http.RoundTripper relatam os eventos internos procurando pelo *httptrace.ClientTrace do contexto e chamando as funções de hook relevantes.
O rastreio tem um escopo para o contexto do pedido, e os usuários devem colocar um *httptrace.ClientTrace no contexto do pedido antes de iniciarem uma solicitação.
req, _ := http.NewRequest("GET", "http://example.com", nil) trace := &httptrace.ClientTrace{ DNSDone: func(dnsInfo httptrace.DNSDoneInfo) { fmt.Printf("DNS Info: %+v\n", dnsInfo) }, GotConn: func(connInfo httptrace.GotConnInfo) { fmt.Printf("Got Conn: %+v\n", connInfo) }, } req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) if _, err := http.DefaultTransport.RoundTrip(req); err != nil { log.Fatal(err) }
Durante uma viagem de ida e volta, http.DefaultTransport invocará cada hook enquanto um evento acontece. O programa acima irá imprimir as informações de DNS assim que a pesquisa de DNS estiver concluída. Ele também imprimirá informações de conexão quando uma conexão for estabelecida para o host da solicitação.
Rastreio com http.Client
O mecanismo de rastreamento é projetado para rastrear os eventos no ciclo de vida de um único http.Transport.RoundTrip. No entanto, um cliente pode fazer várias viagens de ida e volta para concluir uma solicitação HTTP. Por exemplo, no caso de um redirecionamento de URL, os hooks registrados serão chamados quantas vezes o cliente seguir os redirecionamentos HTTP, fazendo várias solicitações. Os usuários são responsáveis por reconhecer tais eventos no nível http.Client. O programa abaixo identifica a solicitação atual usando um wrapper http.RoundTripper.
package main import ( "fmt" "log" "net/http" "net/http/httptrace" ) // transport is an http.RoundTripper that keeps track of the in-flight // request and implements hooks to report HTTP tracing events. type transport struct { current *http.Request } // RoundTrip wraps http.DefaultTransport.RoundTrip to keep track // of the current request. func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { t.current = req return http.DefaultTransport.RoundTrip(req) } // GotConn prints whether the connection has been used previously // for the current request. func (t *transport) GotConn(info httptrace.GotConnInfo) { fmt.Printf("Connection reused for %v? %v\n", t.current.URL, info.Reused) } func main() { 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} if _, err := client.Do(req); err != nil { log.Fatal(err) } }
O programa seguirá o redirecionamento de google.com para www.google.com e exibirá:
Connection reused for https://google.com? false Connection reused for https://www.google.com/? false
O Transport no pacote net/http suporta rastreamento de solicitações HTTP/1 e HTTP/2.
Se você é um autor de uma implementação personalizada http.RoundTripper, pode oferecer suporte para o rastreamento verificando o contexto de solicitação de um *httptest.ClientTrace e invocando os hooks relevantes à medida que os eventos ocorrem.
Conclusão
O rastreamento HTTP é uma adição valiosa para a linguagem Go para aqueles que estão interessados em depurar a latência de solicitação HTTP e em ferramentas de escrita para depuração de rede para tráfego de saída. Ao ativar essa nova facilidade, esperamos ver ferramentas de depuração, de benchmarking e de visualização de HTTP a partir da comunidade – como a httpstat.
***
Este artigo é do The Go Blog. Ele foi escrito por Jaana Burcu Dogan. A tradução foi feita pela Redação iMasters com autorização. Você pode acessar o original em: https://blog.golang.org/http-tracing.