Query MQL di esempio

Questo documento introduce il linguaggio di query Monitoring (MQL) attraverso alcuni esempi. Tuttavia, non si tenta di coprire tutti gli aspetti del linguaggio. MQL è documentato in modo esaustivo nella sezione Riferimento a Monitoring Query Language.

Per informazioni sui criteri di avviso basati su MQL, consulta Criteri di avviso con MQL.

Puoi scrivere una determinata query in molti modi; il linguaggio è flessibile e, una volta acquisita familiarità con la sintassi, puoi utilizzare molte scorciatoie. Per ulteriori informazioni, consulta Query in formato restrittivo.

Prima di iniziare

Per accedere all'editor di codice quando utilizzi Metrics Explorer:

  1. Nel pannello di navigazione della console Google Cloud, seleziona Monitoring e poi  Metrics Explorer:

    Vai a Metrics Explorer

  2. Nella barra degli strumenti del riquadro del generatore di query, seleziona il pulsante il cui nome è  MQL o  PromQL.
  3. Verifica che sia selezionato MQL nel pulsante di attivazione/disattivazione Lingua. Il pulsante di attivazione/disattivazione della lingua si trova nella stessa barra degli strumenti che consente di formattare la query.

Per eseguire una query, incollala nell'editor e fai clic su Esegui query. Per un'introduzione a questo editor, consulta Utilizzare l'editor di codice per MQL.

È utile avere familiarità con i concetti di Cloud Monitoring, tra cui i tipi di metriche, i tipi di risorse monitorate e le serie temporali. Per un'introduzione a questi concetti, consulta Metriche, serie temporali e risorse.

Modello dati

Le query MQL recuperano e manipolano i dati nel database delle serie temporali di Cloud Monitoring. Questa sezione introduce alcuni concetti e terminologia relativi al database. Per informazioni dettagliate, consulta l'argomento di riferimento Modello dei dati.

Ogni serie temporale ha origine da un singolo tipo di risorsa monitorata e ogni serie temporale raccoglie dati di un solo tipo di metrica. Un descrittore di risorsa monitorata definisce un tipo di risorsa monitorata. Analogamente, un descrittore della metrica definisce un tipo di metrica. Ad esempio, il tipo di risorsa potrebbe essere gce_instance, una macchina virtuale (VM) Compute Engine, e il tipo di metrica potrebbe essere compute.googleapis.com/instance/cpu/utilization, l'utilizzo della CPU della VM di Compute Engine.

Questi descrittori specificano inoltre un insieme di etichette utilizzate per raccogliere informazioni su altri attributi della metrica o del tipo di risorsa. Ad esempio, le risorse in genere hanno un'etichetta zone, utilizzata per registrare la posizione geografica della risorsa.

Viene creata una serie temporale per ogni combinazione di valori per le etichette dalla coppia di un descrittore della metrica e di un descrittore di risorsa monitorata.

Puoi trovare le etichette disponibili per i tipi di risorse nell'elenco delle risorse monitorate, ad esempio gce_instance. Per trovare le etichette dei tipi di metrica, consulta l'elenco delle metriche; ad esempio, vedi le metriche di Compute Engine.

Il database Cloud Monitoring archivia le serie temporali di una determinata metrica e di un determinato tipo di risorsa in un'unica tabella. La metrica e il tipo di risorsa fungono da identificatore della tabella. Questa query MQL recupera la tabella delle serie temporali che registra l'utilizzo della CPU per le istanze di Compute Engine:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization

Nella tabella è presente una serie temporale per ogni combinazione univoca di valori di metrica ed etichetta delle risorse.

Le query MQL recuperano i dati delle serie temporali da queste tabelle e li trasformano in tabelle di output. Queste tabelle di output possono essere passate ad altre operazioni. Ad esempio, puoi isolare le serie temporali scritte dalle risorse in una determinata zona o in un determinato insieme di zone passando la tabella recuperata come input a un'operazione filter:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter zone =~ 'us-central.*'

La query precedente genera come risultato una tabella contenente solo le serie temporali delle risorse in una zona che inizia con us-central.

Le query MQL sono strutturate in modo da passare l'output di un'operazione come input all'operazione successiva. Questo approccio basato su tabelle ti consente di collegare le operazioni per manipolare questi dati filtrando, selezionare e altre operazioni di database conosciute come i join interni ed esterni. Puoi anche eseguire varie funzioni sui dati delle serie temporali mentre i dati vengono passati da un'operazione all'altra.

Le operazioni e le funzioni disponibili in MQL sono completamente documentate nella documentazione di riferimento di Monitoring Query Language.

Struttura della query

Una query è composta da una o più operations. Le operazioni sono collegate, o concatenate, in modo che l'output di un'operazione sia l'input della successiva. Pertanto, il risultato di una query dipende dall'ordine delle operazioni. Ecco alcune delle cose che puoi fare:

  • Avvia una query con un'operazione fetch o un'altra selezione.
  • Crea una query con più operazioni collegate tra loro.
  • Seleziona un sottoinsieme di informazioni con le operazioni filter.
  • Aggrega le informazioni correlate con le operazioni di group_by.
  • Esamina i valori anomali con le operazioni top e bottom.
  • Combina più query con le operazioni { ; } e join.
  • Usa l'operazione e le funzioni value per calcolare rapporti e altri valori.

Non tutte le query utilizzano tutte queste opzioni.

Questi esempi introducono solo alcune delle operazioni e delle funzioni disponibili. Per informazioni dettagliate sulla struttura delle query MQL, consulta l'argomento di riferimento Struttura delle query.

Questi esempi non specificano due cose che potresti aspettarti di vedere: intervalli di tempo e allineamento. Il motivo è spiegato nelle sezioni seguenti.

Intervalli di tempo

Quando utilizzi l'editor di codice, le impostazioni del grafico definiscono l'intervallo di tempo per le query. Per impostazione predefinita, l'intervallo di tempo del grafico è impostato su un'ora.

Per modificare l'intervallo di tempo del grafico, utilizza il selettore dell'intervallo di tempo. Ad esempio, per visualizzare i dati della settimana precedente, seleziona Ultima settimana dal selettore dell'intervallo di tempo. Puoi anche specificare un'ora di inizio e di fine o un orario di visualizzazione.

Per ulteriori informazioni sugli intervalli di tempo nell'editor di codice, consulta Intervalli di tempo, grafici e editor di codice.

Allineamento

Molte delle operazioni utilizzate in questi esempi, come le operazioni join e group_by, dipendono da tutti i punti delle serie temporali in una tabella che si verificano a intervalli regolari. L'allineamento di tutti i punti con timestamp regolari si chiama alignment. Di solito, l'allineamento avviene in modo implicito e nessuno degli esempi qui lo mostra.

MQL allinea automaticamente le tabelle per le operazioni join e group_by quando necessario, ma MQL consente anche di eseguire l'allineamento in modo esplicito.

Recupera e filtra dati

Le query MQL iniziano con il recupero, la selezione o l'applicazione di filtri ai dati. Questa sezione illustra alcune operazioni di recupero e filtri di base con MQL.

Recupera i dati delle serie temporali

Una query viene sempre avviata con un'operazione fetch, che recupera le serie temporali da Cloud Monitoring.

La query più semplice consiste in una singola operazione fetch e un argomento che identifica la serie temporale da recuperare, come segue:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization

L'argomento è composto da un tipo di risorsa monitorata, gce_instance, una coppia di caratteri dei due punti :: e un tipo di metrica compute.googleapis.com/instance/cpu/utilization.

Questa query recupera la serie temporale scritta dalle istanze di Compute Engine per il tipo di metrica compute.googleapis.com/instance/cpu/utilization, che registra l'utilizzo della CPU da parte delle istanze.

Se esegui la query dall'editor di codice in Metrics Explorer, ottieni un grafico che mostra ciascuna delle serie temporali richieste:

Il grafico mostra i dati sull'utilizzo della CPU per le istanze di Compute Engine.

Ogni serie temporale richiesta viene visualizzata come linea nel grafico. Ogni serie temporale include un elenco di valori con timestamp della metrica di utilizzo della CPU per un'istanza VM in questo progetto.

Nello spazio di archiviazione backend utilizzato da Cloud Monitoring, le serie temporali sono archiviate in tabelle. L'operazione fetch organizza le serie temporali per i tipi di risorsa monitorata e metrica specificati in una tabella, quindi restituisce la tabella. I dati restituiti vengono visualizzati nel grafico.

L'operazione fetch è descritta, insieme ai relativi argomenti, nella pagina di riferimento di fetch. Per ulteriori informazioni sui dati generati dalle operazioni, consulta le pagine di riferimento per serie temporali e tabelle.

Filtra operazioni

In genere le query sono composte da una combinazione di più operazioni. La combinazione più semplice consiste nel collegare l'output di un'operazione all'input dell'altra utilizzando l'operatore |. L'esempio seguente illustra l'utilizzo di una barra verticale per inserire la tabella in un'operazione di filtro:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter instance_name =~ 'gke.*'

Questa query indirizza la tabella, restituita dall'operazione fetch mostrata nell'esempio precedente, in un'operazione filter che prende come espressione che restituisce un valore booleano. In questo esempio, l'espressione significa "instance_name inizia con gke".

L'operazione filter prende la tabella di input, rimuove le serie temporali per cui il filtro è falso e restituisce la tabella risultante. Il seguente screenshot mostra il grafico risultante:

Il grafico mostra i risultati filtrati per "gke".

Se non hai nomi di istanza che iniziano con gke, modifica il filtro prima di provare questa query. Ad esempio, se disponi di istanze VM con apache all'inizio del nome, utilizza il seguente filtro:

 | filter instance_name =~ 'apache.*'

L'espressione filter viene valutata una volta per ogni serie temporale di input. Se l'espressione restituisce true, quella serie temporale viene inclusa nell'output. In questo esempio, l'espressione di filtro trova una corrispondenza di espressione regolare, =~, sull'etichetta instance_name di ogni serie temporale. Se il valore dell'etichetta corrisponde all'espressione regolare 'gke.*', la serie temporale viene inclusa nell'output. In caso contrario, la serie temporale viene eliminata dall'output.

Per ulteriori informazioni sui filtri, consulta la pagina di riferimento di filter. Il predicato filter può essere qualsiasi espressione arbitraria che restituisce un valore booleano; per ulteriori informazioni, consulta Espressioni.

Raggruppa e aggrega

Il raggruppamento ti consente di raggruppare serie temporali in base a dimensioni specifiche. L'aggregazione combina tutte le serie temporali di un gruppo in un'unica serie temporale di output.

La seguente query filtra l'output dell'operazione fetch iniziale per conservare solo le serie temporali dalle risorse in una zona che inizia con us-central. Quindi raggruppa le serie temporali per zona e le combina utilizzando l'aggregazione mean.

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter zone =~ 'us-central.*'
| group_by [zone], mean(val())

La tabella risultante dall'operazione group_by ha una serie temporale per zona. Il seguente screenshot mostra il grafico risultante:

Il grafico mostra un recupero filtrato raggruppato per zona.

L'operazione group_by accetta due argomenti, separati da una virgola, ,. Questi argomenti determinano l'esatto comportamento di raggruppamento. In questo esempio, group_by [zone], mean(val()), gli argomenti si comportano come segue:

  • Il primo argomento, [zone], è un'espressione di mappa che determina il raggruppamento delle serie temporali. In questo esempio, specifica le etichette da utilizzare per il raggruppamento. Il passaggio di raggruppamento raccoglie tutte le serie temporali di input che hanno gli stessi valori zone di output in un gruppo. In questo esempio, l'espressione raccoglie le serie temporali dalle VM di Compute Engine in una zona.

    La serie temporale di output ha solo un'etichetta zone e il valore viene copiato dalla serie temporale di input nel gruppo. Altre etichette nelle serie temporali di input vengono eliminate dalla serie temporale di output.

    L'espressione mappa può fare molto di più delle etichette degli elenchi; per ulteriori informazioni, consulta la pagina di riferimento di map.

  • Il secondo argomento, mean(val()), determina in che modo le serie temporali di ogni gruppo vengono combinate o aggregated in un'unica serie temporale di output. Ogni punto delle serie temporali di output di un gruppo è il risultato dell'aggregazione dei punti con lo stesso timestamp di tutte le serie temporali di input nel gruppo.

    La funzione di aggregazione, mean in questo esempio, determina il valore aggregato. La funzione val() restituisce i punti da aggregare e la funzione di aggregazione viene applicata a questi punti. In questo esempio, ottieni la media dell'utilizzo della CPU delle macchine virtuali nella zona in ogni punto temporale dell'output.

    L'espressione mean(val()) è un esempio di espressione di aggregazione.

L'operazione group_by combina sempre raggruppamento e aggregazione. Se specifichi un raggruppamento, ma ometti l'argomento di aggregazione, group_by utilizza un'aggregazione predefinita, aggregate(val()), che seleziona una funzione appropriata per il tipo di dati. Consulta aggregate per l'elenco delle funzioni di aggregazione predefinite.

Utilizza group_by con una metrica basata su log

Supponi di aver creato una metrica di distribuzione basata su log per estrarre il numero di punti dati elaborati da un insieme di voci lunghe, comprese stringhe come le seguenti:

... entry ID 1 ... Processed data points 1000 ...
... entry ID 2 ... Processed data points 1500 ...
... entry ID 3 ... Processed data points 1000 ...
... entry ID 4 ... Processed data points 500 ...

Per creare una serie temporale che mostri il conteggio di tutti i punti dati elaborati, utilizza un MQL come segue:

fetch global
| metric 'logging.googleapis.com/user/METRIC_NAME'
| group_by [], sum(sum_from(value))

Per creare una metrica di distribuzione basata su log, consulta Configurare le metriche di distribuzione.

Escludere colonne da un gruppo

Puoi utilizzare il modificatore drop in una mappatura per escludere le colonne da un gruppo. Ad esempio, la metrica core_usage_time di Kubernetes ha sei colonne:

fetch k8s_container :: kubernetes.io/container/cpu/core_usage_time
| group_by [project_id, location, cluster_name, namespace_name, container_name]

Se non devi raggruppare pod_name, puoi escluderlo con drop:

fetch k8s_container :: kubernetes.io/container/cpu/core_usage_time
| group_by drop [pod_name]

Seleziona serie temporali

Gli esempi in questa sezione illustrano come selezionare determinate serie temporali da una tabella di input.

Seleziona le serie temporali principali o inferiori

Per visualizzare i dati delle serie temporali per le tre istanze di Compute Engine con l'utilizzo più elevato della CPU all'interno del progetto, inserisci la query seguente:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top 3

Il seguente screenshot mostra il risultato di un progetto:

Il grafico mostra le 3 serie temporali
di utilizzo più elevato.

Puoi recuperare le serie temporali con l'utilizzo più basso della CPU sostituendo top con bottom.

L'operazione top restituisce una tabella con un numero specificato di serie temporali selezionate dalla relativa tabella di input. Le serie temporali incluse nell'output hanno il valore più alto per alcuni aspetti della serie temporale.

Poiché questa query non specifica un modo per ordinare le serie temporali, restituisce quelle con il valore più grande per il punto più recente. Per specificare come determinare quali serie temporali hanno il valore più grande, puoi fornire un argomento per l'operazione top. Ad esempio, la query precedente equivale alla seguente query:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top 3, val()

L'espressione val() seleziona il valore del punto più recente in ogni serie temporale a cui è applicata. Di conseguenza, la query restituisce le serie temporali con il valore più alto per il punto più recente.

Puoi fornire un'espressione che esegue l'aggregazione su alcuni o tutti i punti di una serie temporale per fornire il valore di ordinamento. Di seguito viene calcolata la media di tutti i punti negli ultimi 10 minuti:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top 3, mean(val()).within(10m)

Se la funzione within non viene utilizzata, la funzione mean viene applicata ai valori di tutti i punti visualizzati nelle serie temporali.

L'operazione bottom funziona in modo simile. La seguente query trova il valore del punto più grande in ogni serie temporale con max(val()), poi seleziona le tre serie temporali per le quali quel valore è il più piccolo:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| bottom 3, max(val())

Il seguente screenshot mostra un grafico che mostra gli stream con i picchi più piccoli:

Il grafico mostra le 3 serie temporali
di utilizzo più elevato.

Escludi i n risultati migliori o inferiori nelle serie temporali

Considera uno scenario in cui hai molte istanze VM di Compute Engine. Alcune di queste istanze consumano molta più memoria rispetto alla maggior parte delle istanze, e questi valori anomali rendono più difficile visualizzare i pattern di utilizzo nel gruppo più grande. I grafici sull'utilizzo della CPU hanno il seguente aspetto:

Il grafico mostra molte linee di utilizzo della CPU, con diversi valori anomali.

Devi escludere i tre valori anomali dal grafico in modo da poter vedere i pattern nel gruppo più grande in modo più chiaro.

Per escludere le prime tre serie temporali in una query che recupera la serie temporale per l'utilizzo della CPU di Compute Engine, utilizza l'operazione della tabella top per identificare la serie temporale e l'operazione della tabella outer_join per escludere le serie temporali identificate dai risultati. Puoi utilizzare la seguente query:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| {
    top 3 | value [is_default_value: false()]
  ;
    ident
  }
| outer_join true(), _
| filter is_default_value
| value drop [is_default_value]

L'operazione fetch restituisce una tabella di serie temporali per l'utilizzo della CPU da tutte le istanze. Questa tabella viene quindi elaborata in due tabelle risultanti:

  • L'operazione della tabella top n restituisce una tabella contenente la serie temporale n con i valori più elevati. In questo caso, n = 3. La tabella risultante contiene le serie tre volte da escludere.

    La tabella contenente le prime tre serie temporali viene poi riportata in un'operazione di tabella value. Questa operazione aggiunge un'altra colonna a ciascuna delle serie temporali nella tabella delle prime tre. A questa colonna, is_default_value, viene assegnato il valore booleano false per tutte le serie temporali nella tabella delle tre principali.

  • L'operazione ident restituisce la stessa tabella inserita nell'elemento: la tabella originale delle serie temporali di utilizzo della CPU. Nessuna delle serie temporali in questa tabella ha la colonna is_default_value.

Le prime tre tabelle e la tabella originale vengono poi incluse nell'operazione della tabella outer_join. La tabella delle prime tre tabelle è la tabella a sinistra nel join, la tabella recuperata è la tabella destra nel join. Il join esterno è configurato per fornire il valore true come valore per qualsiasi campo che non esiste in una riga che viene unita. Il risultato dell'outer join è una tabella unita, in cui le righe della tabella delle prime tre righe contengono la colonna is_default_value con il valore false, mentre tutte le righe della tabella originale che non erano anch'esse presenti nella tabella delle prime tre chiamate ricevono la colonna is_default_value con il valore true.

La tabella risultante dal join viene quindi passata all'operazione della tabella filter, che filtra le righe che hanno un valore false nella colonna is_default_value. La tabella risultante contiene le righe della tabella recuperata originariamente senza le righe della tabella delle prime tre. Questa tabella contiene l'insieme previsto di serie temporali, con l'elemento is_default_column aggiunto.

Il passaggio finale consiste nell'eliminare la colonna is_default_column aggiunta dal join, in modo che la tabella di output abbia le stesse colonne della tabella recuperata originariamente.

Il seguente screenshot mostra il grafico della query precedente:

Il grafico mostra molte linee di utilizzo della CPU, con i valori anomali esclusi.

Puoi creare una query per escludere le serie temporali con l'utilizzo più basso della CPU sostituendo top n con bottom n.

La possibilità di escludere i valori anomali può essere utile nei casi in cui vuoi impostare un avviso, ma non vuoi che le anomalie lo attivino costantemente. La seguente query di avviso utilizza la stessa logica di esclusione della query precedente per monitorare l'utilizzo del limite di CPU da parte di un insieme di pod Kubernetes dopo aver escluso i primi due pod:

fetch k8s_container
| metric 'kubernetes.io/container/cpu/limit_utilization'
| filter (resource.cluster_name == 'CLUSTER_NAME' &&
          resource.namespace_name == 'NAMESPACE_NAME' &&
          resource.pod_name =~ 'POD_NAME')
| group_by 1m, [value_limit_utilization_max: max(value.limit_utilization)]
| {
    top 2 | value [is_default_value: false()]
  ;
    ident
  }
| outer_join true(), _
| filter is_default_value
| value drop [is_default_value]
| every 1m
| condition val(0) > 0.73 '1'

Seleziona le risposte in alto o in basso dai gruppi

Le operazioni nelle tabelle top e bottom selezionano le serie temporali dall'intera tabella di input. Le operazioni top_by e bottom_by raggruppano le serie temporali in una tabella e poi scelgono un certo numero di serie temporali da ogni gruppo.

La seguente query seleziona le serie temporali in ogni zona con il valore di picco più grande:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top_by [zone], 1, max(val())

Il grafico mostra il picco più grande per zona.

L'espressione [zone] indica che un gruppo è costituito dalla serie temporale con lo stesso valore della colonna zone. 1 in top_by indica quante serie temporali selezionare dal gruppo di ogni zona. L'espressione max(val()) cerca il valore più grande nell'intervallo di tempo del grafico in ogni serie temporale.

Puoi utilizzare qualsiasi funzione di aggregazione al posto di max. Ad esempio, quanto segue utilizza l'aggregatore mean e within per specificare l'intervallo di ordinamento di 20 minuti. Seleziona le prime 2 serie temporali di ogni zona:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| top_by [zone], 2, mean(val()).within(20m)

Il grafico mostra i due più grandi picchi medi per zona entro 20 minuti.

Nell'esempio precedente, è presente una sola istanza nella zona us-central-c, quindi viene restituita una sola serie temporale e non è presente una "top 2" nel gruppo.

Combina le selezioni con union

Puoi combinare operazioni di selezione come top e bottom per creare grafici che mostrino entrambe. Ad esempio, la seguente query restituisce la singola serie temporale con il valore massimo e la singola serie temporale con il valore minimo:

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| {
    top 1, max(val())
  ;
    bottom 1, min(val())
  }
| union

Il grafico risultante mostra due righe, una contenente il valore più alto e l'altra contenente il valore più basso:

Il grafico mostra le serie temporali con i valori più alti e più bassi.

Puoi utilizzare le parentesi graffe, { }, per specificare sequenze di operazioni, ciascuna delle quali restituisce una tabella di serie temporali come output. Le singole operazioni sono separate da un punto e virgola, ;.

In questo esempio, l'operazione fetch restituisce una singola tabella, che viene inviata a ciascuna delle due operazioni nella sequenza, un'operazione top e un'operazione bottom. Ognuna di queste operazioni genera una tabella di output basata sulla stessa tabella di input. L'operazione union combina quindi le due tabelle in un'unica, che viene visualizzata nel grafico.

Scopri di più sulle operazioni di sequenza utilizzando { } nell'argomento di riferimento Struttura delle query.

Combinare serie temporali con valori diversi per una singola etichetta

Supponi di avere più serie temporali per lo stesso tipo di metrica e di voler combinarne alcune. Se vuoi selezionarle in base ai valori di una singola etichetta, non puoi creare la query utilizzando l'interfaccia del generatore di query in Metrics Explorer. Devi filtrare in base a due o più valori diversi della stessa etichetta, ma l'interfaccia di Query Builder richiede che una serie temporale corrisponda a tutti i filtri da selezionare: la corrispondenza delle etichette è un test AND. Nessuna serie temporale può avere due valori diversi per la stessa etichetta, ma non puoi creare un test OR per i filtri in Query Builder.

La seguente query recupera le serie temporali della metrica instance/disk/max_read_ops_count di Compute Engine per due istanze di Compute Engine specifiche e allinea l'output a intervalli di 1 minuto:

fetch gce_instance
| metric 'compute.googleapis.com/instance/disk/max_read_ops_count'
| filter (resource.instance_id == '1854776029354445619' ||
          resource.instance_id == '3124475757702255230')
| every 1m

Il seguente grafico mostra il risultato di questa query:

Il grafico mostra due serie temporali selezionate in base al valore della stessa etichetta.

Se vuoi trovare la somma dei valori massimi di max_read_ops_count per queste due VM e sommarli, puoi procedere come segue:

  • Trova il valore massimo per ogni serie temporale utilizzando l'operatore di tabella group_by, specificando lo stesso periodo di allineamento di 1 minuto e aggregando i dati nel periodo con l'aggregatore max per creare una colonna denominata max_val_of_read_ops_count_max nella tabella di output.
  • Trova la somma delle serie temporali utilizzando l'operatore di tabella group_by e l'aggregatore sum nella colonna max_val_of_read_ops_count_max.

Di seguito viene mostrata la query:

fetch gce_instance
| metric 'compute.googleapis.com/instance/disk/max_read_ops_count'
| filter (resource.instance_id == '1854776029354445619' ||
          resource.instance_id == '3124475757702255230')
| group_by 1m, [max_val_of_read_ops_count_max: max(value.max_read_ops_count)]
| every 1m
| group_by [], [summed_value: sum(max_val_of_read_ops_count_max)]

Il seguente grafico mostra il risultato di questa query:

Il grafico mostra la somma di due serie temporali selezionate in base al valore della stessa etichetta.

Calcola le statistiche percentile nel tempo e tra i flussi

Per calcolare separatamente un valore di flusso percentile su una finestra scorrevole per ogni flusso, utilizza un'operazione group_by temporale. Ad esempio, la seguente query calcola il valore del 99° percentile di un flusso in una finestra scorrevole di 1 ora:

fetch gce_instance :: compute.googleapis.com/instance/cpu/utilization
| group_by 1h, percentile(val(), 99)
| every 1m

Per calcolare la stessa statistica percentile in un determinato momento tra i flussi, anziché nel tempo all'interno di un flusso, utilizza un'operazione group_by spaziale:

fetch gce_instance :: compute.googleapis.com/instance/cpu/utilization
| group_by [], percentile(val(), 99)

Rapporti di calcolo

Supponi di aver creato un servizio web distribuito che viene eseguito su istanze VM di Compute Engine e che utilizza Cloud Load Balancing.

Vuoi visualizzare un grafico che mostri il rapporto tra le richieste che restituiscono risposte HTTP 500 (errori interni) e il numero totale di richieste, ovvero il rapporto di richieste non riuscite. Questa sezione illustra diversi modi per calcolare il rapporto di richieste non riuscite.

Cloud Load Balancing utilizza il tipo di risorsa monitorata http_lb_rule. Il tipo di risorsa monitorata http_lb_rule ha un'etichetta matched_url_path_rule che registra il prefisso degli URL definiti per la regola; il valore predefinito è UNMATCHED.

Il tipo di metrica loadbalancing.googleapis.com/https/request_count ha un'etichetta response_code_class. Questa etichetta acquisisce la classe dei codici di risposta.

Utilizza outer_join e div

La seguente query determina le risposte 500 per ogni valore dell'etichetta matched_url_path_rule in ogni risorsa monitorata http_lb_rule nel tuo progetto. Quindi unisce questa tabella del conteggio degli errori alla tabella originale, che contiene tutti i conteggi delle risposte e suddivide i valori per mostrare il rapporto tra le risposte di errore e le risposte totali:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| {
    filter response_code_class = 500
  ;
    ident
  }
| group_by [matched_url_path_rule]
| outer_join 0
| div

Il seguente grafico mostra il risultato di un progetto:

Il grafico mostra il rapporto di errori totali delle richieste in base all'unione.

Le aree ombreggiate intorno alle linee del grafico sono bande min/max; per ulteriori informazioni, consulta la sezione Bande Min/max.

L'operazione fetch restituisce una tabella di serie temporali contenente i conteggi delle richieste per tutte le query con bilanciamento del carico. Questa tabella viene elaborata in due modi dalle due sequenze di operazioni tra parentesi graffe:

  • filter response_code_class = 500 restituisce solo le serie temporali che hanno l'etichetta response_code_class con il valore 500. La serie temporale risultante conteggia le richieste con codici di risposta HTTP 5xx (errore).

    Questa tabella è il numeratore del rapporto.

  • L'operazione ident, o identity, restituisce l'input, quindi questa operazione restituisce la tabella recuperata inizialmente. Questa è la tabella che contiene le serie temporali con il conteggio di ogni codice di risposta.

    Questa tabella è il denominatore del rapporto.

Le tabelle del numeratore e del denominatore, prodotte rispettivamente dalle operazioni filter e ident, vengono elaborate separatamente dall'operazione group_by. L'operazione group_by raggruppa le serie temporali in ogni tabella in base al valore dell'etichetta matched_url_path_rule e somma i conteggi per ogni valore dell'etichetta. Questa operazione group_by non dichiara esplicitamente la funzione di aggregazione, perciò viene utilizzato un valore predefinito, sum.

  • Per la tabella filtrata, il risultato group_by è il numero di richieste che restituiscono una risposta 500 per ogni valore matched_url_path_rule.

  • Per la tabella delle identità, il risultato group_by è il numero totale di richieste per ogni valore matched_url_path_rule.

Queste tabelle sono collegate all'operazione outer_join, che accoppia le serie temporali ai valori delle etichette corrispondenti, uno da ciascuna delle due tabelle di input. Le serie temporali accoppiate vengono compresse abbinando il timestamp di ogni punto in una serie temporale al timestamp di un punto nell'altra serie temporale. Per ogni coppia corrispondente di punti, outer_join produce un singolo punto di output con due valori, uno da ciascuna delle tabelle di input. La serie temporale compressa viene visualizzata dal join con le stesse etichette delle serie temporali a due input.

Con un outer join, se un punto della seconda tabella non ha un punto di corrispondenza nella prima, è necessario fornire un valore sostitutivo. In questo esempio viene utilizzato un punto con valore 0, l'argomento dell'operazione outer_join.

Infine, l'operazione div prende ogni punto con due valori e suddivide i valori per produrre un singolo punto di output: il rapporto tra 500 risposte a tutte le risposte per ogni mappa URL.

La stringa div qui è in realtà il nome della funzione div, che suddivide due valori numerici. Ma è utilizzato qui come operazione. Quando utilizzate come operazioni, funzioni come div prevedono due valori in ciascun punto di input (garantito da join) e producono un singolo valore per il punto di output corrispondente.

La parte | div della query è una scorciatoia per | value val(0) / val(1). L'operazione value consente alle espressioni arbitrarie sulle colonne dei valori di una tabella di input di produrre le colonne di valori della tabella di output. Per saperne di più, consulta le pagine di riferimento per l'operazione value e le espressioni.

Utilizza ratio

La funzione div può essere sostituita con qualsiasi funzione su due valori. Tuttavia, dal momento che i rapporti sono utilizzati così di frequente, MQL fornisce un'operazione della tabella ratio che calcola direttamente i rapporti.

La seguente query è equivalente alla versione precedente, utilizzando outer_join e div:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| {
    filter response_code_class = 500
  ;
    ident
  }
| group_by [matched_url_path_rule]
| ratio

In questa versione, l'operazione ratio sostituisce le operazioni outer_join 0 | div nella versione precedente e produce lo stesso risultato.

Tieni presente che ratio utilizza outer_join per fornire un 0 per il numeratore solo se gli input relativi al numeratore e al denominatore hanno le stesse etichette che identificano ogni serie temporale, richiesta da MQL outer_join. Se l'input del numeratore ha etichette aggiuntive, non ci sarà alcun output per nessun punto mancante nel denominatore.

Utilizza group_by e /

C'è un altro modo per calcolare il rapporto tra le risposte di errore e tutte le risposte. In questo caso, poiché il numeratore e il denominatore del rapporto provengono dalla stessa serie temporale, puoi anche calcolare il rapporto raggruppando i dati. La seguente query mostra questo approccio:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| group_by [matched_url_path_rule],
    sum(if(response_code_class = 500, val(), 0)) / sum(val())

Questa query utilizza un'espressione di aggregazione basata sul rapporto di due somme:

  • Il primo elemento sum utilizza la funzione if per conteggiare 500 etichette con valore e 0 per le altre. La funzione sum calcola il conteggio delle richieste che hanno restituito 500.

  • Il secondo sum somma i conteggi di tutte le richieste, val().

Le due somme vengono quindi divise, ottenendo il rapporto di 500 risposte per tutte le risposte. Questa query produce lo stesso risultato di quelle query in Utilizzo di outer_join e div e Utilizzo di ratio.

Utilizza filter_ratio_by

Poiché i rapporti vengono spesso calcolati dividendo due somme derivate dalla stessa tabella, MQL fornisce l'operazione filter_ratio_by a questo scopo. La seguente query funziona come la versione precedente, che suddivide esplicitamente le somme:

fetch https_lb_rule::loadbalancing.googleapis.com/https/request_count
| filter_ratio_by [matched_url_path_rule], response_code_class = 500

Il primo operando dell'operazione filter_ratio_by, qui [matched_url_path_rule], indica come raggruppare le risposte. La seconda operazione, qui response_code_class = 500, agisce come espressione di filtro per il numeratore.

  • La tabella del denominatore è il risultato del raggruppamento della tabella recuperata per matched_url_path_rule e aggregata tramite sum.
  • La tabella del numeratore è la tabella recuperata, filtrata in base alle serie temporali con un codice di risposta HTTP 5xx e poi raggruppate per matched_url_path_rule e aggregate utilizzando sum.

Proporzioni e metriche di quota

Per configurare query e avvisi sulle metriche delle quote di serviceruntime e sulle metriche di quota specifiche delle risorse al fine di monitorare il consumo della quota, puoi utilizzare MQL. Per ulteriori informazioni, inclusi gli esempi, consulta Utilizzo delle metriche delle quote.

Calcolo aritmetico

A volte potresti voler eseguire un'operazione aritmetica sui dati prima di crearli in un grafico. Ad esempio, potresti voler scalare le serie temporali, convertire i dati in scala logaritmica o tracciare la somma di due serie temporali. Per un elenco delle funzioni aritmetiche disponibili in MQL, consulta Aritmetica.

Per scalare una serie temporale, utilizza la funzione mul. Ad esempio, la seguente query recupera le serie temporali e moltiplica ogni valore per 10:

  fetch gce_instance
  | metric 'compute.googleapis.com/instance/disk/read_bytes_count'
  | mul(10)

Per sommare due serie temporali, configura la query in modo da recuperare due tabelle di serie temporali, unisci i risultati e chiama la funzione add. L'esempio seguente illustra una query che calcola la somma del numero di byte letti e scritti nelle istanze di Compute Engine:

  fetch gce_instance
  | { metric 'compute.googleapis.com/instance/disk/read_bytes_count'
    ; metric 'compute.googleapis.com/instance/disk/write_bytes_count' }
  | outer_join 0
  | add

Per sottrarre il numero di byte scritti dal conteggio dei byte letti, sostituisci add con sub nell'espressione precedente.

MQL utilizza le etichette negli insiemi di tabelle restituite dal primo e dal secondo recupero per determinare come unire le tabelle:

  • Se la prima tabella contiene un'etichetta non trovata nella seconda, MQL non può eseguire un'operazione outer_join sulle tabelle e, di conseguenza, segnala un errore. Ad esempio, la seguente query causa un errore perché l'etichetta metric.throttle_reason è presente nella prima tabella, ma non nella seconda:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/throttled_read_bytes_count'
        ; metric 'compute.googleapis.com/instance/disk/write_bytes_count' }
      | outer_join 0
      | add
    

    Un modo per risolvere questo tipo di errore è applicare clausole di raggruppamento per garantire che le due tabelle abbiano le stesse etichette. Ad esempio, puoi raggruppare le etichette tutte le serie temporali:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/throttled_read_bytes_count'
          | group_by []
        ; metric 'compute.googleapis.com/instance/disk/write_bytes_count'
          | group_by [] }
      | outer_join 0
      | add
    
  • Se le etichette delle due tabelle corrispondono o se la seconda tabella contiene un'etichetta non trovata nella prima tabella, il join esterno è consentito. Ad esempio, la seguente query non genera un errore anche se l'etichetta metric.throttle_reason è presente nella seconda tabella, ma non nella prima:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/write_bytes_count'
        ; metric 'compute.googleapis.com/instance/disk/throttled_read_bytes_count' }
      | outer_join 0
      | sub
    

    Una serie temporale presente nella prima tabella potrebbe avere valori di etichetta corrispondenti a più serie temporali nella seconda tabella, quindi MQL esegue l'operazione di sottrazione per ogni abbinamento.

Variazione temporale

A volte potresti voler confrontare ciò che sta succedendo ora con ciò che è accaduto in passato. Per consentirti di confrontare i dati passati con quelli attuali, MQL fornisce l'operazione della tabella time_shift per spostare i dati dal passato al periodo di tempo attuale.

Proporzioni di tempi supplementari

La seguente query utilizza time_shift, join e div per calcolare il rapporto dell'utilizzo medio in ogni zona da adesso a una settimana prima.

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| group_by [zone], mean(val())
| {
    ident
  ;
    time_shift 1w
  }
| join | div

Il seguente grafico mostra un possibile risultato di questa query:

Il grafico mostra il rapporto tra i dati attuali e in timeshift.

Le prime due operazioni recuperano le serie temporali e poi le raggruppano per zona, calcolando i valori medi di ciascuna. La tabella risultante viene quindi passata a due operazioni. La prima operazione, ident, trasmette la tabella senza modifiche.

La seconda operazione, time_shift, aggiunge il periodo (1 settimana) ai timestamp dei valori nella tabella, spostando i dati da una settimana prima. Con questa modifica, i timestamp dei dati meno recenti nella seconda tabella vengono allineati a quelli dei dati correnti nella prima tabella.

La tabella non modificata e la tabella con timeshift vengono quindi combinate utilizzando un elemento join interno. join genera una tabella di serie temporali in cui ogni punto ha due valori: l'utilizzo attuale e l'utilizzo della settimana precedente. La query utilizza quindi l'operazione div per calcolare il rapporto tra il valore attuale e il valore della settimana precedente.

Dati passati e presenti

Combinando time_shift con union, puoi creare un grafico che mostra contemporaneamente i dati passati e presenti. Ad esempio, la seguente query restituisce l'utilizzo medio complessivo attuale e di una settimana prima. Con union, puoi visualizzare questi due risultati nello stesso grafico.

fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| group_by []
| {
     add [when: "now"]
  ;
     add [when: "then"] | time_shift 1w
  }
| union

Il seguente grafico mostra un possibile risultato di questa query:

Il grafico mostra la media di utilizzo
attuale e passata.

Questa query recupera le serie temporali e utilizza group_by [] per combinarle in un'unica serie temporale senza etichette, lasciando i punti dati relativi all'utilizzo della CPU. Questo risultato viene passato a due operazioni. Il primo aggiunge una colonna per una nuova etichetta denominata when con il valore now. Il secondo aggiunge un'etichetta denominata when con il valore then e trasmette il risultato all'operazione time_shift per spostare i valori di una settimana. Questa query utilizza il modificatore di mappa add; consulta Mappe per ulteriori informazioni.

Le due tabelle, ciascuna contenente i dati di una singola serie temporale, vengono passate a union, che genera una tabella contenente le serie temporali di entrambe le tabelle di input.

Passaggi successivi

Per una panoramica delle strutture del linguaggio MQL, consulta Informazioni sul linguaggio MQL.

Per una descrizione completa di MQL, consulta la documentazione di riferimento sul linguaggio di query di Monitoring.

Per informazioni sull'interazione con i grafici, consulta Utilizzo dei grafici.