Desenvolvimento

22 fev, 2017

Introdução ao rastreamento HTTP

Publicidade

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.