Utilizzo delle metriche OpenCensus

Questa pagina illustra le nozioni di base della creazione di metriche OpenCensus per gli SLI di disponibilità e latenza. Fornisce inoltre esempi di implementazione di come definire gli SLO utilizzando le metriche di OpenCensus.

Nozioni di base su OpenCensus

OpenCensus è un'unica distribuzione open source di librerie, disponibile nella pagina GitHub di OpenCensus, che raccoglie automaticamente tracce e metriche e le invia a qualsiasi backend. OpenCensus può essere utilizzato per instrumentare i servizi per emettere metriche personalizzate che possono essere importate in Cloud Monitoring. Puoi quindi utilizzare queste metriche come SLI.

Per un esempio in cui viene utilizzato OpenCensus per creare metriche di Monitoring che non sono progettate specificamente come SLI, consulta Metriche personalizzate con OpenCensus.

Metriche

Per raccogliere i dati delle metriche dal servizio mediante OpenCensus, devi utilizzare i seguenti costrutti di OpenCensus:

  • Measure, che rappresenta il tipo di metrica da registrare, specificato con un nome metrica. Un Measure può registrare valori Int64 o Float64.
  • Measurement: registra un punto dati specifico raccolto e scritto da un Measure per un particolare evento. Ad esempio, un Measurement potrebbe registrare la latenza di una risposta specifica.
  • View, che specifica un'aggregazione applicata a un Measure. OpenCensus supporta i seguenti tipi di aggregazione:
    • Conteggio: un conteggio del numero di punti di misurazione.
    • Distribuzione: una distribuzione a istogrammi dei punti di misurazione.
    • Somma: una somma dei valori di misurazione.
    • LastValue: l'ultimo valore registrato dalla misurazione.

Per ulteriori informazioni, consulta Statistiche/metriche di OpenCensus. Tieni presente che OpenCensus spesso fa riferimento alle metriche come statistiche.

Strumentazione

Le librerie OpenCensus sono disponibili per diverse lingue. Per informazioni specifiche per la lingua sulla strumentazione del tuo servizio per l'emissione di metriche, consulta Supporto delle lingue OpenCensus. Inoltre, le metriche personalizzate con OpenCensus forniscono esempi per le lingue comunemente utilizzate con Monitoring.

Nel caso di base, devi procedere come segue:

  • Instrumenta il tuo servizio per registrare ed esportare le metriche.
  • Definisci un esportatore che riceva le metriche.

Per ogni metrica, devi definire un Measure per specificare il tipo di valore: Int64 o Float64. Devi inoltre definire e registrare View per specificare il tipo di aggregazione (conteggio, distribuzione, somma o ultimo valore). Per utilizzare il tipo di aggregazione della distribuzione, devi anche specificare esplicitamente i confini del bucket a istogrammi. Devi specificare anche un nome per la metrica in View.

Esportatore

Infine, devi utilizzare un esportatore per raccogliere le metriche e scriverle in Cloud Monitoring o in un altro backend. Per informazioni sugli esportatori specifici per lingua disponibili per Monitoring, consulta Esportatori di OpenCensus.

Puoi anche scrivere un esportatore personalizzato. Per ulteriori informazioni, consulta Scrivere un esportatore personalizzato.

Creazione di metriche per gli SLI

L'applicazione deve creare metriche OpenCensus che possano essere utilizzate come SLI in Cloud Monitoring:

  • Per gli SLI di disponibilità sui conteggi delle richieste e degli errori, utilizza un elemento Measure con aggregazione del conteggio.
  • Per gli SLI di latenza, utilizza un Measure con aggregazione di distribuzione.

Metriche per gli SLI di disponibilità

Per esprimere uno SLI di disponibilità basato su richiesta nell'API Cloud Monitoring puoi utilizzare la struttura TimeSeriesRatio per configurare un rapporto tra richieste "valide" o "non valide" rispetto alle richieste totali. Questo rapporto viene utilizzato nel campo goodTotalRatio di una struttura RequestBasedSli.

L'applicazione deve creare metriche OpenCensus che possano essere utilizzate per costruire questo rapporto. Nella tua applicazione, devi creare almeno due dei seguenti elementi:

  1. Una metrica che conteggia gli eventi totali; utilizza questa metrica nell'elemento totalServiceFilter del rapporto.

    Puoi creare una metrica OpenCensus di tipo Int64 con aggregazione dei conteggi, in cui registri un valore pari a 1 per ogni richiesta ricevuta.

  2. Una metrica che conteggia gli eventi "non validi", utilizza questa metrica nell'elemento badServiceFilter del rapporto.

    Puoi creare una metrica OpenCensus di tipo Int64 con aggregazione dei conteggi, in cui registri un valore pari a 1 per ogni errore o richiesta non riuscita.

  3. Una metrica che conteggia gli eventi "validi", utilizza questa metrica nell'elemento goodServiceFilter del rapporto.

    Puoi creare una metrica OpenCensus di tipo Int64 con aggregazione dei conteggi, in cui registri un valore pari a 1 per ogni risposta riuscita.

Metriche per gli SLI di latenza

Esprimi uno SLI di latenza basato su richiesta nell'API Cloud Monitoring utilizzando una struttura DistributionCut. Questa struttura viene utilizzata nel campo distributionCut di una struttura RequestBasedSli.

Puoi creare un Measure Int64 o Float64 con un View utilizzando il tipo di aggregazione di distribuzione. Devi inoltre definire esplicitamente i confini dei bucket. Tieni presente che è fondamentale definire i bucket in modo da misurare con precisione la percentuale di richieste che rientrano nella soglia desiderata. Per una discussione su questo argomento, consulta Implementazione degli SLO nella Guida di Site Reliability Engineering.

Esempio di implementazione

Questa sezione presenta un esempio che implementa le metriche per gli SLI di disponibilità di base e di latenza utilizzando OpenCensus in Node.js.

Strumentazione

Per consentire al tuo servizio di emettere metriche utilizzando OpenCensus:

  1. Includi le librerie necessarie:

    Go

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    import (
    	"flag"
    	"fmt"
    	"log"
    	"math/rand"
    	"net/http"
    	"time"
    
    	"contrib.go.opencensus.io/exporter/stackdriver"
    	"go.opencensus.io/stats"
    	"go.opencensus.io/stats/view"
    	"go.opencensus.io/tag"
    )
    

    Node.js

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // opencensus setup
    const {globalStats, MeasureUnit, AggregationType} = require('@opencensus/core');
    const {StackdriverStatsExporter} = require('@opencensus/exporter-stackdriver');

    Python

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    from flask import Flask
    from opencensus.ext.prometheus import stats_exporter as prometheus
    from opencensus.stats import aggregation as aggregation_module
    from opencensus.stats import measure as measure_module
    from opencensus.stats import stats as stats_module
    from opencensus.stats import view as view_module
    from opencensus.tags import tag_map as tag_map_module
    
    from prometheus_flask_exporter import PrometheusMetrics
    
  2. Definisci e registra l'esportatore:

    Go

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // Sets up Cloud Monitoring exporter.
    sd, err := stackdriver.NewExporter(stackdriver.Options{
    	ProjectID:         *projectID,
    	MetricPrefix:      "opencensus-demo",
    	ReportingInterval: 60 * time.Second,
    })
    if err != nil {
    	log.Fatalf("Failed to create the Cloud Monitoring exporter: %v", err)
    }
    defer sd.Flush()
    
    sd.StartMetricsExporter()
    defer sd.StopMetricsExporter()

    Node.js

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // Stackdriver export interval is 60 seconds
    const EXPORT_INTERVAL = 60;
    const exporter = new StackdriverStatsExporter({
      projectId: projectId,
      period: EXPORT_INTERVAL * 1000,
    });
    globalStats.registerExporter(exporter);

    Python

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    def setup_openCensus_and_prometheus_exporter() -> None:
        stats = stats_module.stats
        view_manager = stats.view_manager
        exporter = prometheus.new_stats_exporter(prometheus.Options(namespace="oc_python"))
        view_manager.register_exporter(exporter)
        register_all_views(view_manager)
  3. Definisci un valore Measure per ogni metrica:

    Go

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // Sets up metrics.
    var (
    	requestCount       = stats.Int64("oc_request_count", "total request count", "requests")
    	failedRequestCount = stats.Int64("oc_failed_request_count", "count of failed requests", "requests")
    	responseLatency    = stats.Float64("oc_latency_distribution", "distribution of response latencies", "s")
    )
    

    Node.js

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    const REQUEST_COUNT = globalStats.createMeasureInt64(
      'request_count',
      MeasureUnit.UNIT,
      'Number of requests to the server'
    );
    const ERROR_COUNT = globalStats.createMeasureInt64(
      'error_count',
      MeasureUnit.UNIT,
      'Number of failed requests to the server'
    );
    const RESPONSE_LATENCY = globalStats.createMeasureInt64(
      'response_latency',
      MeasureUnit.MS,
      'The server response latency in milliseconds'
    );

    Python

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    m_request_count = measure_module.MeasureInt(
        "python_request_count", "total requests", "requests"
    )
    m_failed_request_count = measure_module.MeasureInt(
        "python_failed_request_count", "failed requests", "requests"
    )
    m_response_latency = measure_module.MeasureFloat(
        "python_response_latency", "response latency", "s"
    )
  4. Definisci e registra il View per ogni Measure con il tipo di aggregazione appropriato e, per la latenza di risposta, i limiti dei bucket:

    Go

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // Sets up views.
    var (
    	requestCountView = &view.View{
    		Name:        "oc_request_count",
    		Measure:     requestCount,
    		Description: "total request count",
    		Aggregation: view.Count(),
    	}
    	failedRequestCountView = &view.View{
    		Name:        "oc_failed_request_count",
    		Measure:     failedRequestCount,
    		Description: "count of failed requests",
    		Aggregation: view.Count(),
    	}
    	responseLatencyView = &view.View{
    		Name:        "oc_response_latency",
    		Measure:     responseLatency,
    		Description: "The distribution of the latencies",
    		// Bucket definitions must be explicitly specified.
    		Aggregation: view.Distribution(0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000),
    	}
    )
    
    	// Register the views.
    	if err := view.Register(requestCountView, failedRequestCountView, responseLatencyView); err != nil {
    		log.Fatalf("Failed to register the views: %v", err)
    	}

    Node.js

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    const request_count_metric = globalStats.createView(
      'request_count_metric',
      REQUEST_COUNT,
      AggregationType.COUNT
    );
    globalStats.registerView(request_count_metric);
    const error_count_metric = globalStats.createView(
      'error_count_metric',
      ERROR_COUNT,
      AggregationType.COUNT
    );
    globalStats.registerView(error_count_metric);
    const latency_metric = globalStats.createView(
      'response_latency_metric',
      RESPONSE_LATENCY,
      AggregationType.DISTRIBUTION,
      [],
      'Server response latency distribution',
      // Latency in buckets:
      [0, 1000, 2000, 3000, 4000, 5000, 10000]
    );
    globalStats.registerView(latency_metric);

    Python

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    # set up views
    latency_view = view_module.View(
        "python_response_latency",
        "The distribution of the latencies",
        [],
        m_response_latency,
        aggregation_module.DistributionAggregation(
            [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000]
        ),
    )
    
    request_count_view = view_module.View(
        "python_request_count",
        "total requests",
        [],
        m_request_count,
        aggregation_module.CountAggregation(),
    )
    
    failed_request_count_view = view_module.View(
        "python_failed_request_count",
        "failed requests",
        [],
        m_failed_request_count,
        aggregation_module.CountAggregation(),
    )
    
    # register views
    def register_all_views(view_manager: stats_module.stats.view_manager) -> None:
        view_manager.register_view(latency_view)
        view_manager.register_view(request_count_view)
        view_manager.register_view(failed_request_count_view)
  5. Registra i valori per le metriche di numero di richieste ed errori:

    Go

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // Counts the request.
    stats.Record(ctx, requestCount.M(1))
    
    // Randomly fails 10% of the time.
    if rand.Intn(100) >= 90 {
    	// Counts the error.
    	stats.Record(ctx, failedRequestCount.M(1))

    Node.js

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    // record a request count for every request
    globalStats.record([
      {
        measure: REQUEST_COUNT,
        value: 1,
      },
    ]);
    
    // randomly throw an error 10% of the time
    const randomValue = Math.floor(Math.random() * 9 + 1);
    if (randomValue === 1) {
      // Record a failed request.
      globalStats.record([
        {
          measure: ERROR_COUNT,
          value: 1,
        },
      ]);

    Python

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    mmap = stats_recorder.new_measurement_map()
    # count request
    mmap.measure_int_put(m_request_count, 1)
    # fail 10% of the time
    if random.randint(0, 100) > 90:
        mmap.measure_int_put(m_failed_request_count, 1)
        tmap = tag_map_module.TagMap()
        mmap.record(tmap)
        return ("error!", 500)
  6. Registra i valori di latenza:

    Go

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    requestReceived := time.Now()
    // Records latency for failure OR success.
    defer func() {
    	stats.Record(ctx, responseLatency.M(time.Since(requestReceived).Seconds()))
    }()

    Node.js

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    globalStats.record([
      {
        measure: RESPONSE_LATENCY,
        value: stopwatch.elapsedMilliseconds,
      },
    ]);

    Python

    Per eseguire l'autenticazione a Monitoring, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.

    start_time = time.perf_counter()
    mmap = stats_recorder.new_measurement_map()
    if random.randint(0, 100) > 90:
        response_latency = time.perf_counter() - start_time
        mmap.measure_float_put(m_response_latency, response_latency)
        tmap = tag_map_module.TagMap()
        mmap.record(tmap)

Metriche importate

Quando le metriche vengono esportate in Cloud Monitoring, vengono visualizzate come tipi di metriche con un prefisso che ne indica che hanno avuto origine da OpenCensus. Ad esempio, il nome di ogni View di OpenCensus nell'implementazione Node.js è mappato come segue:

  • request_count_sli diventa custom.googleapis.com/opencensus/request_count_sli.
  • error_count_sli diventa custom.googleapis.com/opencensus/error_count_sli.
  • response_latency_sli diventa custom.googleapis.com/opencensus/response_latency_sli.

Quando il servizio è in esecuzione, puoi confermare che le metriche vengono importate in Monitoring cercandole in Metrics Explorer.

SLI di disponibilità

In Cloud Monitoring, puoi esprimere uno SLI di disponibilità basato su richiesta utilizzando una struttura TimeSeriesRatio. L'esempio seguente mostra uno SLO che utilizza le metriche OpenCensus importate e prevede che il servizio abbia una disponibilità del 98%, come calcolato da un rapporto compreso tra error_count_sli e request_count_sli, in una finestra temporale continua di 28 giorni:

{
  "serviceLevelIndicator": {
    "requestBased": {
      "goodTotalRatio": {
        "totalServiceFilter":
          "metric.type=\"custom.googleapis.com/opencensus/request_count_sli\",
       "badServiceFilter":
          "metric.type=\"custom.googleapis.com/opencensus/error_count_sli\"
      }
    }
  },
  "goal": 0.98,
  "rollingPeriod": "2419200s",
  "displayName": "98% Availability, rolling 28 days"
}

SLI di latenza

In Cloud Monitoring, esprimi uno SLI di latenza basato su richiesta utilizzando una struttura DistributionCut. L'esempio seguente mostra uno SLO che utilizza la metrica di latenza OpenCensus importata e si aspetta che il 98% delle richieste venga completato in meno di 1000 ms in una finestra temporale continuativa di un giorno:

{
  "serviceLevelIndicator": {
    "requestBased": {
      "distributionCut": {
        "distributionFilter":
          "metric.type=\"custom.googleapis.com/opencensus/response_latency_sli\",
        "range": {
          "min": 0,
          "max": 1000
        }
      }
    }
  },
  "goal": 0.98,
  "rollingPeriod": "86400s",
  "displayName": "98% requests under 1000 ms"
}