Ce document traite du concept de journalisation structurée et des méthodes d'ajout d'une structure aux champs de charge utile des entrées de journal. Lorsque la charge utile du journal est mise en forme en tant qu'objet JSON et que cet objet est stocké dans le champ jsonPayload
, l'entrée de journal est appelée journal structuré. Pour ces journaux, vous pouvez créer des requêtes qui recherchent des chemins JSON spécifiques et vous pouvez indexer des champs spécifiques dans la charge utile du journal. En revanche, lorsque la charge utile du journal est mise en forme sous forme de chaîne et stockée dans le champ textPayload
, l'entrée de journal est non structurée.
Vous pouvez effectuer une recherche dans le champ de texte, mais vous ne pouvez pas en indexer le contenu.
Pour créer des entrées de journal structurées, procédez comme suit:
- Appelez la méthode API
entries.write
et fournissez unLogEntry
entièrement formaté. - Exécutez la commande
gcloud logging write
.
- Utilisez une bibliothèque cliente Cloud Logging qui écrit des journaux structurés.
- Utilisez le service BindPlane.
Utilisez un agent pour écrire des journaux:
Certains services Google Cloud contiennent un agent de journalisation intégré qui envoie les données écrites dans
stdout
oustderr
sous forme de journaux à Cloud Logging. Vous pouvez utiliser cette approche pour les services Google Cloud tels que Google Kubernetes Engine, l'environnement flexible App Engine et les fonctions Cloud Run.Pour les machines virtuelles (VM) Compute Engine, vous pouvez installer et configurer l'Agent Ops ou l'ancien agent Logging, puis utiliser l'agent installé pour envoyer des journaux à Cloud Logging.
Pour en savoir plus sur ces approches, consultez les sections suivantes.
Écrire des journaux à l'aide de bibliothèques clientes ou de l'API
Vous pouvez écrire des données de journalisation à l'aide des bibliothèques clientes Cloud Logging, qui appellent l'API Cloud Logging, ou en appelant directement l'API Cloud Logging.
Les bibliothèques clientes peuvent simplifier la population des champs JSON spéciaux en capturant automatiquement certaines informations et en fournissant des interfaces pour remplir les champs de manière appropriée. Toutefois, pour contrôler entièrement la structure de vos charges utiles, appelez directement l'API Cloud Logging et transmettez-lui la structure LogEntry
complète.
Pour en savoir plus, consultez la référence entries.write
.
Pour obtenir des exemples de code, consultez la section Écrire des journaux structurés.
Écrire des journaux à l'aide de la gcloud CLI
Vous pouvez écrire des données de journal à l'aide de gcloud CLI. L'interface accepte les journaux structurés et non structurés. Lorsque vous souhaitez écrire un journal structuré, fournissez à la commande un objet JSON sérialisé.
Pour obtenir un guide de démarrage rapide, consultez Écrire et interroger des entrées de journal avec la Google Cloud CLI.
Pour obtenir des exemples de code, consultez la documentation de référence de gcloud logging write
.
Écrire des journaux à l'aide de BindPlane
Vous pouvez utiliser le service BindPlane pour envoyer des journaux à Logging. Pour ces journaux, les charges utiles sont au format JSON et structurées en fonction du système source. Pour plus d'informations sur la recherche et l'affichage des journaux ingérés à l'aide de BindPlane, consultez le guide de démarrage rapide de BindPlane.
Écrire des journaux à l'aide d'un agent
Pour obtenir les journaux de vos instances Compute Engine, vous pouvez utiliser l'agent Ops ou l'ancien agent Cloud Logging. Les deux agents peuvent collecter des métriques à partir d'applications tierces et sont compatibles avec la journalisation structurée:
L'agent Ops est l'agent recommandé pour collecter la télémétrie à partir de vos instances Compute Engine. Cet agent combine la journalisation et les métriques dans un seul agent, fournit une configuration basée sur YAML et dispose d'une journalisation à haut débit.
Pour savoir comment configurer l'agent Ops pour qu'il prenne en charge la journalisation structurée ou pour personnaliser la forme d'un journal structuré, consultez la section Configurer l'agent Ops.
L'ancien agent Cloud Logging collecte les journaux. Cet agent ne collecte pas d'autres formes de télémétrie.
Le reste de cette section est spécifique à l'ancien agent Logging.
Agent Logging: champs JSON spéciaux
Certains champs de l'objet JSON sont reconnus comme spéciaux par l'ancien agent Logging et extraits dans la structure LogEntry
. Ces champs JSON spéciaux peuvent être utilisés pour définir les champs suivants dans LogEntry
:
severity
spanId
labels
défini par l'utilisateur.httpRequest
JSON étant plus précis et polyvalent que les lignes de texte, vous pouvez utiliser des objets JSON pour écrire des messages multilignes et ajouter des métadonnées.
Afin de créer des entrées de journal structurées pour vos applications au format simplifié, consultez le tableau suivant, qui répertorie les champs et leurs valeurs au format JSON :
Champ de journal JSON |
LogEntry
champ
|
Fonction de l'agent Cloud Logging | Exemple de valeur |
---|---|---|---|
severity
|
severity
|
L'agent Logging tente de faire correspondre différentes chaînes de gravité courantes, qui incluent la liste des chaînes LogSeverity reconnues par l'API Logging. | "severity":"ERROR"
|
message
|
textPayload (ou partie de jsonPayload )
|
Message qui s'affiche sur la ligne d'entrée de journal dans l'explorateur de journaux. | "message":"There was an error in the application." Remarque : Le champ message est enregistré en tant que textPayload s'il s'agit du seul champ restant après le déplacement des autres champs spécifiques par l'agent Logging et si detect_json était désactivé. Sinon, message reste dans jsonPayload . detect_json ne s'applique pas aux environnements de journalisation gérés tels que Google Kubernetes Engine. Si votre entrée de journal contient une trace de la pile d'exception, celle-ci doit être définie dans le champ de journal JSON message , de sorte qu'elle puisse être analysée et enregistrée dans Error Reporting. |
log (ancienne version de Google Kubernetes Engine uniquement) |
textPayload
|
Ne s'applique qu'à l'ancienne version de Google Kubernetes Engine : si après déplacement des champs spéciaux, il ne reste plus qu'un champ log , ce champ est enregistré en tant que textPayload . |
|
httpRequest
|
httpRequest
|
Un enregistrement structuré au format du champ HttpRequest de LogEntry . |
"httpRequest":{"requestMethod":"GET"}
|
champs liés au temps | timestamp
|
Pour en savoir plus, consultez la section Champs liés au temps. | "time":"2020-10-12T07:20:50.52Z"
|
logging.googleapis.com/insertId
|
insertId
|
Pour en savoir plus, consultez la section insertId de la page LogEntry . |
"logging.googleapis.com/insertId":"42"
|
logging.googleapis.com/labels
|
labels
|
La valeur de ce champ doit être un enregistrement structuré.
Pour en savoir plus, consultez la section labels de la page LogEntry . |
"logging.googleapis.com/labels":
{"user_label_1":"value_1","user_label_2":"value_2"}
|
logging.googleapis.com/operation
|
operation
|
La valeur de ce champ est également utilisée par l'explorateur de journaux pour regrouper les entrées de journal associées.
Pour en savoir plus, consultez la section operation de la page LogEntry . |
"logging.googleapis.com/operation":
{"id":"get_data","producer":"github.com/MyProject/MyApplication",
"first":"true"}
|
logging.googleapis.com/sourceLocation
|
sourceLocation
|
Les informations d'emplacement du code source associées à l'entrée de journal, le cas échéant.
Pour en savoir plus, consultez la section LogEntrySourceLocation de la page LogEntry . |
"logging.googleapis.com/sourceLocation":
{"file":"get_data.py","line":"142","function":"getData"}
|
logging.googleapis.com/spanId
|
spanId
|
ID de délai dans la trace associée à l'entrée de journal.
Pour en savoir plus, consultez la section spanId de la page LogEntry . |
"logging.googleapis.com/spanId":"000000000000004a"
|
logging.googleapis.com/trace
|
trace
|
Nom de ressource de la trace associée à l'entrée de journal, le cas échéant.
Pour en savoir plus, consultez la section trace de la page LogEntry .
|
"logging.googleapis.com/trace":"projects/my-projectid/traces/0679686673a" Remarque : Si vous n'écrivez pas dans stdout ou stderr , la valeur de ce champ doit être au format projects/[PROJECT-ID]/traces/[TRACE-ID] . Cela permet à l'explorateur de journaux et au lecteur de traces de regrouper les entrées de journal et de les afficher en parallèle avec les traces.
Si le paramètre autoformat_stackdriver_trace est défini sur "true" et que [V] correspond au format traceId de ResourceTrace, le champ trace de LogEntry possède la valeur projects/[PROJECT-ID]/traces/[V] . |
logging.googleapis.com/trace_sampled
|
traceSampled
|
La valeur de ce champ doit être true ou false .
Pour en savoir plus, consultez la section traceSampled de la page LogEntry . |
"logging.googleapis.com/trace_sampled": false
|
Pour créer des entrées de journal au format simplifié, créez une représentation JSON de l'entrée en utilisant les champs. Tous les champs sont facultatifs.
Voici un exemple d'entrée de journal JSON simplifiée :
{ "severity":"ERROR", "message":"There was an error in the application.", "httpRequest":{ "requestMethod":"GET" }, "times":"2020-10-12T07:20:50.52Z", "logging.googleapis.com/insertId":"42", "logging.googleapis.com/labels":{ "user_label_1":"value_1", "user_label_2":"value_2" }, "logging.googleapis.com/operation":{ "id":"get_data", "producer":"github.com/MyProject/MyApplication", "first":"true" }, "logging.googleapis.com/sourceLocation":{ "file":"get_data.py", "line":"142", "function":"getData" }, "logging.googleapis.com/spanId":"000000000000004a", "logging.googleapis.com/trace":"projects/my-projectid/traces/06796866738c859f2f19b7cfb3214824", "logging.googleapis.com/trace_sampled":false }
Voici un exemple d'entrée de journal obtenue :
{ "insertId": "42", "jsonPayload": { "message": "There was an error in the application", "times": "2020-10-12T07:20:50.52Z" }, "httpRequest": { "requestMethod": "GET" }, "resource": { "type": "k8s_container", "labels": { "container_name": "hello-app", "pod_name": "helloworld-gke-6cfd6f4599-9wff8", "project_id": "stackdriver-sandbox-92334288", "namespace_name": "default", "location": "us-west4", "cluster_name": "helloworld-gke" } }, "timestamp": "2020-11-07T15:57:35.945508391Z", "severity": "ERROR", "labels": { "user_label_2": "value_2", "user_label_1": "value_1" }, "logName": "projects/stackdriver-sandbox-92334288/logs/stdout", "operation": { "id": "get_data", "producer": "github.com/MyProject/MyApplication", "first": true }, "trace": "projects/my-projectid/traces/06796866738c859f2f19b7cfb3214824", "sourceLocation": { "file": "get_data.py", "line": "142", "function": "getData" }, "receiveTimestamp": "2020-11-07T15:57:42.411414059Z", "spanId": "000000000000004a" }
Agent Logging: configuration
L'ancien agent Logging, google-fluentd
, est un package du collecteur de données de journal Fluentd spécifique à Cloud Logging.
L'agent Logging est fourni avec la configuration Fluentd par défaut et utilise les plug-ins d'entrée Fluentd pour extraire les journaux des événements à partir de sources externes telles que les fichiers sur disque ou pour analyser les enregistrements de journaux entrants.
Fluentd dispose d'une liste d'analyseurs disponibles qui extraient les journaux et les convertissent en charges utiles (JSON) structurées.
En configurant une source de journal avec le format [PARSER_NAME]
, vous pouvez vous appuyer sur les analyseurs intégrés fournis par Fluentd. Pour en savoir plus sur la configuration de l'ancien agent Logging, consultez la section Configurer l'agent Logging.
Les exemples de code suivants montrent la configuration Fluentd, l'enregistrement du journal d'entrée et la charge utile structurée de sortie, qui fait partie d'une entrée de journal Cloud Logging :
Configuration Fluentd :
<source> @type tail format syslog # This uses a predefined log format regex named # `syslog`. See details at https://docs.fluentd.org/parser/syslog. path /var/log/syslog pos_file /var/lib/google-fluentd/pos/syslog.pos read_from_head true tag syslog </source>
Enregistrement du journal (entrée) :
<6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test
Charge utile structurée (sortie) :
jsonPayload: { "pri": "6", "host": "192.168.0.1", "ident": "fluentd", "pid": "11111", "message": "[error] Syslog test" }
Pour plus d'informations sur le fonctionnement de l'analyseur syslog
, consultez la documentation détaillée de Fluentd.
Agent Logging: analyseurs standards activés par défaut
Le tableau suivant présente les analyseurs standards inclus dans l'agent si vous activez la journalisation structurée :
Nom de l'analyseur | Fichier de configuration |
---|---|
syslog |
/etc/google-fluentd/config.d/syslog.conf |
nginx |
/etc/google-fluentd/config.d/nginx.conf |
apache2 |
/etc/google-fluentd/config.d/apache.conf |
apache_error |
/etc/google-fluentd/config.d/apache.conf |
Pour connaître la procédure d'activation de la journalisation structurée lors de l'installation de l'ancien agent Logging, consultez la section Installation.
Agent Logging: installation
Pour activer la journalisation structurée, vous devez modifier la configuration par défaut de l'ancien agent Logging lors de son installation (ou de sa réinstallation). L'activation de la journalisation structurée remplace les fichiers de configuration précédemment répertoriés, mais ne modifie pas le fonctionnement de l'agent lui-même.
Lorsque vous activez la journalisation structurée, les journaux répertoriés sont convertis en entrées de journal sous des formats différents de ceux utilisés avant l'activation des journaux structurés. Si les journaux sont acheminés vers des destinations extérieures à Logging, la modification peut affecter les applications de post-traitement. Par exemple, si vous acheminez des journaux vers BigQuery, BigQuery rejette les nouvelles entrées de journal pour le reste de la journée en raison de leur schéma incorrect.
Pour obtenir des instructions sur l'installation de l'ancien agent Logging et l'activation de la journalisation structurée, consultez la page Installer l'agent Logging.
Les anciens fichiers de configuration de l'agent Logging se trouvent dans /etc/google-fluentd/config.d/
. Ils doivent désormais inclure les analyseurs standards activés par défaut.
Agent Logging: configurer le format du journal d'accès Apache
Par défaut, l'ancien agent Logging stocke les données du journal d'accès Apache dans le champ jsonPayload
. Exemple :
{
"logName": ...,
"resource": ...,
"httpRequest": ...,
"jsonPayload": {
"user" : "some-user",
"method" : "GET",
"code" : 200,
"size" : 777,
"host" : "192.168.0.1",
"path" : "/some-path",
"referer": "some-referer",
"agent" : "Opera/12.0"
},
...
}
Vous pouvez également configurer l'ancien agent Logging pour extraire certains champs dans le champ httpRequest
. Exemple :
{
"logName": ...,
"resource": ...,
"httpRequest": {
"requestMethod": "GET",
"requestUrl": "/some-path",
"requestSize": "777",
"status": "200",
"userAgent": "Opera/12.0",
"serverIp": "192.168.0.1",
"referrer":"some-referrer",
},
"jsonPayload": {
"user":"some-user"
},
...
}
La configuration du champ httpRequest
, comme illustré dans l'exemple précédent, facilite le traçage: la console Google Cloud présente tous les journaux d'une requête HTTP donnée dans une hiérarchie parent-enfant.
Pour configurer cette extraction, ajoutez les éléments suivants à la fin de /etc/google-fluentd/config.d/apache.conf
:
<filter apache-access>
@type record_transformer
enable_ruby true
<record>
httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "serverIp" => record['host'],
"referer" => record['referer']} }
</record>
remove_keys method, path, size, code, agent, host, referer
</filter>
Pour plus d'informations sur la configuration de vos entrées de journal, consultez la section Modifier des enregistrements de journal.
Agent Logging: configurer le format du journal d'accès nginx
Par défaut, l'ancien agent Logging stocke les données du journal d'accès nginx dans le champ jsonPayload
. Exemple :
{
"logName": ...,
"resource": ...,
"httpRequest": ...,
"jsonPayload": {
"remote":"127.0.0.1",
"host":"192.168.0.1",
"user":"some-user",
"method":"GET",
"path":"/some-path",
"code":"200",
"size":"777",
"referrer":"some-referrer",
"agent":"Opera/12.0",
"http_x_forwarded_for":"192.168.3.3"
},
...
}
Vous pouvez également configurer l'ancien agent Logging pour extraire certains champs dans le champ httpRequest
. Exemple :
{
"logName": ...,
"resource": ...,
"httpRequest": {
"requestMethod": "GET",
"requestUrl": "/some-path",
"requestSize": "777",
"status": "200",
"userAgent": "Opera/12.0",
"remoteIp": "127.0.0.1",
"serverIp": "192.168.0.1",
"referrer":"some-referrer",
},
"jsonPayload": {
"user":"some-user",
"http_x_forwarded_for":"192.168.3.3"
},
...
}
La configuration du champ httpRequest
, comme illustré dans l'exemple précédent, facilite le traçage: la console Google Cloud présente tous les journaux d'une requête HTTP donnée dans une hiérarchie parent-enfant.
Pour configurer cette extraction, ajoutez les éléments suivants à la fin de /etc/google-fluentd/config.d/nginx.conf
:
<filter nginx-access>
@type record_transformer
enable_ruby true
<record>
httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "remoteIp" => record['remote'], "serverIp" => record['host'], "referer" => record['referer']} }
</record>
remove_keys method, path, size, code, agent, remote, host, referer
</filter>
Pour plus d'informations sur la configuration de vos entrées de journal, consultez la section Modifier des enregistrements de journal.
Écrire votre propre analyseur
Si vos journaux ne sont pas compatibles avec les analyseurs standards, vous pouvez écrire votre propre analyseur. Les analyseurs consistent en une expression régulière permettant de faire correspondre les enregistrements du journal et d'appliquer des libellés aux éléments.
Les exemples de code suivants affichent une ligne de journal dans l'enregistrement de journal, une configuration avec une expression régulière indiquant le format de la ligne de journal et l'entrée de journal stockée:
Ligne de journal dans l'enregistrement du journal :
REPAIR CAR $500
Configuration avec une expression régulière qui indique le format de la ligne de journal:
$ sudo vim /etc/google-fluentd/config.d/test-structured-log.conf $ cat /etc/google-fluentd/config.d/test-structured-log.conf <source> @type tail # Format indicates the log should be translated from text to # structured (JSON) with three fields, "action", "thing" and "cost", # using the following regex: format /(?<action>\w+) (?<thing>\w+) \$(?<cost>\d+)/ # The path of the log file. path /tmp/test-structured-log.log # The path of the position file that records where in the log file # we have processed already. This is useful when the agent # restarts. pos_file /var/lib/google-fluentd/pos/test-structured-log.pos read_from_head true # The log tag for this log input. tag structured-log </source>
Entrée de journal correspondante :
{ insertId: "eps2n7g1hq99qp" jsonPayload: { "action": "REPAIR" "thing": "CAR" "cost": "500" } labels: { compute.googleapis.com/resource_name: "add-structured-log-resource" } logName: "projects/my-sample-project-12345/logs/structured-log" receiveTimestamp: "2023-03-21T01:47:11.475065313Z" resource: { labels: { instance_id: "3914079432219560274" project_id: "my-sample-project-12345" zone: "us-central1-c" } type: "gce_instance" } timestamp: "2023-03-21T01:47:05.051902169Z" }
Résoudre les problèmes
Pour résoudre les problèmes courants rencontrés lors de l'installation de l'ancien agent Logging ou de l'interaction avec celui-ci, consultez la page Dépanner l'agent.
Étape suivante
Pour interroger et afficher des entrées de journal, consultez la page Afficher les journaux à l'aide de l'explorateur de journaux.
Pour lire des entrées de journal à l'aide de la Google Cloud CLI, consultez la section Lire des entrées de journal.
Pour découvrir comment lire des entrées de journal via l'API Logging, reportez-vous à la méthode
entries.list
.