Exemples de requêtes SQL

Ce document contient des exemples de requêtes sur des entrées de journal stockées dans des buckets de journaux mis à niveau pour utiliser l'analyse de journaux. Vous pouvez exécuter des requêtes SQL sur ces buckets à partir de la page Analyse de journaux de la console Google Cloud . Pour obtenir d'autres exemples, consultez les dépôts GitHub logging-analytics-samples et security-analytics.

Ce document ne décrit pas SQL ni comment acheminer et stocker les entrées de journal. Pour en savoir plus sur ces sujets, consultez la section Étapes suivantes.

Avant de commencer

Cette section décrit les étapes à suivre avant de pouvoir utiliser Log Analytics.

Configurer des buckets de journaux

Assurez-vous que vos buckets de journaux ont été mis à niveau pour utiliser l'Analyse de journaux :

  1. Dans la console Google Cloud , accédez à la page Stockage des journaux :

    Accéder à la page Stockage des journaux

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

  2. Pour chaque bucket de journaux comportant une vue de journaux que vous souhaitez interroger, assurez-vous que la colonne Log Analytics disponible affiche Ouvrir. Si l'option Mettre à niveau s'affiche, cliquez dessus et remplissez la boîte de dialogue.

Configurer les rôles et autorisations IAM

Cette section décrit les rôles ou autorisations IAM requis pour utiliser Log Analytics :

  • Pour obtenir les autorisations nécessaires pour utiliser Log Analytics et interroger les vues de journaux, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

    Vous pouvez limiter une entité principale à une vue de journaux spécifique en ajoutant une condition IAM à l'attribution du rôle "Accesseur de vues de journaux" effectuée au niveau du projet, ou en ajoutant une liaison IAM au fichier de stratégie de la vue de journaux. Pour en savoir plus, consultez Contrôler l'accès à une vue de journal.

    Il s'agit des mêmes autorisations que celles dont vous avez besoin pour afficher les entrées de journal sur la page Explorateur de journaux. Pour en savoir plus sur les rôles supplémentaires dont vous avez besoin pour interroger les vues sur les buckets définis par l'utilisateur ou pour interroger la vue _AllLogs du bucket de journaux _Default, consultez Rôles Cloud Logging.

  • Pour obtenir les autorisations nécessaires pour interroger les vues d'analyse, demandez à votre administrateur de vous attribuer le rôle IAM Utilisateur Observability Analytics (roles/observability.analyticsUser) sur votre projet.

Comment utiliser ces requêtes

Pour utiliser les requêtes présentées dans ce document sur la page Analyse de journaux, remplacez TABLE_NAME_OF_LOG_VIEW par le nom de la table correspondant à la vue de journaux ou à la vue analytique que vous souhaitez interroger.

  • Pour interroger une vue de journaux, dans la clause FROM, utilisez le format suivant :

    FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
    
  • Pour interroger une vue Analytics, dans la clause FROM, utilisez le format suivant :

    FROM `analytics_view.PROJECT_ID.LOCATION.ANALYTICS_VIEW_ID`
    

Voici la signification des champs dans les expressions précédentes :

  • PROJECT_ID : identifiant du projet.
  • LOCATION : emplacement de la vue des journaux ou de la vue des données analytiques.
  • BUCKET_ID : nom ou ID du bucket de journaux.
  • LOG_VIEW_ID : identifiant de la vue de journal, limité à 100 caractères et ne pouvant inclure que des lettres, des chiffres, des traits de soulignement et des traits d'union.
  • ANALYTICS_VIEW_ID : ID de la vue Analytics, limité à 100 caractères et ne pouvant inclure que des lettres, des chiffres, des traits de soulignement et des traits d'union.

Si vous avez créé un ensemble de données BigQuery associé, vous pouvez l'interroger depuis la page BigQuery Studio. Sur cette page, remplacez TABLE_NAME_OF_LOG_VIEW par le chemin d'accès à la table dans l'ensemble de données associé. Par exemple, pour interroger la vue _AllLogs sur l'ensemble de données associé mydataset qui se trouve dans le projet myproject, définissez ce champ sur myproject.mydataset._AllLogs.

Accédez à la page Analyse de journaux.

Pour ouvrir la page Analyse de journaux :

  1. Dans la console Google Cloud , accédez à la page Analyse de journaux :

    Accéder à l'Analyse de journaux

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

  2. Pour identifier les vues de journaux et les vues analytiques, accédez au volet Vues.

    Les vues de journaux sont listées dans la section Journaux, et les vues d'analyse sont listées dans la section Vues d'analyse.

  3. Facultatif : Pour identifier le schéma d'une vue de journal ou d'une vue analytique, sélectionnez la vue de journal ou la vue analytique.

    Le schéma s'affiche. Vous pouvez utiliser le champ Filtre pour localiser des champs spécifiques. Vous ne pouvez pas modifier le schéma.

Pour savoir comment accéder à la requête par défaut d'un élément listé dans le volet Vues, consultez Interroger et analyser les journaux avec l'analyse des journaux.

Filtrer les journaux

Les requêtes SQL déterminent les entrées à traiter dans la vue du journal, puis elles regroupent ces entrées et effectuent des opérations d'agrégation. Lorsqu'aucune opération de regroupement et d'agrégation n'est listée, le résultat de la requête inclut les lignes sélectionnées par l'opération de filtrage. Les exemples de cette section illustrent le filtrage.

Filtrer par heure

Pour définir la période de votre requête, nous vous recommandons d'utiliser le sélecteur de période. Ce sélecteur est utilisé automatiquement lorsqu'une requête ne spécifie pas de champ timestamp dans la clause WHERE. Par exemple, pour afficher les données de la semaine dernière, sélectionnez Les 7 derniers jours dans le sélecteur de période. Vous pouvez également utiliser le sélecteur de période pour spécifier une heure de début et de fin, une heure à afficher et changer de fuseau horaire.

Si vous incluez un champ timestamp dans la clause WHERE, le paramètre du sélecteur de période n'est pas utilisé. L'exemple suivant filtre les données à l'aide de la fonction TIMESTAMP_SUB, qui vous permet de spécifier un intervalle de rétrospection à partir de l'heure actuelle :

WHERE
  timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Pour savoir comment filtrer par heure, consultez les sections Fonctions temporelles et Fonctions d'horodatage.

Filtrer par ressource

Pour filtrer par ressource, ajoutez une restriction resource.type.

Par exemple, la requête suivante lit les données de la dernière heure, puis conserve les lignes dont le type de ressource correspond à gce_instance, puis trie et affiche jusqu'à 100 entrées :

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  resource.type = "gce_instance"
ORDER BY timestamp ASC
LIMIT 100

Filtrer par gravité

Vous pouvez filtrer par niveau de gravité spécifique avec une restriction telle que severity = 'ERROR'. Vous pouvez également utiliser l'instruction IN et spécifier un ensemble de valeurs valides.

Par exemple, la requête suivante lit les données de la dernière heure, puis ne conserve que les lignes contenant un champ severity dont la valeur est 'INFO' ou 'ERROR' :

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  severity IS NOT NULL AND
  severity IN ('INFO', 'ERROR')
ORDER BY timestamp ASC
LIMIT 100

La requête précédente filtre les résultats en fonction de la valeur du champ severity. Toutefois, vous pouvez également écrire des requêtes qui filtrent les journaux en fonction de la valeur numérique de leur gravité. Par exemple, si vous remplacez les lignes severity par les lignes suivantes, la requête renvoie toutes les entrées de journal dont le niveau de gravité est au moins NOTICE :

  severity_number IS NOT NULL AND
  severity_number > 200

Pour en savoir plus sur les valeurs énumérées, consultez LogSeverity.

Filtrer par nom de journal

Pour filtrer par nom de journal, vous pouvez ajouter une restriction sur la valeur du champ log_name ou log_id. Le champ log_name inclut le chemin d'accès à la ressource. Autrement dit, ce champ contient des valeurs telles que projects/myproject/logs/mylog. Le champ log_id ne stocke que le nom du journal, tel que mylog.

Par exemple, la requête suivante lit l'heure de données la plus récente, puis conserve les lignes où la valeur du champ log_id est cloudaudit.googleapis.com/data_access, puis trie et affiche les résultats :

SELECT
  timestamp, log_id, severity, json_payload, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  log_id = "cloudaudit.googleapis.com/data_access"
ORDER BY timestamp ASC
LIMIT 100

Filtrer par libellé de ressource

La plupart des descripteurs de ressources surveillées définissent des libellés permettant d'identifier la ressource spécifique. Par exemple, le descripteur d'une instance Compute Engine inclut des libellés pour la zone, l'ID de projet et l'ID d'instance. Lorsque l'entrée de journal est écrite, des valeurs sont attribuées à chaque champ. Voici un exemple :

{
   type: "gce_instance"
   labels: {
      instance_id: "1234512345123451"
      project_id: "my-project"
      zone: "us-central1-f"
   }
}

Étant donné que le type de données du champ labels est JSON, l'inclusion d'une restriction telle que resource.labels.zone = "us-centra1-f" dans une requête entraîne une erreur de syntaxe. Pour obtenir la valeur d'un champ dont le type de données est JSON, utilisez la fonction JSON_VALUE.

Par exemple, la requête suivante lit les données les plus récentes, puis conserve les lignes où la ressource est une instance Compute Engine située dans la zone us-central1-f :

SELECT
  timestamp, log_name, severity, JSON_VALUE(resource.labels.zone) AS zone, json_payload, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  resource.type = "gce_instance" AND
  JSON_VALUE(resource.labels.zone) = "us-central1-f"
ORDER BY timestamp ASC
LIMIT 100

Pour en savoir plus sur toutes les fonctions permettant de récupérer et de transformer des données JSON, consultez Fonctions JSON.

Filtrer par requête HTTP

Pour filtrer la vue du journal afin de n'inclure que les entrées de journal correspondant à une requête ou une réponse HTTP, ajoutez une restriction http_request IS NOT NULL :

SELECT
  timestamp, log_name, severity, http_request, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  http_request IS NOT NULL
ORDER BY timestamp
LIMIT 100

La requête suivante n'inclut que les lignes correspondant aux requêtes GET ou POST :

SELECT
  timestamp, log_name, severity, http_request, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  http_request IS NOT NULL AND
  http_request.request_method IN ('GET', 'POST')
ORDER BY timestamp ASC
LIMIT 100

Filtrer par code d'état HTTP

Pour filtrer par code d'état HTTP, modifiez la clause WHERE afin d'exiger que le champ http_request.status soit défini :

SELECT
  timestamp, log_name, http_request.status, http_request, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  http_request IS NOT NULL AND
  http_request.status IS NOT NULL
ORDER BY timestamp ASC
LIMIT 100

Pour déterminer le type de données stockées dans un champ, consultez le schéma ou affichez le champ. Les résultats de la requête précédente montrent que le champ http_request.status stocke des valeurs entières.

Filtrer par un champ de type JSON

Pour extraire une valeur d'une colonne dont le type de données est JSON, utilisez la fonction JSON_VALUE.

Considérez les requêtes suivantes :

SELECT
  json_payload
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  json_payload.status IS NOT NULL

et

SELECT
  json_payload
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  JSON_VALUE(json_payload.status) IS NOT NULL

Les requêtes précédentes testent la valeur du champ json_payload dans l'entrée de journal. Les deux requêtes écartent les entrées de journal qui ne contiennent pas de champ intitulé json_payload. La différence entre ces deux requêtes réside dans la dernière ligne, qui définit ce qui est testé par rapport à NULL. Prenons l'exemple d'une vue de journal comportant deux entrées de journal. Pour une entrée de journal, le champ json_payload se présente comme suit :

{
    status: {
        measureTime: "1661517845"
    }
}

Pour l'autre entrée de journal, le champ json_payload a une structure différente :

{
    @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
    jobName: "projects/my-project/locations/us-central1/jobs/test1"
    relativeUrl: "/food=cake"
    status: "NOT_FOUND"
    targetType: "APP_ENGINE_HTTP"
}

Les deux entrées de journal précédentes respectent la restriction json_payload.status IS NOT NULL. Autrement dit, le résultat de la première requête inclut les deux entrées de journal. Toutefois, lorsque la restriction est JSON_VALUE(json_payload.status) IS NOT NULL, seule la deuxième entrée de journal est incluse dans le résultat de la requête.

Filtrer par expression régulière

Pour renvoyer la sous-chaîne qui correspond à une expression régulière, utilisez la fonction REGEXP_EXTRACT. Le type renvoyé de cette fonction est STRING ou BYTES.

La requête suivante affiche les entrées de journal les plus récentes reçues, conserve celles comportant un champ json_payload.jobName, puis affiche la partie du nom commençant par test :

SELECT
  timestamp, REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  json_payload.jobName IS NOT NULL
ORDER BY timestamp DESC
LIMIT 20

Pour obtenir d'autres exemples, consultez la documentation REGEXP_EXTRACT. Pour obtenir d'autres exemples d'expressions régulières que vous pouvez utiliser, consultez Fonctions, opérateurs et instructions conditionnelles.

La requête présentée dans cet exemple n'est pas efficace. Pour une correspondance de sous-chaîne, comme celle illustrée, utilisez la fonction CONTAINS_SUBSTR.

Regrouper et agréger les entrées de journaux

Cette section s'appuie sur les exemples précédents et explique comment regrouper et agréger les entrées de journal. Si vous ne spécifiez pas de regroupement, mais que vous spécifiez une agrégation, un seul résultat est imprimé, car SQL traite toutes les lignes qui satisfont la clause WHERE comme un seul groupe.

Chaque expression SELECT doit être incluse dans les champs de groupe ou être agrégée.

Regrouper par heure

Pour regrouper les données par heure, utilisez la fonction TIMESTAMP_TRUNC, qui tronque un code temporel selon une précision spécifiée, comme MINUTE. Par exemple, un code temporel 15:30:11, au format hours:minutes:seconds, devient 15:30:00 lorsque la précision est définie sur MINUTE.

La requête suivante lit les données reçues dans l'intervalle spécifié par le sélecteur de période, puis conserve les lignes où la valeur du champ json_payload.status n'est pas NULL. La requête tronque le code temporel de chaque ligne par heure, puis regroupe les lignes par code temporel tronqué et par état :

SELECT
  TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
  JSON_VALUE(json_payload.status) AS status,
  COUNT(*) AS count
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  json_payload IS NOT NULL AND
  JSON_VALUE(json_payload.status) IS NOT NULL
GROUP BY hour,status
ORDER BY hour ASC

Pour obtenir d'autres exemples, consultez la documentation TIMESTAMP_TRUNC. Pour en savoir plus sur les autres fonctions basées sur le temps, consultez Fonctions de date et heure.

Regrouper par ressource

La requête suivante lit les données de la dernière heure, puis regroupe les entrées de journal par type de ressource. Il comptabilise ensuite le nombre de lignes pour chaque type de ressource et renvoie un tableau à deux colonnes. La première colonne liste le type de ressource, tandis que la deuxième indique le nombre de lignes pour ce type de ressource :

SELECT
   resource.type, COUNT(*) AS count
FROM
  `TABLE_NAME_OF_LOG_VIEW`
GROUP BY resource.type
LIMIT 100

Regrouper par niveau de gravité

La requête suivante lit les données de la dernière heure, puis conserve les lignes comportant un champ de gravité. La requête regroupe ensuite les lignes par gravité et compte le nombre de lignes pour chaque groupe :

SELECT
  severity, COUNT(*) AS count
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  severity IS NOT NULL
GROUP BY severity
ORDER BY severity
LIMIT 100

Grouper par log_id

Le résultat de la requête suivante est une table comportant deux colonnes. La première colonne liste les noms des journaux et la deuxième colonne liste le nombre d'entrées de journal qui ont été écrites dans le journal. La requête trie les résultats par nombre d'entrées :

SELECT
  log_id, COUNT(*) AS count
FROM
  `TABLE_NAME_OF_LOG_VIEW`
GROUP BY log_id
ORDER BY count DESC
LIMIT 100

Calculer la latence moyenne des requêtes HTTP

La requête suivante illustre le regroupement par plusieurs colonnes et le calcul d'une valeur moyenne. La requête regroupe les lignes par URL contenue dans la requête HTTP et par valeur du champ labels.checker_location. Après avoir regroupé les lignes, la requête calcule la latence moyenne pour chaque groupe :

SELECT
  JSON_VALUE(labels.checker_location) AS location,
  AVG(http_request.latency.seconds) AS secs, http_request.request_url
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  http_request IS NOT NULL AND
  http_request.request_method IN ('GET')
GROUP BY http_request.request_url, location
ORDER BY location
LIMIT 100

Dans l'expression précédente, JSON_VALUE est nécessaire pour extraire la valeur du champ labels.checker_location, car le type de données pour labels est JSON. Toutefois, vous n'utilisez pas cette fonction pour extraire la valeur du champ http_request.latency.seconds. Le dernier champ est de type entier.

Calculer la moyenne des octets envoyés pour un test de sous-réseau

La requête suivante montre comment afficher le nombre moyen d'octets envoyés par emplacement.

La requête lit l'heure de données la plus récente, puis ne conserve que les lignes dont la colonne de type de ressource est gce_subnetwork et dont la colonne json_payload n'est pas NULL. Ensuite, la requête regroupe les lignes par emplacement de la ressource. Contrairement à l'exemple précédent où les données sont stockées sous forme de valeur numérique, la valeur du champ bytes_sent est une chaîne. Vous devez donc convertir la valeur en FLOAT64 avant de calculer la moyenne :

SELECT JSON_VALUE(resource.labels.location) AS location,
   AVG(CAST(JSON_VALUE(json_payload.bytes_sent) AS FLOAT64)) AS bytes
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  resource.type = "gce_subnetwork" AND
  json_payload IS NOT NULL
GROUP BY location
LIMIT 100

Le résultat de la requête précédente est un tableau dans lequel chaque ligne liste un emplacement et la moyenne des octets envoyés pour cet emplacement.

Pour en savoir plus sur toutes les fonctions permettant de récupérer et de transformer des données JSON, consultez Fonctions JSON.

Pour en savoir plus sur CAST et les autres fonctions de conversion, consultez Fonctions de conversion.

Compter les entrées de journal avec un champ correspondant à un modèle

Pour renvoyer la sous-chaîne qui correspond à une expression régulière, utilisez la fonction REGEXP_EXTRACT. Le type renvoyé de cette fonction est STRING ou BYTES.

La requête suivante conserve les entrées de journal pour lesquelles la valeur du champ json_payload.jobName n'est pas NULL. Il regroupe ensuite les entrées par suffixe de nom commençant par test. Enfin, la requête compte le nombre d'entrées dans chaque groupe :

SELECT
  REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
  COUNT(*) AS count
FROM
  `TABLE_NAME_OF_LOG_VIEW`
WHERE
  json_payload.jobName IS NOT NULL
GROUP BY name
ORDER BY count
LIMIT 20

Pour obtenir d'autres exemples, consultez la documentation REGEXP_EXTRACT. Pour obtenir d'autres exemples d'expressions régulières que vous pouvez utiliser, consultez Fonctions, opérateurs et instructions conditionnelles.

Cette section décrit deux approches différentes que vous pouvez utiliser pour rechercher des données dans plusieurs colonnes d'un tableau.

Pour rechercher dans une vue de journaux les entrées qui correspondent à un ensemble de termes de recherche, utilisez la fonction SEARCH. Cette fonction nécessite deux paramètres : l'emplacement de la recherche et la requête de recherche. Étant donné que la fonction SEARCH est soumise à des règles spécifiques concernant la recherche de données, nous vous recommandons de lire la documentation SEARCH.

La requête suivante ne conserve que les lignes dont un champ correspond exactement à "35.193.12.15" :

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW` AS t
WHERE
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  SEARCH(t,"`35.193.12.15`")
ORDER BY timestamp ASC
LIMIT 20

Dans la requête précédente, des guillemets inversés entourent la valeur à rechercher. Cela garantit que la fonction SEARCH recherche une correspondance exacte entre la valeur d'un champ et la valeur entre les accents graves.

Lorsque les guillemets inversés sont omis dans la chaîne de requête, celle-ci est divisée en fonction des règles définies dans la documentation SEARCH. Par exemple, lorsque l'instruction suivante est exécutée, la chaîne de requête est divisée en quatre jetons : "35", "193", "12" et "15" :

  SEARCH(t,"35.193.12.15")

L'instruction SEARCH précédente correspond à une ligne lorsqu'un seul champ correspond aux quatre jetons. L'ordre des jetons n'a pas d'importance.

Vous pouvez inclure plusieurs instructions SEARCH dans une requête. Par exemple, dans la requête précédente, vous pouvez remplacer le filtre sur l'ID de journal par une instruction comme celle-ci :

  SEARCH(t,"`cloudaudit.googleapis.com/data_access`")

L'instruction précédente recherche tous les champs des entrées de journal dans la vue du journal, tandis que l'instruction d'origine ne recherche que le champ log_id des entrées de journal.

Pour effectuer plusieurs recherches dans plusieurs champs, séparez les chaînes individuelles par un espace. Par exemple, l'instruction suivante correspond aux lignes dans lesquelles un champ contient "Hello World", "happy" et "days" :

  SEARCH(t,"`Hello World` happy days")

Enfin, vous pouvez rechercher des champs spécifiques au lieu de rechercher dans un tableau entier. Par exemple, l'instruction suivante ne recherche que dans les colonnes nommées text_payload et json_payload :

   SEARCH((text_payload, json_payload) ,"`35.222.132.245`")

Pour savoir comment les paramètres de la fonction SEARCH sont traités, consultez la page de référence BigQuery Fonctions de recherche.

Pour effectuer un test non sensible à la casse afin de déterminer si une valeur existe dans une expression, utilisez la fonction CONTAINS_SUBSTR. Cette fonction renvoie TRUE si la valeur existe et FALSE dans le cas contraire. La valeur de la recherche doit être un littéral de type STRING, mais pas de valeur littérale NULL.

Par exemple, la requête suivante récupère toutes les entrées de journal d'audit d'accès aux données avec une adresse IP spécifique dont les codes temporels se trouvent dans une plage de temps spécifique. Enfin, la requête trie les résultats, puis affiche les 20 plus anciens :

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `TABLE_NAME_OF_LOG_VIEW` AS t
WHERE
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  CONTAINS_SUBSTR(t,"35.193.12.15")
ORDER BY timestamp ASC
LIMIT 20

La requête précédente effectue un test de sous-chaîne. Par conséquent, une ligne contenant "35.193.12.152" correspond à l'instruction CONTAINS_SUBSTR.

Combiner des données provenant de plusieurs sources

Les instructions de requête analysent une ou plusieurs tables ou expressions, et renvoient les lignes de résultats calculées. Par exemple, vous pouvez utiliser des instructions de requête pour fusionner les résultats des instructions SELECT sur différentes tables ou ensembles de données de différentes manières, puis sélectionner les colonnes à partir des données combinées.

Combiner les données de deux tables avec des jointures

Pour combiner des informations provenant de deux tables, utilisez l'un des opérateurs join. Le type de jointure et la clause conditionnelle que vous utilisez déterminent la façon dont les lignes sont combinées et supprimées.

La requête suivante vous donne les champs json_payload des lignes de deux tables différentes écrites par la même portée de trace. La requête effectue une jointure interne JOIN sur deux tables pour les lignes où les valeurs des colonnes span_id et trace des deux tables correspondent. À partir de ce résultat, la requête sélectionne ensuite les champs timestamp, severity et json_payload provenant de TABLE_NAME_OF_LOG_VIEW_1, le champ json_payload provenant de TABLE_NAME_OF_LOG_VIEW_2, ainsi que les valeurs des champs span_id et trace sur lesquels les deux tables ont été jointes, et renvoie jusqu'à 100 lignes :

SELECT
  a.timestamp, a.severity, a.json_payload, b.json_payload, a.span_id, a.trace
FROM `TABLE_NAME_OF_LOG_VIEW_1` a
JOIN `TABLE_NAME_OF_LOG_VIEW_2` b
ON
  a.span_id = b.span_id AND
  a.trace = b.trace
LIMIT 100

Combiner plusieurs sélections avec des unions

Pour combiner les résultats d'au moins deux instructions SELECT et supprimer les lignes en double, utilisez l'opérateur UNION. Pour conserver les lignes en double, utilisez l'opérateur UNION ALL.

La requête suivante lit l'heure de données la plus récente de TABLE_NAME_OF_LOG_VIEW_1, fusionne le résultat avec l'heure de données la plus récente de TABLE_NAME_OF_LOG_VIEW_2, trie les données fusionnées par ordre croissant d'horodatage, puis affiche les 100 entrées les plus anciennes :

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
FROM(
  SELECT * FROM `TABLE_NAME_OF_LOG_VIEW_1`
  UNION ALL
  SELECT * FROM `TABLE_NAME_OF_LOG_VIEW_2`
)
ORDER BY timestamp ASC
LIMIT 100

Supprimer les entrées de journaux en double

L'analyse de journaux ne supprime pas les entrées de journal en double avant l'exécution d'une requête. Ce comportement est différent de celui observé lorsque vous interrogez des entrées de journal à l'aide de l'explorateur de journaux, qui supprime les entrées en double en comparant les champs "Nom du journal", "Code temporel" et "ID d'insertion".

Vous pouvez utiliser la validation au niveau des lignes pour supprimer les entrées de journaux en double.

Pour en savoir plus, consultez Résoudre les problèmes : des entrées de journaux en double figurent dans les résultats de Log Analytics.

Limites

Les requêtes utilisées sur la page Analyse de journaux sont compatibles avec les fonctions GoogleSQL, à quelques exceptions près.

Les commandes SQL suivantes ne sont pas acceptées pour les requêtes SQL émises à l'aide de la page Analyse de journaux :

  • Commandes LDD et LMD
  • Fonctions JavaScript définies par l'utilisateur
  • Fonctions BigQuery ML
  • Variables SQL

Les éléments suivants ne sont compatibles que lorsque vous interrogez un ensemble de données associé à l'aide des pages BigQuery Studio et Looker Studio, ainsi que de l'outil de ligne de commande bq :

  • Fonctions JavaScript définies par l'utilisateur
  • Fonctions BigQuery ML
  • Variables SQL

Étapes suivantes

Pour savoir comment acheminer et stocker les entrées de journal, consultez les documents suivants :

Pour la documentation de référence SQL, consultez les documents suivants :