Exemples de requêtes MQL

Ce document présente le langage MQL (Monitoring Query Language) à travers des exemples. Cependant, il ne tente pas de couvrir tous les aspects du langage. MQL est est intégralement documentée dans la documentation de référence sur le langage de requête Monitoring.

Pour obtenir des informations sur les règles d'alerte basées sur MQL, consultez la page Règles d'alerte avec MQL.

Vous pouvez rédiger une requête particulière sous de nombreuses formes ; la langue est flexible et il existe de nombreux raccourcis que vous pouvez utiliser après avoir familiarisé avec la syntaxe. Pour en savoir plus, consultez la section Requêtes de format strict.

Avant de commencer

Pour accéder à l'éditeur de code lorsque vous utilisez l'Explorateur de métriques, procédez comme suit : suivantes:

  1. Dans la console Google Cloud, accédez à la page Explorateur de métriques :

    Accéder à l'explorateur de métriques

    Si vous utilisez la barre de recherche pour trouver cette page, sélectionnez le résultat dont le sous-titre est Surveillance.

  2. Dans la barre d'outils du volet de création de requêtes, sélectionnez le bouton nommé  MQL ou  PromQL.
  3. Vérifiez que MQL est sélectionné dans le bouton d'activation Langage. Le bouton de langage se trouve dans la barre d'outils qui vous permet de mettre en forme votre requête.

Pour exécuter une requête, collez-la dans l'éditeur, puis cliquez sur Exécuter la requête. Pour en savoir plus sur cet éditeur, consultez Utilisez l'éditeur de code pour MQL.

Une certaine connaissance des concepts de Cloud Monitoring, y compris des types de métriques, des types de ressources surveillées et des séries temporelles, est utile. Pour obtenir une présentation de ces concepts, consultez la page Métriques, séries temporelles et ressources.

Modèle de données

Les requêtes MQL récupèrent et manipulent les données de la base de données de séries temporelles Cloud Monitoring. Cette section présente certains concepts et termes associés à cette base de données. Pour en savoir plus, consultez la section Modèle de données dans la documentation de référence.

Chaque série temporelle provient d'un seul type de ressource surveillée, et chaque série temporelle collecte des données d'un type de métrique. Un descripteur de ressource surveillée définit un type de ressource surveillée. De même, Un descripteur de la métrique définit un type de métrique. Par exemple, le type de ressource peut être gce_instance, une Compute Engine, et que le type de métrique peut être compute.googleapis.com/instance/cpu/utilization, l'utilisation du processeur de la VM Compute Engine.

Ces descripteurs spécifient également un ensemble de libellés permettant de collecter des informations sur d'autres attributs du type de ressource ou de métrique. Par exemple, les ressources ont généralement un libellé zone, qui permet d'enregistrer leur emplacement géographique.

Une série temporelle unique est créée pour chaque combinaison de valeurs pour les libellés de la paire d'un descripteur de métrique et d'un descripteur de ressource surveillée.

Vous trouverez les libellés disponibles pour les types de ressources dans la Liste des ressources surveillées, par exemple gce_instance Pour trouver les libellés des types de métriques, consultez la liste des métriques. par exemple, consultez la section Métriques de Compute Engine.

La base de données Cloud Monitoring stocke la série temporelle la métrique et le type de ressource dans une seule table. Le type de métrique et le type de ressource servent d'identifiant pour la table. La requête MQL ci-dessous extrait la table des séries temporelles enregistrant l'utilisation du processeur pour les instances Compute Engine :

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

Le tableau contient une série temporelle pour chaque combinaison unique de métriques. et des valeurs d'étiquette de ressource.

Les requêtes MQL récupèrent les données de séries temporelles de ces tables et les transforment en tables de sortie. Ces tables de sortie peuvent être transmises à d'autres opérations. Par exemple, vous pouvez isoler les séries temporelles écrites par les ressources d'une zone ou d'un ensemble de zones spécifique en transmettant la table récupérée en tant qu'entrée à une opération filter :

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

La requête précédente génère une table qui ne contient que les séries temporelles des ressources d'une zone commençant par us-central :

Les requêtes MQL sont structurées pour transmettre le résultat d'une opération en tant qu'entrée à l'opération suivante. Cette approche basée sur les tables vous permet d'associer des opérations pour manipuler ces données par le biais du filtrage, de la sélection et d'autres opérations de base de données courantes telles que les jointures internes et externes. Vous pouvez également exécuter différentes fonctions sur les données de la série temporelle à mesure que les données est transmis d'une opération à une autre.

Les opérations et les fonctions disponibles dans le langage MQL sont entièrement décrites dans la documentation de référence sur le langage MQL.

Structure d'une requête

Une requête est composée d'une ou de plusieurs opérations. Les opérations sont liées ou canalisées, de sorte que la sortie d'une opération soit l'entrée de la suivante. Par conséquent, le résultat d'une requête dépend de l'ordre des opérations. Voici quelques exemples de ce que vous pouvez faire :

  • Lancer une requête avec une opération fetch ou une autre opération de sélection
  • Créer une requête avec plusieurs opérations canalisées
  • Sélectionnez un sous-ensemble d'informations avec des opérations filter.
  • Agréger les informations associées avec les opérations group_by
  • Examiner les anomalies avec les opérations top et bottom
  • Combiner plusieurs requêtes avec les opérations { ; } et join
  • Utiliser l'opération et les fonctions value pour calculer des ratios et d'autres valeurs

Toutes les requêtes n'utilisent pas toutes ces options.

Ces exemples ne présentent qu'une partie des opérations et des fonctions disponibles. Pour en savoir plus sur la structure des requêtes MQL, consultez la section Structure des requêtes dans la documentation de référence.

Ces exemples ne spécifient pas deux choses que vous pouvez vous attendre à voir : les périodes et l'alignement. Les sections suivantes expliquent pourquoi.

Périodes

Lorsque vous utilisez l'éditeur de code, les paramètres du graphique définissent le période pour les requêtes. Par défaut, la période du graphique est définie sur une heure.

Pour modifier la période du graphique, utilisez le sélecteur de période. Pour Par exemple, si vous souhaitez afficher les données de la semaine précédente, sélectionnez La semaine dernière selon le sélecteur de période. Vous pouvez également spécifier une heure de début et de fin, ou indiquer une heure à voir autour de vous.

Pour en savoir plus sur les périodes dans l'éditeur de code, consultez Périodes, graphiques et éditeur de code :

Alignement

De nombreuses opérations utilisées dans ces exemples, telles que les opérations join et group_by, dépendent de tous les points de série temporelle d'une table qui se produisent à intervalles réguliers. L'action d'aligner tous les points à des horodatages réguliers est appelée alignement. Habituellement, l’alignement est effectué implicitement, et aucun des exemples ici ne le montre.

MQL aligne automatiquement les tables pour les opérations join et group_by en cas de besoin, mais MQL vous permet également d'effectuer explicitement l'alignement.

  • Pour obtenir des informations générales sur le concept d'alignement, consultez la section Alignement : agrégation au sein d'une série.

  • Pour plus d'informations sur l'alignement dans le langage MQL, consultez la section Alignement dans la documentation de référence. L'alignement peut être explicitement contrôlé à l'aide des opérations align et every.

Extraire et filtrer les données

Les requêtes MQL commencent par la récupération, la sélection ou le filtrage données. Cette section présente quelques opérations de base à l'aide de MQL.

Récupérer des données de séries temporelles

Une requête commence toujours par une opération fetch, qui récupère l'heure de Cloud Monitoring.

La requête la plus simple consiste en une seule opération fetch et un argument qui identifie les séries temporelles à extraire, comme suit :

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

L'argument comprend un type de ressource surveillée (gce_instance), une paire de signes deux-points (::) et un type de métrique (compute.googleapis.com/instance/cpu/utilization).

Cette requête récupère la série temporelle écrite par les instances Compute Engine pour le type de métrique compute.googleapis.com/instance/cpu/utilization, enregistre l'utilisation du processeur par ces instances.

Si vous exécutez la requête à partir de l'éditeur de code dans l'Explorateur de métriques, vous obtenez un graphique illustrant chacune des séries temporelles demandées:

Le graphique montre les données d'utilisation du processeur pour les instances Compute Engine.

Chacune des séries temporelles demandées est affichée sous forme de ligne dans le graphique. Chaque série temporelle inclut une liste de valeurs horodatées issues de la métrique d'utilisation du processeur pour une instance de VM de ce projet.

Dans l'espace de stockage backend utilisé par Cloud Monitoring, les séries temporelles sont stockées tableaux. L'opération fetch organise la série temporelle pour l'élément spécifié de ressources surveillées et de métriques dans une table, puis renvoie la table. Les données renvoyées sont affichées dans le graphique.

L'opération fetch est décrite, ainsi que ses arguments, sur la page de référence sur fetch. Pour en savoir plus sur les données générées par les opérations, consultez les pages de référence sur les séries temporelles et les tables.

Filtrer les opérations

Les requêtes consistent généralement en une combinaison de plusieurs opérations. La combinaison la plus simple consiste à canaliser la sortie d'une opération vers l'entrée de la suivante en utilisant l'opérateur de barre verticale, |. L'exemple suivant illustre l'utilisation d'une barre verticale pour fournir en entrée la table dans une opération de filtrage :

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

Cette requête canalise la table, renvoyée par l'opération fetch indiquée dans le l'exemple précédent, en une opération filter qui accepte en tant qu'expression qui renvoie une valeur booléenne. Dans cet exemple, l'expression signifie "instance_name commence par gke".

L'opération filter prend la table d'entrée, supprime les séries temporelles pour laquelle le filtre est faux et génère la table obtenue. La capture d'écran suivante montre le graphique obtenu :

Le graphique affiche les résultats filtrés pour "gke".

Si aucun nom d'instance ne commence par gke, modifiez le filtre avant d'essayer cette requête. Par exemple, si vous avez des instances de VM comportant apache au début de leur nom, utilisez le filtre suivant :

 | filter instance_name =~ 'apache.*'

L'expression filter est évaluée une fois pour chaque série temporelle d'entrée. Si l'expression renvoie true, cette série temporelle est incluse dans la sortie. Dans cet exemple, l'expression de filtre procède à une mise en correspondance d'expression régulière, =~, sur le libellé instance_name de chaque série temporelle. Si la valeur du libellé correspond à l'expression régulière 'gke.*', la série temporelle est incluse dans la sortie. Dans le cas contraire, elle est supprimée de la sortie.

Pour plus d'informations sur le filtrage, consultez la page de référence sur filter. Le prédicat filter peut être n'importe quelle expression arbitraire qui renvoie une valeur booléenne. Pour en savoir plus, consultez la section Expressions.

Regrouper et agréger

Les groupes vous permettent de regrouper des séries temporelles en fonction de dimensions spécifiques. L'agrégation combine toutes les séries temporelles d'un groupe en une seule série temporelle de sortie.

La requête suivante filtre la sortie de l'opération fetch initiale pour ne conserver que les séries temporelles des ressources d'une zone commençant par us-central. Elle regroupe ensuite les séries temporelles par zone et les combine à l'aide de l'agrégation mean.

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

La table résultant de l'opération group_by comporte une série temporelle par zone. La capture d'écran suivante montre le graphique obtenu :

Graphique présentant une extraction filtrée regroupée par zone.

L'opération group_by prend deux arguments, séparés par une virgule (,). Ces arguments déterminent le comportement de regroupement précis. Dans cet exemple, group_by [zone], mean(val()), les arguments fonctionnent comme suit :

  • Le premier argument, [zone], est une expression de mappage qui détermine la des séries temporelles. Dans cet exemple, elle spécifie les étiquettes pour le regroupement. L'étape de regroupement collecte toutes les séries temporelles ont les mêmes valeurs zone de sortie dans un seul groupe. Dans cet exemple, collecte les séries temporelles à partir des VM Compute Engine une zone.

    La série temporelle de sortie ne comporte qu'une étiquette zone, la valeur étant copiée depuis la série temporelle d'entrée dans le groupe. Les autres libellés des séries temporelles d'entrée sont supprimés de la série temporelle de sortie.

    L'expression de mappage peut faire bien plus que de répertorier des libellés. Pour en savoir plus, consultez la page de référence sur map.

  • Le deuxième argument, mean(val()), détermine la façon dont les séries temporelles sont combinés, ou aggregated, en une seule série temporelle de sortie. Chaque dans la série temporelle de sortie d'un groupe est le résultat de l'agrégation les points ayant le même horodatage de toutes les séries temporelles d'entrée dans le groupe.

    Dans cet exemple, la fonction d'agrégation mean détermine la valeur agrégée. La fonction val() renvoie les points la fonction d'agrégation est appliquée à ces points. Dans cet exemple, vous obtenez la moyenne de l'utilisation du processeur des machines virtuelles de la zone à chaque point de sortie.

    L'expression mean(val()) est un exemple d'expression d'agrégation.

L'opération group_by combine toujours regroupement et agrégation. Si vous spécifiez un regroupement, mais omettez l'argument d'agrégation, group_by utilise une agrégation par défaut, aggregate(val()), qui sélectionne une fonction appropriée pour le type de données. Consultez la section sur aggregate pour obtenir la liste des fonctions d'agrégation par défaut.

Utiliser group_by avec une métrique basée sur les journaux

Supposons que vous ayez créé une métrique de distribution basée sur les journaux pour extraire le nombre de points de données traités à partir d'un ensemble d'entrées longues comprenant des chaînes telles que suivantes:

... 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 ...

Pour créer une série temporelle affichant le nombre total de points de données traités, utilisez un MQL comme celui-ci:

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

Pour créer une métrique de distribution basée sur les journaux, consultez Configurer des métriques de distribution.

Exclure des colonnes d'un groupe

Vous pouvez utiliser le modificateur drop dans un mappage pour exclure les colonnes d'une groupe. Par exemple, la métrique Kubernetes core_usage_time comporte six colonnes:

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

Si vous n'avez pas besoin de regrouper pod_name, vous pouvez l'exclure avec drop:

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

Sélectionner une série temporelle

Les exemples de cette section montrent comment sélectionner des séries temporelles spécifiques dans une table d'entrée.

Sélectionner la série temporelle supérieure ou inférieure

Pour afficher les données de séries temporelles des trois instances Compute Engine présentant le niveau le plus élevé d'utilisation du processeur dans votre projet, saisissez la requête suivante :

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

La capture d'écran suivante montre le résultat pour un projet :

Le graphique montre les trois séries temporelles présentant le niveau le plus élevé d'utilisation.

Vous pouvez récupérer les séries temporelles présentant le niveau le plus faible d'utilisation du processeur en remplaçant top par bottom.

L'opération top génère une table avec un nombre spécifié de séries temporelles sélectionnées dans sa table d'entrée. Les séries temporelles incluses dans la sortie a la plus grande valeur pour un aspect des séries temporelles.

Comme cette requête ne spécifie pas de moyen d'ordonner les séries temporelles, il renvoie les séries temporelles avec la valeur la plus élevée pour le point le plus récent. Pour spécifier comment déterminer les séries temporelles ayant la valeur la plus élevée, vous peut fournir un argument à l'opération top. Par exemple, précédente est équivalente à la requête suivante:

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

L'expression val() sélectionne la valeur du point le plus récent dans chaque à la série temporelle à laquelle elle est appliquée. La requête renvoie donc les séries temporelles avec la valeur la plus élevée pour le point le plus récent.

Vous pouvez fournir une expression qui effectue une agrégation sur tout ou partie des points d'une série temporelle pour indiquer la valeur de tri. La valeur suivante prend la moyenne de tous les points des 10 dernières minutes :

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

Si la fonction within n'est pas utilisée, la fonction mean est appliquée aux valeurs de tous les points affichés dans les séries temporelles.

L'opération bottom fonctionne d'une manière semblable. La requête suivante recherche la valeur du plus grand point de chaque série temporelle avec max(val()), puis sélectionne les trois séries temporelles pour lesquelles cette valeur est la plus faible :

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

La capture d'écran suivante montre un graphique affichant les flux avec les plus petits pics:

Le graphique montre les trois séries temporelles présentant le niveau le plus élevé d'utilisation.

Exclure les n résultats supérieurs ou inférieurs de la série temporelle

Prenons l'exemple d'un scénario dans lequel vous disposez de plusieurs instances de VM Compute Engine. Certaines de ces instances consomment beaucoup plus de mémoire que la plupart des instances, Ces anomalies rendent plus difficiles la compréhension des schémas d'utilisation groupe plus important. Vos graphiques d'utilisation du processeur se présentent comme suit:

Le graphique montre de nombreuses lignes d'utilisation du processeur, avec plusieurs anomalies.

Vous voulez exclure ces trois valeurs aberrantes du graphique afin de voir les modèles dans le groupe plus large plus clairement.

Pour exclure les trois premières séries temporelles d'une requête qui les récupère Pour l'utilisation du processeur Compute Engine, utilisez l'opération de table top. pour identifier la série temporelle et l'opération de table outer_join pour exclure la série temporelle identifiée des résultats. Vous pouvez utiliser la requête suivante:

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'opération fetch renvoie une table de séries temporelles pour l'utilisation du processeur toutes les instances. Cette table est ensuite traitée en deux tables générées:

  • L'opération de table top n génère une table qui contient l'heure n série avec les valeurs les plus élevées. Dans ce cas, n = 3. Le résultat Le tableau contient les trois séries temporelles à exclure.

    Le tableau contenant les trois premières séries temporelles est ensuite redirigé vers Opération de table value. Cette opération ajoute une colonne à chacune des séries temporelles du tableau. Cette colonne, is_default_value reçoit la valeur booléenne false pour toutes les séries temporelles dans le tableau des trois premiers.

  • L'opération ident renvoie la même table qui y est redirigée: le tableau d'origine des séries temporelles d'utilisation du processeur. Rien du temps de ce tableau contiennent la colonne is_default_value.

Les trois tableaux du haut et le tableau d'origine sont ensuite redirigés Opération de table outer_join. Les trois tableaux du haut est celui de gauche dans la jointure, la table récupérée est la table de droite dans la jointure. La jointure externe est configurée pour fournir la valeur true comme valeur pour tout champ qui n'existe pas dans une ligne en cours de jointure. Le résultat de la la jointure externe est une table fusionnée, où les lignes des trois tables supérieures conservent la colonne is_default_value avec la valeur false, et toutes les lignes de à la table d'origine qui ne figuraient pas également dans les trois premières tables, Colonne is_default_value avec la valeur true.

La table résultant de la jointure est ensuite transmise au filter opération "table", qui filtre les lignes ayant une la valeur de false dans la colonne is_default_value. La table obtenue contient les lignes de la table initialement récupérée, sans les lignes du tableau des trois premiers. Ce tableau contient l'ensemble de séries temporelles prévu, avec le is_default_column ajouté.

La dernière étape consiste à supprimer la colonne is_default_column qui a été ajoutée par la jointure. Ainsi, la table de sortie contient les mêmes colonnes que celles extraites à l'origine. tableau.

La capture d'écran suivante montre le graphique de la requête précédente:

Le graphique montre de nombreuses lignes d'utilisation du processeur, sans les anomalies.

Vous pouvez créer une requête pour exclure la série temporelle présentant la latence la plus faible Utilisation du processeur en remplaçant top n par bottom n.

La possibilité d'exclure les anomalies peut être utile lorsque vous souhaitez définir une alerte, mais que vous ne voulez pas que les valeurs aberrantes déclenchent constamment l'alerte. La requête d'alerte suivante utilise la même logique d'exclusion que la précédente pour surveiller l'utilisation de la limite de processeur par un ensemble de pods Kubernetes après avoir exclu les deux premiers pods:

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'

Sélectionner le haut ou le bas des groupes

Les opérations de table top et bottom sélectionnent des séries temporelles dans l'ensemble de la table d'entrée. Les opérations top_by et bottom_by regroupent les séries temporelles d'une table, puis choisissent un certain nombre de séries temporelles dans chaque groupe.

La requête suivante sélectionne dans chaque zone la série temporelle ayant la plus haute valeur maximale :

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

Le graphique montre la valeur maximale la plus haute par zone.

L'expression [zone] indique qu'un groupe est composé des éléments suivants : la série temporelle avec la même valeur de la colonne zone. La valeur 1 dans top_by indique le nombre de séries temporelles à sélectionner dans le groupe de chaque zone. L'expression max(val()) recherche la plus grande valeur de la période du graphique dans chaque série temporelle.

Vous pouvez utiliser n'importe quelle fonction d'agrégation à la place de max. Dans l'exemple suivant, l'agrégateur mean et within sont utilisés pour spécifier la plage de tri de 20 minutes. Les deux premières séries temporelles de chaque zone sont sélectionnées :

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

Le graphique montre les deux pics moyens les plus élevés dans une plage de 20 minutes.

Dans l'exemple précédent, il n'y a qu'une seule instance dans la zone us-central-c, Une seule série temporelle est donc renvoyée. il n'y a pas de "top 2" dans le groupe.

Combiner les sélections avec union

Vous pouvez combiner des opérations de sélection telles que top et bottom pour créer des graphiques qui affichent les deux. Par exemple, la requête suivante renvoie la série temporelle unique présentant la valeur maximale et la série temporelle unique présentant la valeur minimale :

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

Le graphique obtenu affiche deux lignes, l'une contenant la valeur la plus élevée et l'autre contenant la plus basse :

Le graphique montre les séries temporelles présentant les valeurs les plus élevées et les plus faibles.

Vous pouvez utiliser des accolades ({ }) pour spécifier des séquences d'opérations, chacune produisant une table de séries temporelles en sortie. Les opérations individuelles sont séparées à l'aide d'un point-virgule (;).

Dans cet exemple, l'opération fetch renvoie une seule table, qui est canalisée vers chacune des deux opérations de la séquence, une opération top et une opération bottom. Chacune de ces opérations génère une table de sortie basée sur la même table d'entrée. L'opération union combine ensuite les deux tables en une seule, qui s'affiche sur le graphique.

Pour en savoir plus sur le séquençage des opérations, utilisez { } dans la documentation de référence. sur la page Structure des requêtes.

Combiner des séries temporelles associées à différentes valeurs pour une étiquette

Supposons que vous ayez plusieurs séries temporelles pour le même type de métrique et que vous devez en combiner quelques-uns. Si vous souhaitez les sélectionner, en fonction des valeurs d'une seule étiquette, vous ne pouvez pas créer la requête à l'aide de l'interface du générateur de requêtes dans l'Explorateur de métriques. Vous devez filtrer sur au moins deux valeurs différentes du même libellé, mais le générateur de requêtes interface requiert qu'une série temporelle corresponde à tous les filtres sélectionnés: la correspondance des étiquettes est un test AND. Aucune série temporelle ne peut avoir deux pour le même libellé, mais vous ne pouvez pas créer de test OR pour les filtres dans le générateur de requêtes.

La requête suivante récupère les séries temporelles pour l'instance Compute Engine instance/disk/max_read_ops_count pour deux instances Compute Engine instances et aligne la sortie sur des intervalles d'une minute:

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

Le graphique suivant montre le résultat de cette requête:

Le graphique montre deux séries temporelles sélectionnées selon la valeur du même libellé.

Si vous souhaitez trouver la somme des valeurs max_read_ops_count maximales de ces deux VM et les additionner, vous pouvez effectuer les opérations suivantes:

  • Trouver la valeur maximale pour chaque série temporelle à l'aide des Opérateur de table group_by, spécifiant la même durée d'une minute période d'alignement et en agrégeant les données sur la période avec l'agrégateur max pour créer une colonne nommée max_val_of_read_ops_count_max dans la sortie tableau.
  • Trouver la somme des séries temporelles à l'aide de l'opérateur de table group_by l'agrégateur sum sur la colonne max_val_of_read_ops_count_max.

Voici la requête:

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

Le graphique suivant montre le résultat de cette requête:

Le graphique indique la somme de deux séries temporelles sélectionnées par valeur du même libellé.

Calculez les statistiques de centiles au fil du temps et entre les flux.

À calculer une valeur de flux au centile sur une fenêtre glissante séparément pour chaque utilisez une opération temporelle group_by. Par exemple : La requête calcule la valeur du 99e centile d'un flux sur une période d'une heure période:

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

Pour calculer la même statistique de centile à un moment précis sur plusieurs flux, plutôt que sur plusieurs périodes au sein d'un même flux, utilisez une opération spatiale group_by:

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

Calculer les ratios

Supposons que vous ayez créé un service Web distribué qui s'exécute sur des instances de VM Compute Engine et utilise Cloud Load Balancing.

Vous souhaitez afficher un graphique indiquant le ratio entre les requêtes qui renvoient des réponses HTTP 500 (erreurs internes) et le nombre total de requêtes, c'est-à-dire le ratio requêtes/échecs. Cette section illustre plusieurs façons de calculer ce ratio.

Cloud Load Balancing utilise le type de ressource surveillée http_lb_rule. Le type de ressource surveillée http_lb_rule possède un libellé matched_url_path_rule qui enregistre le préfixe des URL définies dans la règle. La valeur par défaut est UNMATCHED.

Le type de métrique loadbalancing.googleapis.com/https/request_count comporte un libellé response_code_class. Ce libellé capture la classe des codes de réponse.

Utiliser outer_join et div

La requête suivante détermine les réponses 500 pour chaque valeur du libellé matched_url_path_rule dans chaque ressource surveillée http_lb_rule de votre projet. Elle joint ensuite cette table de comptage des échecs à la table d'origine, qui contient tous les décomptes de réponses et divise les valeurs pour afficher le ratio entre les réponses d'échec et le nombre total de réponses :

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

Le graphique suivant montre le résultat pour un projet :

Le graphique montre le ratio entre les réponses d'échec et le nombre total de réponses obtenu par jointure.

Les parties ombrées autour des lignes du graphique sont des bandes minimales/maximales. Pour en savoir plus, consultez la section Bandes minimales/maximales.

L'opération fetch génère une table de séries temporelles contenant les décomptes de requêtes pour toutes les requêtes à équilibrage de charge. Cette table est traitée de deux manières par les deux séquences d'opérations entre accolades :

  • filter response_code_class = 500 ne renvoie que les séries temporelles associées au libellé response_code_class avec la valeur 500. La série temporelle obtenue comptabilise les requêtes avec des codes de réponse HTTP 5xx (erreur).

    Cette table est le numérateur du ratio.

  • L'opération ident, ou identité, génère son entrée, donc cette opération renvoie la table récupérée à l'origine. C’est la table qui contient des séries temporelles avec le nombre de chaque code de réponse.

    Cette table est le dénominateur du ratio.

Les tables de numérateur et de dénominateur, générées respectivement par les opérations filter et ident, sont traitées séparément par l'opération group_by. L'opération group_by regroupe les séries temporelles de chaque table en fonction de la valeur du libellé matched_url_path_rule et additionne les décomptes pour chaque valeur du libellé. Cette opération group_by n'indique pas explicitement la fonction d'agrégateur. Une valeur par défaut, sum, est utilisée.

  • Pour la table filtrée, le résultat group_by correspond au nombre de requêtes renvoyant une réponse 500 pour chaque valeur matched_url_path_rule.

  • Pour la table d'identité, le résultat group_by est le nombre total de pour chaque valeur matched_url_path_rule.

Ces tables sont canalisées vers l'opération outer_join, qui associe les séries temporelles aux valeurs de libellé correspondantes, une dans chacune des deux tables d'entrée. Les séries temporelles associées sont compressées en faisant correspondre l'horodatage de chaque point d'une série temporelle à celui d'un point de l'autre série temporelle. Pour chaque paire de points mis en correspondance, outer_join génère un seul point de sortie avec deux valeurs, provenant de chacune des tables d'entrée. La série temporelle compressée est générée par la jointure avec les mêmes libellés que les deux séries temporelles d'entrée.

Avec une jointure externe, si un point de la deuxième table ne possède pas point de correspondance dans le premier, une valeur de remplacement doit être fournie. Dans cet exemple, un point avec la valeur 0 (argument de l'opération outer_join) est utilisé.

Enfin, l'opération div prend chaque point avec deux valeurs et divise les valeurs pour générer un seul point de sortie : il s'agit du ratio entre les réponses 500 et toutes les réponses pour chaque mappage d'URL.

La chaîne div ici est en fait le nom de la fonction div, qui divise deux valeurs numériques. Cependant, elle est utilisée ici comme opération. Lorsqu'elles sont utilisées en tant qu'opérations, les fonctions telles que div attendent deux valeurs dans chaque point d'entrée (ce que garantit join) et génèrent une seule valeur pour le point de sortie correspondant.

La partie | div de la requête est un raccourci pour | value val(0) / val(1). L'opération value permet à des expressions arbitraires sur les colonnes de valeur d'une table d'entrée de générer les colonnes de valeur de la table de sortie. Pour plus d'informations, consultez les pages de référence sur l'opération value et les expressions.

Utiliser ratio

La fonction div peut être remplacée par n'importe quelle fonction sur deux valeurs. Toutefois, comme les ratios sont fréquemment utilisés, la langage MQL fournit une opération de table ratio qui les calcule directement.

La requête ci-dessous équivaut à la version précédente, utilisant outer_join et div :

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

Dans cette version, l'opération ratio remplace les opérations outer_join 0 | div de la version précédente et génère le même résultat.

Notez que ratio n'utilise outer_join que pour fournir un 0 pour le numérateur si les entrées du numérateur et du dénominateur ont les mêmes étiquettes identifiant chaque série temporelle, ce qui est requis par MQL outer_join. Si l'entrée du numérateur comporte des étiquettes supplémentaires, il n'y aura aucun résultat pour les points manquants dans dénominateur.

Utiliser group_by et /

Il existe une autre façon de calculer le ratio entre les réponses d'erreur et le nombre total de réponses. Dans ce cas, comme le numérateur et le dénominateur du ratio sont dérivés de la même série temporelle, vous pouvez également calculer le ratio en effectuant uniquement un regroupement. La requête suivante illustre cette approche :

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

Cette requête utilise une expression d'agrégation basée sur le ratio de deux sommes :

  • La première somme (sum) utilise la fonction if pour comptabiliser les libellés ayant la valeur 500 et 0 pour les autres. La fonction sum calcule le nombre de requêtes ayant renvoyé 500.

  • La seconde somme (sum) additionne les décomptes de toutes les requêtes, val().

Les deux sommes sont ensuite divisées, ce qui donne le ratio entre le nombre de réponses 500 et le nombre total de réponses. Cette requête génère le même résultat que les requêtes figurant dans les sections Utiliser outer_join et div et Utiliser ratio.

Utiliser filter_ratio_by

Comme les ratios sont souvent calculés en divisant deux sommes dérivées de la même table, le langage MQL fournit l'opération filter_ratio_by à cet effet. La requête suivante effectue la même opération que la version précédente, qui divise explicitement les sommes :

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

Ici, le premier opérande de l'opération filter_ratio_by. [matched_url_path_rule] indique comment regrouper les réponses. La seconde opération, ici response_code_class = 500, agit comme une expression de filtrage pour le numérateur.

  • La table de dénominateur est le résultat du regroupement de la table extraite par matched_url_path_rule et agrégée à l'aide de sum.
  • La table de numérateur est la table extraite, filtrée pour les séries temporelles ayant le code de réponse HTTP 5xx, puis regroupée par matched_url_path_rule et agrégée à l'aide de sum.

Ratios et métriques de quotas

Configurer des requêtes et des alertes sur le quota serviceruntime des métriques et des métriques de quota spécifiques aux ressources pour surveiller la consommation de quotas, vous pouvez utiliser MQL. Pour en savoir plus et obtenir des exemples, consultez la page Utiliser des métriques de quota.

Calcul arithmétique

Parfois, vous voudrez peut-être effectuer une opération arithmétique sur les données avant de le représenter dans le graphique. Par exemple, vous pouvez effectuer le scaling de séries temporelles, convertir les données en échelle logarithmique ou représenter graphiquement la somme de deux séries temporelles. Pour une liste des fonctions arithmétiques disponibles dans MQL, consultez la page Arithmétique.

Pour effectuer le scaling d'une série temporelle, utilisez la fonction mul. Par exemple, La requête suivante récupère la série temporelle, puis multiplie chaque valeur par 10:

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

Pour additionner deux séries temporelles, configurez votre requête de façon à extraire deux tables de séries temporelles : joindre ces résultats, puis appeler la fonction add. Les éléments suivants : Cet exemple illustre une requête qui calcule la somme du nombre d'octets lus et écrites dans des instances 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

Pour soustraire le nombre d'octets écrits du nombre d'octets lus, remplacez add par sub dans l'expression précédente.

MQL utilise les étiquettes des ensembles de tables renvoyés par puis une seconde extraction pour déterminer comment joindre les tables:

  • Si la première table contient une étiquette introuvable dans le deuxième tableau, alors MQL ne peut pas effectuer d'opération outer_join sur la tables, et donc signale une erreur. Par exemple, la requête suivante génère une erreur, car le Le libellé metric.instance_name est présent dans la première table, mais pas dans le deuxième tableau:

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

    Une façon de résoudre ce type d'erreur consiste à appliquer des clauses de regroupement les deux tables ont les mêmes étiquettes. Par exemple, vous pouvez regrouper étiquettes de séries temporelles:

     fetch gce_instance
      | { metric 'compute.googleapis.com/instance/disk/write_bytes_count'
          | group_by []
        ; metric 'compute.googleapis.com/instance/disk/max_write_bytes_count'
          | group_by [] }
      | outer_join 0
      | add
    
  • Si les étiquettes des deux tableaux correspondent, ou si la deuxième table contient un étiquette introuvable dans la première table, la jointure externe est autorisée. Pour exemple, la requête suivante ne provoque pas d'erreur même si le Le libellé metric.instance_name est présent dans la deuxième table, mais pas dans le en premier:

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

    Une série temporelle trouvée dans la première table peut avoir des valeurs de libellé qui correspondent plusieurs séries temporelles dans le deuxième tableau. MQL effectue l'opération de soustraction pour chaque paire.

Décalage temporel

Parfois, vous souhaitez comparer ce qui se passe actuellement et ce qui est survenu dans le passé. Pour vous permettre de comparer des données antérieures aux données actuelles, MQL fournit une opération de table time_shift pour déplacer les données du passé vers la période actuelle.

Ratios au fil du temps

La requête suivante utilise time_shift, join et div pour calculer le ratio de l'utilisation moyenne dans chaque entre la période actuelle et une semaine auparavant.

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

Le graphique suivant montre un résultat possible de cette requête :

Le graphique montre le ratio des données actuelles et décalées dans le temps.

Les deux premières opérations récupèrent la série temporelle, puis regroupent par zone, en calculant leurs valeurs moyennes. La table obtenue est ensuite transmise à deux opérations. La première opération, ident, transmet la table sans la modifier.

La seconde opération, time_shift, ajoute la période (1 semaine) aux horodatages des valeurs dans la table, ce qui décale les données d'une semaine en avant. Cette modification rend les horodatages des données plus anciennes dans la deuxième table s'alignent avec les horodatages des données actuelles dans le premier tableau.

La table non modifiée et la table décalée dans le temps sont ensuite combinées à l'aide d'une opération join interne. L'opération join génère une table de séries temporelles où chaque point a deux valeurs : l'utilisation actuelle et l'utilisation une semaine auparavant. La requête utilise ensuite l'opération div pour calculer le ratio entre la valeur actuelle et la valeur de la semaine passée.

Données passées et présentes

En combinant time_shift avec union, vous pouvez créer un graphique qui affiche simultanément les données passées et présentes. Par exemple, la requête suivante renvoie l'utilisation moyenne globale pour la période actuelle et pour la semaine précédente. À l'aide de union, vous pouvez afficher ces deux résultats sur le même graphique.

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

Le graphique suivant montre un résultat possible de cette requête :

Le graphique indique l'utilisation moyenne actuelle et passée.

Cette requête extrait la série temporelle, puis utilise group_by [] pour les combiner en une seule série temporelle sans étiquette, laissant Points de données d'utilisation du processeur Ce résultat est transmis à deux opérations. La première ajoute une colonne pour un nouveau libellé appelé when avec la valeur now. La seconde ajoute un libellé appelé when avec la valeur then et transmet le résultat à l'opération time_shift pour décaler les valeurs d'une semaine. Cette requête utilise le modificateur de mappage add. Pour en savoir plus, consultez la section Mappages.

Les deux tables, chacune contenant des données pour une seule série temporelle, sont transmises à union, qui génère une table contenant les séries temporelles des deux tables d'entrée.

Étape suivante

Pour obtenir une présentation des structures du langage MQL, consultez la page À propos du langage MQL.

Pour obtenir une description complète du langage MQL, consultez la documentation de référence sur le langage MQL.

Pour en savoir plus sur l'interaction avec les graphiques, consultez Travailler avec des graphiques.