Adicione rastreios e métricas personalizados à sua app com o OpenTelemetry

Este documento descreve como adicionar código de observabilidade à sua aplicação através do OpenTelemetry. O OpenTelemetry fornece bibliotecas de instrumentação que geram telemetria para frameworks populares. Pode aumentar a telemetria gerada pela biblioteca adicionando instrumentação personalizada que mede o comportamento específico da sua aplicação.

Os princípios e os conceitos descritos neste documento podem ser aplicados a apps escritas em todos os idiomas suportados pelo OpenTelemetry. Para saber mais sobre a instrumentação, consulte os seguintes documentos:

O código de exemplo, que é a mesma app Go descrita no exemplo de instrumentação Go, está disponível no GitHub. Para ver o exemplo completo, clique em Mais e, de seguida, selecione Ver no GitHub.

Antes de começar

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

Roles required to enable APIs

To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

Enable the APIs

Crie rastreios personalizados

Para gerar rastreios personalizados a partir da sua aplicação, adicione código de instrumentação que cria extensões do OpenTelemetry. No OpenTelemetry, os intervalos são os componentes fundamentais dos rastreios.

Para criar um intervalo, faça o seguinte:

  1. Modifique a sua app para adquirir um Tracer do OpenTelemetry. No OpenTelemetry, um rastreador é um criador de intervalos. Pode adquirir um rastreador, conforme demonstrado no seguinte código:

    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 âmbito da instrumentação dos rastreios gerados.

  2. Use a instância tracer para criar intervalos. No exemplo de código seguinte, 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 intervalo gerado a partir da função computeSubrequests representa o trabalho realizado por toda a função. Isto deve-se ao facto de o primeiro passo da função ser iniciar um novo intervalo com tracer.Start e a palavra-chave defer antes de span.End() garantir que o intervalo termina imediatamente antes de a função terminar.

Crie métricas personalizadas

Para gerar métricas a partir da sua aplicação, adicione código de instrumentação que regista as medições feitas durante a execução da app.

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

  1. Modifique a sua app para adquirir um Meter do OpenTelemetry. No OpenTelemetry, um medidor fornece acesso a instrumentos de métricas para registar métricas. Pode adquirir um contador, conforme demonstrado no seguinte código:

    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 contador, representado por scopeName, identifica o âmbito da instrumentação das métricas geradas.

  2. Use a instância meter para criar instrumentos que podem registar métricas. Por exemplo, no código seguinte, usamos o meter para criar um OpenTelemetry Histogram:

    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)
    }

    Este código anterior gera um histograma denominado sleepHistogram.

  3. Use a instância sleepHistogram para registar a hora de dormir, que é determinada 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 registadas destes instrumentos são exportadas da sua aplicação com base na configuração do exportador do OpenTelemetry.

O que se segue?