Afficher les journaux acheminés vers BigQuery

Ce document explique comment trouver les entrées de journal que vous avez acheminées depuis Cloud Logging vers des tables BigQuery. Les récepteurs Logging diffusent les données de journalisation dans BigQuery par petits lots, ce qui vous permet d'interroger les données sans exécuter de tâche de chargement. Pour vous aider à créer des requêtes et à comprendre le format de votre table BigQuery, ce document décrit également le schéma BigQuery des journaux acheminés.

En règle générale, les entrées de journal sont visibles dans BigQuery au bout d'une minute. Toutefois, lorsqu'une table est créée, les premières entrées de journal peuvent mettre plusieurs minutes à apparaître.

Avant de commencer

Pour en savoir plus sur les concepts liés aux récepteurs, consultez la page Présentation des modèles de routage et de stockage: récepteurs.

Pour savoir comment acheminer vos journaux, consultez la section Acheminer les journaux vers les destinations compatibles.

Pour découvrir comment les champs des entrée de journal acheminés sont nommés, consultez la page Schéma BigQuery des journaux acheminés.

Voir les journaux

Pour afficher les journaux acheminés vers BigQuery, procédez comme suit:

  1. Dans le panneau de navigation de la console Google Cloud, sélectionnez BigQuery:

    Accéder à BigQuery

  2. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

    Les entrées de journal sont visibles dans l'onglet Détails. Vous pouvez également interroger la table pour qu'elle renvoie vos données.

Exemples de requêtes

Pour en savoir plus sur la syntaxe des requêtes BigQuery, consultez la documentation de référence sur les requêtes. Les fonctions de caractères génériques de table, qui vous permettent d'effectuer des requêtes sur plusieurs tables, et l'opérateur plat, qui vous permet d'afficher des données à partir de champs répétés, sont particulièrement utiles.

Exemple de requête Compute Engine

La requête BigQuery suivante récupère les entrées de journal de plusieurs jours et de différents types de journaux :

  • La requête recherche les trois derniers jours des journaux syslog et apache-access. La requête a été effectuée le 23 février 2020 et couvre toutes les entrées de journal reçues les 21 et 22 février, ainsi que les entrées de journaux reçues le 23 février jusqu'à l'émission de la requête.

  • La requête récupère les résultats d'une seule instance de Compute Engine : 1554300700000000000.

SELECT
  timestamp AS Time,
  logName as Log,
  textPayload AS Message
FROM
  (TABLE_DATE_RANGE(my_bq_dataset.syslog_,
    DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP())),
  (TABLE_DATE_RANGE(my_bq_dataset.apache_access_,
    DATE_ADD(CURRENT_TIMESTAMP(), -2, 'DAY'), CURRENT_TIMESTAMP()))
WHERE
  resource.type == 'gce_instance'
  AND resource.labels.instance_id == '1554300700000000000'
ORDER BY time;

Voici quelques exemples de lignes de sortie :

Row | Time                    | Log                                         | Message
--- | ----------------------- | ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------
 5  | 2020-02-21 03:40:14 UTC | projects/project-id/logs/syslog             | Feb 21 03:40:14 my-gce-instance collectd[24281]: uc_update: Value too old: name = 15543007601548826368/df-tmpfs/df_complex-used; value time = 1424490014.269; last cache update = 1424490014.269;
 6  | 2020-02-21 04:17:01 UTC | projects/project-id/logs/syslog             | Feb 21 04:17:01 my-gce-instance /USR/SBIN/CRON[8082]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
 7  | 2020-02-21 04:49:58 UTC | projects/project-id/logs/apache-access      | 128.61.240.66 - - [21/Feb/2020:04:49:58 +0000] "GET / HTTP/1.0" 200 536 "-" "masscan/1.0 (https://github.com/robertdavidgraham/masscan)"
 8  | 2020-02-21 05:17:01 UTC | projects/project-id/logs/syslog             | Feb 21 05:17:01 my-gce-instance /USR/SBIN/CRON[9104]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
 9  | 2020-02-21 05:30:50 UTC | projects/project-id/log/syslogapache-access | 92.254.50.61 - - [21/Feb/2020:05:30:50 +0000] "GET /tmUnblock.cgi HTTP/1.1" 400 541 "-" "-"

Exemple de requête App Engine

La requête BigQuery suivante récupère les requêtes App Engine du mois dernier qui n'ont pas abouti :

SELECT
  timestamp AS Time,
  protoPayload.host AS Host,
  protoPayload.status AS Status,
  protoPayload.resource AS Path
FROM
  (TABLE_DATE_RANGE(my_bq_dataset.appengine_googleapis_com_request_log_,
    DATE_ADD(CURRENT_TIMESTAMP(), -1, 'MONTH'), CURRENT_TIMESTAMP()))
WHERE
  protoPayload.status != 200
ORDER BY time

Voici une partie des résultats :

Row | Time                    | Host                                  | Status | Path
--- | ----------------------- | ------------------------------------- | ------ | ------
 6  | 2020-02-12 19:35:02 UTC | default.my-gcp-project-id.appspot.com |    404 | /foo?thud=3
 7  | 2020-02-12 19:35:21 UTC | default.my-gcp-project-id.appspot.com |    404 | /foo
 8  | 2020-02-16 20:17:19 UTC | my-gcp-project-id.appspot.com         |    404 | /favicon.ico
 9  | 2020-02-16 20:17:34 UTC | my-gcp-project-id.appspot.com         |    404 | /foo?thud=%22what???%22

Schéma BigQuery des journaux routés

Les schémas de table BigQuery pour les journaux acheminés se basent sur la structure du type LogEntry et sur le contenu des charges utiles des journaux. Cloud Logging applique également des règles pour raccourcir les noms de champs des schémas BigQuery pour les journaux d'audit et pour certains champs de charge utile structurée. Vous pouvez afficher le schéma d'une table en sélectionnant une table comportant des entrées de journal acheminées dans l'interface BigQuery.

Conventions de dénomination de champs

Des conventions de dénomination s'appliquent aux champs d'entrées de journal lors de l'envoi de journaux à BigQuery :

  • Les noms de champs d'entrées de journal ne peuvent pas dépasser 128 caractères.

  • Les noms de champs d'entrées de journal ne peuvent contenir que des caractères alphanumériques. Tous les caractères non acceptés sont supprimés des noms de champs et remplacés par des traits de soulignement. Par exemple, jsonPayload.foo%% serait transformé en jsonPayload.foo__.

    Les noms de champs d'entrées de journal doivent commencer par un caractère alphanumérique, même après la transformation. Tous les traits de soulignement au début sont supprimés.

  • Pour les champs d'entrées de journaux appartenant au type LogEntry, les noms des champs BigQuery correspondants sont identiques aux noms des champs des entrées de journaux.

  • Pour les champs d'entrées de journal fournis par l'utilisateur, les noms de champs BigQuery correspondants sont normalisés en minuscules, mais la dénomination est conservée.

  • Pour les champs de charges utiles structurées, tant que le spécificateur @type n'apparaît pas, les noms de champs BigQuery correspondants sont normalisés en minuscules, mais la dénomination est conservée.

    Pour en savoir plus sur les charges utiles structurées contenant le spécificateur @type, consultez la section Champs de charge utile avec @type sur cette page.

Les exemples suivants montrent comment s'appliquent ces conventions de dénomination :

Champ d'entrée de journal Mappage de type LogEntry Nom de champ BigQuery
insertId insertId insertId
textPayload textPayload textPayload
httpRequest.status httpRequest.status httpRequest.status
httpRequest.requestMethod.GET httpRequest.requestMethod.[ABC] httpRequest.requestMethod.get
resource.labels.moduleid resource.labels.[ABC] resource.labels.moduleid
jsonPayload.MESSAGE jsonPayload.[ABC] jsonPayload.message
jsonPayload.myField.mySubfield jsonPayload.[ABC].[XYZ] jsonPayload.myfield.mysubfield

Champs de charge utile avec @type

Cette section traite des noms de champs spéciaux des schémas BigQuery pour les entrées de journal dont les charges utiles contiennent le spécificateur @type. Cela inclut les entrées de journal d'audit acheminées vers BigQuery.

Les charges utiles des entrées de journal peuvent contenir des données structurées. Tout champ structuré peut inclure un spécificateur de type facultatif au format suivant :

@type: type.googleapis.com/[TYPE]

Les règles de dénomination expliquent pourquoi un champ protoPayload d'une entrée de journal d'audit peut être mappé au champ de schéma BigQuery protopayload_auditlog.

Règles de dénomination pour @type

Les champs structurés qui possèdent des spécificateurs de type reçoivent généralement des noms de champs BigQuery suivis d'un [TYPE]. La valeur de [TYPE] peut être n'importe quelle chaîne.

Les règles de dénomination de @type ne s'appliquent qu'au niveau supérieur de jsonPayload ou protoPayload. Les champs imbriqués sont ignorés. Lorsque vous traitez des champs de charge utile structurée au niveau supérieur, Logging supprime le préfixe type.googleapis.com.

Par exemple, le tableau suivant présente le mappage des champs de charge utile structurée de niveau supérieur avec les noms de champs BigQuery :

Charge utile Indicateur @type de la charge utile Champ de charge utile Nom de champ BigQuery
jsonPayload (aucun) statusCode jsonPayload.statusCode
jsonPayload type.googleapis.com/abc.Xyz statusCode jsonpayload_abc_xyz.statuscode
protoPayload (aucun) statusCode protoPayload.statuscode
protoPayload type.googleapis.com/abc.Xyz statusCode protopayload_abc_xyz.statuscode

Certaines exceptions s'appliquent aux règles précédentes pour les champs contenant des spécificateurs de type :

  • Dans les journaux de requêtes App Engine, le nom de la charge utile des journaux acheminés vers BigQuery est protoPayload, même si elle possède un spécificateur de type.

  • Cloud Logging applique des règles spéciales pour raccourcir les noms de champs des schémas BigQuery pour les journaux d'audit. Ce point est abordé dans la section Champs de journaux d'audit de cette page.

Exemple

Cet exemple montre comment les champs de charge utile structurée sont nommés et utilisés lorsqu'ils sont reçus par BigQuery.

Imaginons que la charge utile d'une entrée de journal possède la structure suivante :

jsonPayload: {
  @type: "type.googleapis.com/google.cloud.v1.CustomType"
    name_a: {
      sub_a: "A value"
    }
    name_b: {
      sub_b: 22
    }
  }

Dans ce cas, le mappage avec les champs BigQuery est tel que décrit ci-dessous :

  • Le champ structuré de niveau supérieur jsonPayload contient un spécificateur @type. Son nom BigQuery est jsonpayload_v1_customtype.

  • Les champs imbriqués sont traités avec les règles de dénomination standards de BigQuery, car les règles de spécificateur de type ne s'appliquent pas aux champs imbriqués.

Ainsi, les noms BigQuery suivants sont définis pour la charge utile de l'entrée de journal :

  jsonpayload_v1_customtype
  jsonpayload_v1_customtype._type
  jsonpayload_v1_customtype.name_b
  jsonpayload_v1_customtype.name_b.sub_b
  jsonpayload_v1_customtype.name_a
  jsonpayload_v1_customtype.name_a.sub_a

Champs de journaux d'audit

Si vous n'utilisez pas les journaux d'audit acheminés vers BigQuery, vous pouvez ignorer cette section.

Les champs de charge utile de journal d'audit protoPayload.request, protoPayload.response et protoPayload.metadata contiennent des spécificateurs @type, mais sont traités comme des données JSON. Autrement dit, leurs noms de schéma BigQuery correspondent à leurs noms de champ suivis de Json, et ils contiennent des données de chaîne au format JSON.

Les deux ensembles de noms de champs de charge utile de journal d'audit sont répertoriés dans le tableau suivant :

Champ d'entrée de journal Nom de champ BigQuery
protoPayload protopayload_auditlog
protopayload.metadata protopayload_auditlog.metadataJson
protoPayload.serviceData protopayload_auditlog.servicedata_v1_bigquery
Exemple : protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest
protoPayload.request protopayload_auditlog.requestJson
protoPayload.response protopayload_auditlog.responseJson

Notez que la convention de dénomination serviceData est spécifique aux journaux d'audit qui sont générés par BigQuery, puis exportés de Cloud Logging vers BigQuery. Ces entrées du journal d'audit contiennent un champ serviceData contenant le spécificateur @type type.googleapis.com/google.cloud.bigquery.logging.v1.auditdata.

Exemple

Une entrée de journal d'audit générée par BigQuery contient un champ dont le nom est le suivant :

protoPayload.serviceData.tableInsertRequest

Si cette entrée de journal était ensuite exportée vers BigQuery, comment le champ tableInsertRequest serait-il référencé ? Avant d'être raccourci, le nom de champ correspondant dans BigQuery serait le suivant :

protopayload_google_cloud_audit_auditlog.servicedata_google_cloud_bigquery_logging_v1_auditdata.tableInsertRequest

Après avoir été raccourci, le même champ est référencé dans les tables BigQuery de la manière suivante :

protopayload_auditlog.servicedata_v1_bigquery.tableInsertRequest

Organisation des tables

Cette section présente les tables partitionnées pour les journaux acheminés vers BigQuery.

Lorsque vous acheminez des journaux vers un ensemble de données BigQuery, Logging crée des tables pour conserver les entrées de journal. La première entrée de journal reçue par BigQuery détermine le schéma de la table BigQuery de destination. BigQuery crée une table dont les colonnes sont basées sur les champs de la première entrée de journal et leur type. Les entrées de journal suivantes peuvent entraîner une non-concordance du schéma. Pour en savoir plus sur les circonstances et la manière dont elles sont traitées, consultez la section Incohérences dans le schéma.

Logging organise les données qu'il achemine au moyen de deux types de tables : les tables segmentées par date et les tables partitionnées. Les deux types de table segmentent les données des journaux en fonction des champs timestamp des entrées de journal. Cependant, il existe deux différences majeures entre les types de table :

  • Performances : une table partitionnée divise une grande table en partitions plus petites. Vous pouvez ainsi améliorer les performances des requêtes et, par conséquent, mieux contrôler les coûts BigQuery en réduisant le nombre d'octets lus par une requête.

  • Nomenclature des tables : les types de tables utilisent différentes conventions de dénomination, comme indiqué dans la section ci-dessous.

Organisation des tables

Les entrées de journal sont segmentées dans des tables BigQuery dont l'organisation et les noms sont basés sur le nom des entrées de journal et sur leur horodatage.

Les noms des tables sont associés à la date du calendrier de l'horodatage UTC de l'entrée de journal, au format de base ISO 8601 (AAAAMMJJ).

Le tableau suivant montre des exemples illustrant la façon dont les noms des journaux et les horodatages sont mappés au nom des tables dans BigQuery :

Nom du journal Entrée de journal timestamp1 Nom de la table BigQuery
(segmentée par date)
Nom de la table BigQuery
(partitionnée)
syslog 2017-05-23T18:19:22.135Z syslog_20170523 syslog
apache-access 2017-01-01T00:00:00.000Z apache_access_20170101 apache_access
compute.googleapis.com/activity_log 2017-12-31T23:59:59.999Z compute_googleapis_com_activity_log_20171231 compute_googleapis_com_activity_log

1 Les horodatages d'entrée de journal utilisent l'heure UTC (temps universel coordonné).

Créer des tables partitionnées

Lorsque vous créez un récepteur pour acheminer vos journaux vers BigQuery, vous pouvez utiliser des tables segmentées par date ou des tables partitionnées. La sélection par défaut est une table segmentée par date:

Pour obtenir des instructions sur la création de récepteurs, consultez les ressources suivantes:

Incohérences dans le schéma

La première entrée de journal reçue par BigQuery détermine le schéma de la table BigQuery de destination. BigQuery crée une table dont les colonnes sont basées sur les champs de la première entrée de journal et leur type.

Une erreur de correspondance de schéma se produit lorsque les entrées de journal sont écrites dans la table de destination et que l'une des erreurs suivantes se produit :

  • Une entrée de journal ultérieure modifie le type de champ d'un champ existant de la table.

    Par exemple, si le champ jsonPayload.user_id de l'entrée de journal initiale est défini sur string, cette entrée de journal génère une table dans laquelle ce champ est de type chaîne. La journalisation ultérieure de jsonPayload.user_id en tant que array entraînera une incohérence de schéma.

  • Une nouvelle entrée de journal contient un champ qui ne figure pas dans le schéma actuel. Son insertion dans la table de destination entraînerait le dépassement de la limite de colonnes BigQuery.

    La table de destination peut accepter le nouveau champ si celui-ci ne provoque pas le dépassement de la limite de colonnes.

Lorsque BigQuery identifie une incohérence de schéma, il crée une table dans l'ensemble de données correspondant pour stocker les informations d'erreur. Le type d'une table détermine son nom. Pour les tables segmentées par date, le format des noms est export_errors_YYYYMMDD. Pour les tables partitionnées, le format des noms est export_errors. Pour en savoir plus, consultez la page Organisation des tables.

Lors de l'exportation des entrées de journal, Logging envoie des messages par lot à BigQuery. BigQuery utilise les règles suivantes pour déterminer la table dans laquelle les entrées de journal du lot de messages actuel sont écrites :

  • Lorsqu'une modification de type de champ se produit, seules les entrées de journal ayant provoqué une non-concordance du schéma sont écrites dans la table d'erreur. Les entrées de journal du lot de messages actuel qui n'entraînent pas d'incohérence de schéma sont écrites dans la table de destination d'origine.

  • Lorsque la limite de colonnes est dépassée, toutes les entrées de journal du lot de messages actuel sont écrites dans la table d'erreur.

Schéma de la table d'erreurs

La table d'erreurs contient des données de LogEntry et des informations sur la non-concordance:

  • logEntry: contient l'entrée de journal complète. Toutefois, l'entrée de journal est convertie de JSON en chaîne.
  • schemaErrorDetail: contient le message d'erreur complet renvoyé par BigQuery.
  • sink: contient le chemin d'accès complet à la ressource du récepteur de journaux.
  • logName: extrait de LogEntry.
  • timestamp: extrait de LogEntry.
  • receiveTimestamp: extrait de LogEntry.
  • severity: extrait de LogEntry.
  • insertId: extrait de LogEntry.
  • trace: extrait de LogEntry.
  • resourceType: extrait de LogEntry.

Logging communique les incohérences de schéma au projet Google Cloud qui contient le récepteur de routage de la manière suivante:

  • Les propriétaires du projet reçoivent un e-mail. Les détails incluent l'ID de projet Google Cloud, le nom du récepteur et la destination.
  • La page "Activité" de la console Google Cloud affiche l'erreur Stackdriver Config error. Les détails incluent le nom du récepteur et la destination, ainsi qu'un lien vers un exemple d'entrée de journal à l'origine de l'erreur.

Éviter les incohérences au niveau des types de champ à l'avenir

Pour corriger les incohérences de type de champ pour les entrées de journal ultérieures, corrigez le type de champ afin qu'il corresponde au schéma actuel. Pour savoir comment corriger un type de champ, consultez Modifier le type de données d'une colonne.

Parfois, le type de champ ne peut pas être modifié. Par exemple, il est impossible de modifier un type de champ pour les journaux qui sont automatiquement générés par les services Google Cloud. Pour éviter les incohérences de schéma lorsque vous ne pouvez pas modifier un type de champ, renommez la table ou modifiez les paramètres du récepteur afin que Logging recrée la table dans un autre ensemble de données. Pour obtenir des instructions, consultez la section Gérer les récepteurs.

Dépannage

Si des journaux semblent être manquants dans la destination de votre récepteur, ou si vous pensez qu'il ne les achemine pas correctement, consultez la section Résoudre les problèmes liés aux journaux de routage.

Tarification

Cloud Logging ne facture pas l'acheminement des journaux vers une destination compatible. Toutefois, la destination peut appliquer des frais. À l'exception du bucket de journaux _Required, Cloud Logging facture la diffusion des journaux dans les buckets de journaux et leur stockage plus longtemps que la durée de conservation par défaut du bucket.

Cloud Logging ne facture pas la copie des journaux ni les requêtes émises via la page Explorateur de journaux ou Analyse de journaux.

Pour en savoir plus, consultez les documents suivants :