Adicionar traces e métricas personalizados ao app com o OpenTelemetry

Este documento descreve como adicionar código de observabilidade ao seu aplicativo usando o OpenTelemetry. OpenTelemetry fornece bibliotecas de instrumentação que geram telemetria para estruturas populares. Você pode aumentar a telemetria gerada pela biblioteca adicionando instrumentação personalizada que mede o comportamento específico do seu aplicativo.

Os princípios e conceitos descritos neste documento podem ser aplicados a aplicativos escritos em todas as linguagens suportadas pelo OpenTelemetry. Para saber mais sobre instrumentação, consulte os seguintes documentos:

O exemplo de código, que é o mesmo aplicativo Go descrito em Gerar traces e métricas com o Go está disponível no GitHub. Para ver o exemplo completo, clique em Mais e selecione Ver no GitHub.

Antes de começar

Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs.

Enable the APIs

Criar rastreamentos personalizados

Para gerar traces personalizados do seu aplicativo, adicione código de instrumentação que cria períodos do OpenTelemetry. No OpenTelemetry, os períodos são os blocos de construção dos traces.

Para criar um período, faça o seguinte:

  1. Modifique seu app para adquirir um OpenTelemetry Tracer. No OpenTelemetry, um rastreador é o criador de períodos. Você pode adquirir um rastreador conforme demonstrado no código a seguir:

    const scopeName = "github.com/GoogleCloudPlatform/golang-samples/opentelemetry/instrumentation/app/work"
    
    var (
    	meter                = otel.Meter(scopeName)
    	tracer               = otel.Tracer(scopeName)
    	sleepHistogram       metric.Float64Histogram
    	subRequestsHistogram metric.Int64Histogram
    )
    

    O nome do rastreador, representado por scopeName, identifica o escopo de instrumentação dos traces gerados.

  2. Use a instância tracer para criar períodos. No exemplo de código a seguir, a função computeSubrequests gera um intervalo sempre que é chamada:

    func computeSubrequests(r *http.Request, subRequests int) error {
    	// Add custom span representing the work done for the subrequests
    	ctx, span := tracer.Start(r.Context(), "subrequests")
    	defer span.End()
    
    	// Make specified number of http requests to the /single endpoint.
    	for i := 0; i < subRequests; i++ {
    		if err := callSingle(ctx); err != nil {
    			return err
    		}
    	}
    	// record number of sub-requests made
    	subRequestsHistogram.Record(ctx, int64(subRequests))
    	return nil
    }
    

    No exemplo de código anterior, o período gerado pela função computeSubrequests representa o trabalho realizado por toda a função. Isso ocorre porque a primeira etapa da função é iniciar um novo período usando tracer.Start e a palavra-chave defer antes de span.End() garantir que o período seja encerrado logo antes do encerramento da função.

Criar métricas personalizadas

Para gerar metrics do seu aplicativo, adicione um código de instrumentação que registre as medições feitas durante a execução do seu aplicativo.

Para criar métricas, faça o seguinte:

  1. Modifique seu app para adquirir um OpenTelemetry Meter. No OpenTelemetry, um medidor fornece acesso a instrumentos métricos para registrar métricas. Você pode adquirir um medidor conforme demonstrado no código a seguir:

    const scopeName = "github.com/GoogleCloudPlatform/golang-samples/opentelemetry/instrumentation/app/work"
    
    var (
    	meter                = otel.Meter(scopeName)
    	tracer               = otel.Tracer(scopeName)
    	sleepHistogram       metric.Float64Histogram
    	subRequestsHistogram metric.Int64Histogram
    )
    

    O nome do medidor, representado por scopeName, identifica o escopo de instrumentação das métricas geradas.

  2. Use a instância meter para criar instrumentos que possam registrar métricas. Por exemplo, no código a seguir, usamos meter para criar um histograma OpenTelemetry:

    sleepHistogram, err = meter.Float64Histogram("example.sleep.duration",
    	metric.WithDescription("Sample histogram to measure time spent in sleeping"),
    	metric.WithExplicitBucketBoundaries(0.05, 0.075, 0.1, 0.125, 0.150, 0.2),
    	metric.WithUnit("s"))
    if err != nil {
    	panic(err)
    }

    O código anterior gera um histograma chamado sleepHistogram.

  3. Use a instância sleepHistogram para registrar o tempo de suspensão, que é determinado quando a função randomSleep é invocada:

    func randomSleep(r *http.Request) time.Duration {
    	// simulate the work by sleeping 100 to 200 ms
    	sleepTime := time.Duration(100+rand.Intn(100)) * time.Millisecond
    	time.Sleep(sleepTime)
    
    	hostValue := attribute.String("host.value", r.Host)
    	// custom histogram metric to record time slept in seconds
    	sleepHistogram.Record(r.Context(), sleepTime.Seconds(), metric.WithAttributes(hostValue))
    	return sleepTime
    }
    

    As métricas registradas desses instrumentos são exportadas do seu aplicativo com base na configuração do exportador OpenTelemetry.

A seguir