Questa pagina fornisce informazioni generali su Monitoring Query Language (MQL), inclusi i seguenti argomenti:
- Scorciatoie per le query per le operazioni e le funzioni delle tabelle.
- Varianti delle operazioni MQL
fetch
. - Query nel formato rigoroso.
- Regole per la corrispondenza della colonna
resource.project_id
. - Scopri in che modo l'"effetto bordo" può influire sui rapporti calcolati tra i tipi di metriche.
- Formati di data supportati da MQL.
- Limiti relativi a lunghezza e complessità delle query.
- Macro in MQL.
Queste informazioni si applicano a prescindere dall'utilizzo di MQL dalla console Google Cloud o dall'API Cloud Monitoring. Per informazioni sulla struttura delle query MQL, consulta gli esempi.
Scorciatoie per le operazioni e le funzioni delle tabelle
Le query in genere sono costituite da catene connesse di operazioni sulle tabelle collegate da tubi (|
), ciascuna delle quali inizia con il nome dell'operazione tabella seguito da un elenco di espressioni. Le espressioni possono contenere chiamate di funzione
che elencano esplicitamente tutti i loro argomenti. Monitoring Query Language consente invece di
esprimere le query con una serie di scorciatoie.
Questa sezione descrive le scorciatoie per le operazioni sulle tabelle, utilizzando le funzioni come operazioni tabella, e una scorciatoia per le colonne dei valori come argomenti delle funzioni.
Per un elenco completo, vedi Scorciatoie per le operazioni relative alle tabelle.
Scorciatoie per le operazioni nelle tabelle
Quando utilizzi le operazioni fetch
, group_by
e filter
, puoi omettere l'operazione di tabella esplicita quando gli argomenti sono sufficienti per determinare l'operazione prevista. Ad esempio, la query seguente:
gce_instance::compute.googleapis.com/instance/cpu/utilization
equivale a:
fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
Le seguenti operazioni group_by
sono equivalenti:
[zone], mean(val()) group_by [zone], mean(val())
Puoi omettere la parola filter
se tra parentesi il test del filtro. Ad esempio, le seguenti due operazioni filter
sono l'equivalente:
(instance_name =~ 'apache.*') filter instance_name =~ 'apache.*'
Puoi combinare questi moduli di scelta rapida nelle query. Ad esempio, la seguente query:
gce_instance::compute.googleapis.com/instance/cpu/utilization
| (instance_name =~ 'apache.*')
| [zone], mean(val())
è equivalente a questa forma più esplicita:
fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| filter instance_name =~ 'apache.*'
| group_by [zone], mean(val())
Per ulteriori informazioni sulle scorciatoie per le operazioni sulle tabelle, consulta Scorciatoie delle operazioni sulle tabelle nel riferimento MQL.
Utilizzo di una funzione come operazione tabella
In genere, un'operazione tabella inizia con il nome di un'operazione tabella. Tuttavia, MQL consente di avviare un'operazione di tabella con il nome di una funzione.
Puoi utilizzare il nome di una funzione quando la funzione con nome esegue alcune trasformazioni delle colonne dei valori della tabella di input. Questa sostituzione è una
scorciatoia per le operazioni della tabella group_by
, align
o value
, a seconda del tipo di funzione di cui viene assegnato il nome.
La forma generale è:
| FUNCTION_NAME ARG, ARG ...
Nell'operazione di tabella, la funzione prende le colonne dei valori della tabella di input come argomenti, argomenti seguiti da qualsiasi argomento per la funzione stessa.
Quando utilizzi una funzione come operazione tabella, specifichi gli argomenti nel formato
operazione tabella, come elenco separato da virgole, anziché con le
parentesi circostanti (()
) normalmente utilizzate con le funzioni.
L'operazione di tabella completa generata dall'espansione della scorciatoia dipende dal tipo di funzione:
group_by
: se utilizzi una funzione di aggregazione con un'operazionegroup_by
che aggrega tutte le colonne degli identificatori delle serie temporali (ossia utilizza[]
per il raggruppamento), puoi utilizzare questa funzione come scorciatoia. Ad esempio:| distribution powers_of(1.1)
è una scorciatoia per
| group_by [], distribution(val(0), powers_of(1.1))
align
: se utilizzi una funzione di allineamento come argomento dell'operazionealign
, puoi utilizzarla come scorciatoia. Ad esempio:| delta
è una scorciatoia per
| align delta()
Analogamente,
| rate 10m
è una scorciatoia per
| align rate(10m)
Tieni presente che le funzioni di allineamento prendono le serie temporali di input come un argomento implicito, pertanto le colonne dei valori non vengono indicate esplicitamente qui.
value
: tutte le altre funzioni possono fungere da scorciatoie per l'operazione della tabellavalue
. Ad esempio:| mul 3.3
è una scorciatoia per
| value mul(val(0), 3.3)
Analogamente,
| div
è una scorciatoia per
| value div(val(0), val(1))
Tieni presente che la scorciatoia
div
consente di eseguire un'operazione di tabella di input con due colonne di valori e produce un'operazione di tabella con una colonna di valori che rappresenta il rapporto.
Scorciatoia per le funzioni della colonna valori
Puoi utilizzare .function
come scorciatoia
per function(val())
se nell'input è presente una singola
colonna di valori o come scorciatoia per
function(val(0), val(1))
se sono presenti due colonne
di valori e così via.
Il punto iniziale significa: "Richiama la funzione seguente, fornendo la colonna o le colonne del valore del punto di input come argomento o degli argomenti della funzione".
Ad esempio, .mean
è una scorciatoia per mean(val())
. I seguenti termini sono equivalenti:
group_by [zone], .mean group_by [zone], mean(val())
Se la tabella di input ha più colonne di valori, ogni colonna diventa un argomento della funzione in questa scorciatoia. Ad esempio, se la tabella di input ha due colonne di valori, allora
.div
è una scorciatoia per
div(val(0), val(1))
Con questa scorciatoia puoi fornire argomenti che non fanno riferimento alle colonne dei valori. Gli argomenti aggiuntivi vengono forniti dopo gli argomenti colonna-valore. Ad esempio, se la tabella di input ha una colonna di valori, allora
.div(3)
è equivalente a
div(val(0), 3)
Variazioni su fetch
L'operazione fetch
di solito restituisce una tabella delle serie temporali denominata in base a una coppia di tipi di risorse e metriche monitorate. Ad esempio:
fetch gce_instance :: compute.googleapis.com/instance/cpu/utilization
Se la metrica si applica solo a un tipo di risorsa monitorata, puoi omettere la risorsa monitorata dalla query. La seguente query è equivalente alla query precedente, perché la metrica di utilizzo della CPU si applica solo a gce_instance
risorse monitorate:
fetch compute.googleapis.com/instance/cpu/utilization
L'operazione fetch
può specificare solo un tipo di risorsa monitorata, con la metrica specificata in una successiva operazione metric
. Ad esempio, questo esempio è equivalente ai precedenti esempi di fetch
:
fetch gce_instance
| metric metric compute.googleapis.com/instance/cpu/utilization
Suddividere il fetch
in questo modo può essere utile quando vuoi recuperare due metriche diverse per la stessa risorsa monitorata. Ad esempio, la seguente query calcola il numero di pacchetti consumati al secondo di CPU:
fetch gce_instance
| {
metric compute.googleapis.com/instance/network/received_packets_count ;
metric compute.googleapis.com/instance/cpu/usage_time
}
| ratio
La suddivisione di fetch
consente anche di applicare il filtro solo alle etichette della risorsa monitorata:
fetch gce_instance
| filter resource.zone =~ "asia.*"
| {
metric compute.googleapis.com/instance/network/received_packets_count ;
metric compute.googleapis.com/instance/cpu/usage_time
}
| ratio
Un fetch
che nomina solo un tipo di risorsa monitorata deve essere seguito da un'operazione metric
, magari con operazioni filter
intermedie.
Query in formato restrittivo
Una query rigorosa è una senza scorciatoie o valori impliciti utilizzati nelle query concise. Le query più rigorose hanno le seguenti caratteristiche:
- Tutte le scorciatoie vengono sostituite.
- Tutti gli argomenti impliciti vengono resi espliciti.
- Le colonne vengono indicate con nomi completi.
- Le nuove colonne hanno un nome esplicito.
- Qualsiasi operazione di allineamento fornita implicitamente viene fornita in modo esplicito.
L'utilizzo del formato restrittivo rende la query più resiliente alle modifiche nella struttura delle tabelle di input e può rendere più chiaro lo svolgimento della query. La pubblicazione di una query in formato restrittivo non la rende più efficiente.
Quando salvi una query per un grafico, questa viene convertita in formato restrittivo. Nella finestra di dialogo di conferma dell'operazione di salvataggio viene visualizzata la forma restrittiva.
Le query concise per i criteri di avviso non vengono convertite in formato restrittivo. Le query per i criteri di avviso vengono archiviate man mano che le fornisci. Puoi utilizzare il formato conciso o rigoroso.
Grazie alle scorciatoie e ai formati restrittivi disponibili, potresti incontrare query MQL equivalenti che hanno un aspetto molto diverso l'una dall'altra. Ad esempio, la seguente query, che calcola il numero di pacchetti ricevuti per secondo CPU consumata, utilizza molte scorciatoie:
gce_instance
| (zone =~ ".*-a")
| {
compute.googleapis.com/instance/network/received_packets_count ;
compute.googleapis.com/instance/cpu/usage_time
}
| join
| div
Quando salvi questa query in un grafico o come parte di un criterio di avviso, la query in formato restrittivo risultante ha esattamente la stessa funzione. Tuttavia, il formato restrittivo potrebbe avere un aspetto piuttosto diverso, come mostrato nell'esempio seguente:
fetch gce_instance
| filter (resource.zone =~ '.*-a')
| { t_0:
metric 'compute.googleapis.com/instance/network/received_packets_count'
| align delta() ;
t_1:
metric 'compute.googleapis.com/instance/cpu/usage_time'
| align delta() }
| join
| value [v_0: div(t_0.value.received_packets_count, t_1.value.usage_time)]
Quando modifichi la definizione salvata del grafico, nell'editor di codice viene visualizzata la forma restrittiva.
Corrisponde alla colonna resource.project_id
I progetti Google Cloud hanno un nome visualizzato che appare nei menu ma non identifica il progetto in modo univoco. Un nome visualizzato del progetto potrebbe essere "Monitoring demo".
I progetti hanno anche due campi che fungono da identificatori:
- ID progetto: un identificatore di stringa univoco. Spesso si basa sul nome visualizzato. Gli ID progetto vengono impostati al momento della creazione del progetto, in genere concatenando gli elementi del nome del progetto e possibilmente aggiungendo cifre alla fine, se necessario per l'univocità. Un ID progetto può avere il formato "monitoring-demo" o "monitoring-demo-2349". L'ID progetto a volte viene chiamato casualmente il nome del progetto.
- Numero di progetto: un identificatore numerico univoco.
Ogni tipo di risorsa monitorata include un'etichetta project_id
, con una rappresentazione stringa del numero del progetto proprietario della risorsa e dei relativi dati.
Nelle query MQL, fai riferimento a questa etichetta come resource.project_id
.
L'etichetta resource.project_id
ha il numero del progetto in formato testo come
valore, ma MQL lo converte nell'ID progetto in determinate
situazioni.
Nei seguenti casi, MQL considera il valore dell'etichetta resource.project_id
come ID progetto anziché come numero di progetto:
La legenda di un grafico mostra l'ID progetto anziché il numero di progetto per il valore dell'etichetta
resource.project_id
.I confronti di uguaglianza del valore di
resource.project_id
con un valore letterale stringa riconoscono sia il numero di progetto sia l'ID progetto. Ad esempio, quanto segue restituisce true per le risorse di proprietà di questo progetto:resource.project_id == "monitoring-demo"
resource.project_id == "530310927541"
Questo caso si applica agli operatori
==
e!=
e ai relativi moduli di funzione,eq()
ene()
.Una corrispondenza di espressione regolare sull'etichetta
resource.project_id
funziona correttamente con il numero di progetto o l'ID progetto. Ad esempio, entrambe le seguenti espressioni restituisconotrue
per le risorse di proprietà di questo progetto:resource.project_id =~ "monitoring-.*"
resource.project_id =~ ".*27541"
Questo caso si applica agli operatori
=~
e!~
e al modulo della funzionere_full_match
.
In tutti gli altri casi, viene utilizzato il valore effettivo dell'etichetta resource.project_id
. Ad esempio, concatenate("project-", resource.project_id)
restituisce
il valore project-530310927541
e non project-monitoring-demo
.
Rapporti e "effetto bordo"
In generale, è preferibile calcolare i rapporti in base a serie temporali raccolte per un singolo tipo di metrica, utilizzando i valori delle etichette. Un rapporto calcolato per due diversi tipi di metriche è soggetto ad anomalie dovute ai diversi periodi di campionamento e alle finestre di allineamento.
Ad esempio, supponiamo di avere due diversi tipi di metriche, un conteggio totale delle RPC e un conteggio degli errori RPC, e di voler calcolare il rapporto delle RPC rispetto al totale delle RPC. Le RPC non riuscite vengono conteggiate nella serie temporale di entrambi i tipi di metriche. Pertanto, è possibile che, quando allinei le serie temporali, una RPC non riuscita non venga visualizzata nello stesso intervallo di allineamento per entrambe le serie temporali. Questa differenza può verificarsi per diversi motivi, tra cui:
- Poiché esistono due serie temporali diverse che registrano lo stesso evento, esistono due valori contatore sottostanti che implementano la raccolta e i valori non vengono aggiornati a livello atomico.
- Le frequenze di campionamento potrebbero essere diverse. Quando le serie temporali sono allineate a un periodo comune, i conteggi per un singolo evento potrebbero essere visualizzati in intervalli di allineamento adiacenti nelle serie temporali per le diverse metriche.
La differenza nel numero di valori negli intervalli di allineamento corrispondenti può
portare a valori del rapporto error/total
senza senso, come 1/0 o 2/1.
I rapporti di numeri più grandi hanno meno probabilità di generare valori incomprensibili. Puoi ottenere numeri più elevati tramite aggregazione, utilizzando una finestra di allineamento più lunga del periodo di campionamento o raggruppando i dati per determinate etichette. Queste tecniche riducono al minimo l'effetto di piccole differenze nel numero di punti in un dato intervallo. Ciò significa che una disparità di due punti è più significativa quando il numero previsto di punti in un intervallo è 3 rispetto a quando il numero previsto è 300.
Se usi tipi di metriche integrate, potresti non avere altra scelta che calcolare i rapporti tra i tipi di metriche per ottenere il valore di cui hai bisogno.
Se stai progettando metriche personalizzate che potrebbero conteggiare gli stessi elementi, ad esempio le RPC che restituiscono lo stato di errore, in due metriche diverse, prendi in considerazione una singola metrica, che include ogni conteggio una sola volta. Ad esempio, supponiamo che tu stia conteggiando le RPC e che tu voglia monitorare il rapporto tra le RPC non riuscite e tutte le RPC. Per risolvere il problema, crea un singolo tipo di metrica per conteggiare le RPC e utilizza un'etichetta per registrare lo stato della chiamata, incluso lo stato "OK". Quindi, ogni valore di stato, errore o "OK", viene registrato aggiornando un singolo contatore per quel caso.
Formati data MQL
MQL supporta attualmente un numero limitato di formati di data. Nelle query MQL, le date sono espresse in uno dei seguenti modi:
d'BASE_STRING'
D'BASE_STRING'
BASE_STRING è una stringa nel formato
2010/06/23-19:32:15-07:00
. Il primo trattino (-
), che separa data e ora,
può essere sostituito da uno spazio. Nel componente orario, possono essere eliminate parti dell'ora dell'orologio (19:32:15
) o dell'identificatore del fuso orario (-07:00
).
Gli esempi seguenti sono date valide nelle query MQL:
d'2010/06/23-19:32:15-07:00'
d'2010/06/23 19:32:15-07:00'
d'2010/06/23 19:32:15'
D'2010/06/23 19:32'
d'2010/06/23-19'
D'2010/06/23 -07:00'
La seguente tabella elenca la grammatica per BASE_STRING:
Struttura | Significato |
---|---|
%Y/%m/%d |
Data |
%Y/%m/%d %H %Y/%m/%d-%H
|
Data, ora |
%Y/%m/%d %H:%M %Y/%m/%d-%H:%M
|
Data, ora, minuto |
%Y/%m/%d %H:%M:%S %Y/%m/%d-%H:%M:%S
|
Data, ora, minuto, secondo |
%Y/%m/%d %H:%M:%E*S %Y/%m/%d-%H:%M:%E*S
|
Data, ora, minuto, secondo frazionario |
%Y/%m/%d %Ez |
Data con fuso orario |
%Y/%m/%d %H%Ez %Y/%m/%d-%H%Ez
|
Data, ora, con fuso orario |
%Y/%m/%d %H:%M%Ez %Y/%m/%d-%H:%M%Ez
|
Data, ora, minuto, con fuso orario |
%Y/%m/%d %H:%M:%S%Ez %Y/%m/%d-%H:%M:%S%Ez
|
Data, ora, minuto, secondo, con fuso orario |
%Y/%m/%d %H:%M:%E*S%Ez %Y/%m/%d-%H:%M:%E*S%Ez
|
Data, ora, minuto, secondo frazionario, con fuso orario |
Lunghezza e complessità delle query
Le query di Monitoring Query Language possono essere lunghe e complesse, ma non senza limiti.
- Un testo di query con codifica UTF-8 è limitato a 10.000 byte.
- Una query è limitata a 2000 costrutti di linguaggio, ovvero la complessità AST† è limitata a 2000 nodi.
† Un albero di sintassi astratto, o AST, è una rappresentazione del codice sorgente, in questo caso la stringa di query MQL, in cui i nodi nella struttura ad albero sono mappati alle strutture sintattiche nel codice.
Macro MQL
MQL include un'utilità per la definizione delle macro. Puoi utilizzare le macro MQL per sostituire operazioni ripetute, rendere più leggibili le query complesse e semplificare lo sviluppo delle query. Puoi definire le macro per le operazioni della tabella e per le funzioni.
Le definizioni delle macro iniziano con la parola chiave def
.
Quando converti una query in forma rigida, le chiamate di macro vengono sostituite con il testo corrispondente e le definizioni delle macro vengono rimosse.
Quando salvi una query di un grafico che include macro, la query viene convertita in formato stretto, in modo che le macro non vengano conservate. Quando salvi una query per una condizione in un criterio di avviso, la query non viene convertita in formato restrittivo, quindi le macro vengono conservate.
Macro per le operazioni tabella
Puoi scrivere macro per eseguire nuove operazioni della tabella. La sintassi generale è simile alla seguente:
def MACRO_NAME [MACRO_PARAMETER[, MACRO_PARAMETER]] = MACRO_BODY ;
Per richiamare la macro, utilizza la seguente sintassi:
@MACRO_NAME [MACRO_ARG [, MACRO_ARG]]
Ad esempio, supponi di utilizzare la seguente query per recuperare i dati sull'utilizzo della CPU:
fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| every 1m
| group_by [zone], mean(val())
La prima riga può essere sostituita con la seguente macro:
def my_fetch = fetch gce_instance::compute.googleapis.com/instance/cpu/utilization ;
Per richiamare la macro nella query, sostituisci il valore fetch
originale come segue:
def my_fetch = fetch gce_instance::compute.googleapis.com/instance/cpu/utilization ;
@my_fetch
| every 1m
| group_by [zone], mean(val())
Puoi sostituire la seconda e la terza riga con macro che accettano argomenti.
La definizione della macro elenca i parametri della macro e, nel corpo della macro,
fa riferimento ai parametri della macro come $MACRO_PARAMETER
. Ad esempio, puoi definire le macro seguenti:
def my_every time_arg = every $time_arg ; def my_group label, aggr = group_by [$label], $aggr ;
Per richiamare queste macro e fornire gli argomenti, specifica gli argomenti in un elenco delimitato da virgole nelle chiamate delle macro. Di seguito viene mostrata la query con tutte le macro definite e le relative chiamate:
def my_fetch = fetch gce_instance::compute.googleapis.com/instance/cpu/utilization ;
def my_every time_arg = every $time_arg ;
def my_group label, aggr = group_by [$label], $aggr ;
{@my_fetch}
| @my_every 1m
| @my_group zone, mean(val())
Le macro non vengono conservate quando la query viene convertita in strict-form. Ad esempio, la forma restrittiva della query precedente ha il seguente aspetto:
fetch gce_instance::compute.googleapis.com/instance/cpu/utilization
| align mean_aligner()
| every 1m
| group_by [resource.zone],
[value_utilization_mean: mean(value.utilization)]
Macro per le funzioni
Per le funzioni MQL, devi specificare eventuali parametri in un elenco delimitato da virgole tra parentesi. Le parentesi distinguono una macro di funzione da una macro di operazione tabella. La parentesi deve apparire nella chiamata, anche se non sono presenti argomenti. Le macro non vengono conservate quando la query viene convertita in strict-form.
def MACRO_NAME([MACRO_PARAMETER [, MACRO_PARAMETER]]) = MACRO_BODY ;
Ad esempio, la seguente query recupera le tabelle di due metriche, combina le due tabelle in una colonna con due valori e calcola il rapporto tra i byte ricevuti e i byte totali per una colonna denominata received_percent
:
{
fetch k8s_pod :: kubernetes.io/pod/network/received_bytes_count ;
fetch k8s_pod :: kubernetes.io/pod/network/sent_bytes_count
}
| join
| value [received_percent: val(0) * 100 / (val(0) + val(1))]
Puoi sostituire il calcolo di received_percent
con una macro come nell'esempio seguente:
def recd_percent(recd, sent) = $recd * 100 / ($recd + $sent) ;
Per richiamare una macro di funzione, utilizza la seguente sintassi:
@MACRO_NAME([MACRO_ARG[, MACRO_ARG]])
Quando richiami una macro di funzione senza argomenti, devi specificare le parentesi vuote per distinguere la chiamata dalla chiamata di una macro di operazione tabella.
L'esempio seguente mostra la query precedente con una macro per il calcolo dei rapporti:
def recd_percent(recd, sent) = $recd * 100 / ($recd + $sent) ;
{
fetch k8s_pod :: kubernetes.io/pod/network/received_bytes_count ;
fetch k8s_pod :: kubernetes.io/pod/network/sent_bytes_count
}
| join
| value [received_percent: @recd_percent(val(0), val(1))]
Funzionalità macro
Le macro MQL sono elementi sintattici, al contrario degli elementi testuali come le macro utilizzate nel preprocessore C. Questa distinzione significa che un corpo della macro MQL deve essere sempre un'espressione sintatticamente valida. Potrebbe non essere semanticamente valido, il che dipende anche dagli argomenti delle macro e dalla posizione in cui la macro viene espansa.
Poiché le macro MQL sono sintattiche, esistono pochissime restrizioni sul tipo di espressione in cui possono espandersi. Le macro sintattiche sono solo un altro modo per manipolare l'albero della sintassi astratto. I seguenti esempi mostrano alcune delle cose che puoi fare con le macro sintattiche:
# Abbreviating a column name.
def my_col() = instance_name;
# Map-valued macro.
def my_map(c) = [$c, @my_col()];
# Abbreviating a string.
def my_zone() = 'us-central.*';
# Abbreviating a filter expression.
def my_filter(f) = zone =~ @my_zone() && $f;
MQL supporta anche la concatenazione implicita letterale delle stringhe. Questa funzionalità può essere molto utile durante la scrittura di query che includono nomi lunghi delle metriche. Quando un valore letterale stringa e un argomento macro, che devono essere anch'essi un valore letterale stringa, vengono visualizzati uno accanto all'altro nel corpo della macro, l'espansione della macro li concatena in un valore letterale stringa singola.
Nell'esempio seguente, gce_instance
è un
elemento lessicale BARE_NAME
.
Viene promosso automaticamente in un valore letterale di stringa, utile per la creazione di nomi di tabella:
# Builds a table name in domain 'd' with the suffix 'm'.
def my_table(d, m) = gce_instance::$d '/instance/' $m;
# Table name under the given domain.
def my_compute_table(m) = @my_table('compute.googleapis.com', $m);
Riassumendo, la seguente query utilizza tutte le macro definite in precedenza:
fetch @my_compute_table('cpu/utilization')
| filter @my_filter(instance_name =~ 'gke.*')
| group_by @my_map(zone)
Tieni presente che gli argomenti macro possono essere anche espressioni arbitrarie, purché siano sintatticamente corrette. Ad esempio, la macro my_filter
può utilizzare un'espressione booleana come instance_name =~ 'gke.*'
come primo argomento.
Anche abbreviare le operazioni delle tabelle può essere molto utile, come dimostra la seguente query:
# Calculate the ratio between compute metrics 'm1' and 'm2'.
def my_compute_ratio m1, m2 =
{ fetch @my_compute_table($m1); fetch @my_compute_table($m2) }
| join | div;
# Use the table op macro to calculate the ratio between CPU utilization and
# the number of reserved cores per zone.
@my_compute_ratio 'cpu/utilization', 'cpu/reserved_cores' | group_by [zone]
Infine, le macro di funzione possono comportarsi come funzioni normali, ovvero consentono la promozione della funzione, in cui la colonna o le colonne dei valori della tabella di input diventano i primi argomenti della macro. L'esempio seguente mostra una variante della query precedente che utilizza una macro di funzione:
# Simple arithmetic macro.
def my_add_two(x) = $x + 2;
# Similar to previous query, but now using the new arithmetic macro with
# function argument promotion.
fetch @my_compute_table('cpu/utilization')
| filter @my_filter(instance_name =~ 'gke.*')
| group_by @my_map(zone), [.sum.@my_add_two]
Limitazioni
La funzionalità della macro MQL non supporta quanto segue:
- Nidificazione delle definizioni delle macro: non è possibile definire una macro nel corpo di un'altra macro.
- Macro definite in modo ricorsivo. Nessun corpo macro può fare riferimento a macro, inclusa la macro, che non sia ancora completamente definita.
- Uso di funzioni definite dalle macro come operazioni tabellari.
- Uso di argomenti macro come nomi di funzioni o operazioni di tabella.
- Conservazione delle macro quando la query viene convertita in strict form. Le chiamate delle macro vengono sostituite con le espressioni corrispondenti e le definizioni delle macro vengono rimosse.