Adicionar traces e métricas personalizados a um app com o OpenTelemetry

Adicionar instrumentação personalizada do OpenTelemetry ao código do aplicativo permite registrar períodos de trace e métricas personalizados que medem o comportamento específico do aplicativo além do que as bibliotecas de framework padrão coletam. É possível aplicar os conceitos deste documento a aplicativos escritos em qualquer linguagem compatível com o OpenTelemetry. Para mais informações, consulte Observabilidade para desenvolvedores de aplicativos e Escolher uma abordagem de instrumentação.

Os exemplos neste documento usam o aplicativo de amostra do Go descrito em Exemplo de instrumentação do Go, que está disponível no GitHub.

Antes de começar

Ative as APIs Cloud Logging, Cloud Monitoring e API Cloud Trace, se ainda não estiverem ativadas.

Funções necessárias para ativar APIs

Para ativar APIs, você precisa da permissão serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de proprietário (roles/owner). Caso contrário, é possível conseguir essa permissão pelo papel de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

Ativar as 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. Para ver o exemplo completo, selecione o logotipo do GitHub na barra de ferramentas do exemplo.

    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, o código a seguir usa 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