Questo documento illustra il concetto di logging strutturato e i metodi per aggiungere struttura ai campi del payload voce di log. Quando il payload del log è formattato come oggetto JSON e l'oggetto è archiviato nel campo jsonPayload
, la voce del log è chiamata log strutturato. Per questi log, puoi creare query che cercano percorsi JSON specifici e puoi indicizzare campi specifici nel payload del log. Al contrario, quando il payload del log è formattato come stringa e memorizzato nel campo textPayload
, la voce di log è non strutturata.
Puoi eseguire ricerche nel campo di testo, ma non puoi indicizzare i relativi contenuti.
Per creare voci di log strutturate, esegui una delle seguenti operazioni:
- Chiama il metodo dell'API
entries.write
e fornisci unLogEntry
completamente formattato. - Utilizza il comando
gcloud logging write
.
- Utilizza una libreria client di Cloud Logging che scrive log strutturati.
- Utilizza il servizio BindPlane.
Utilizza un agente per scrivere i log:
Alcuni servizi Google Cloud contengono un agente di logging integrato che invia i dati scritti in
stdout
ostderr
come log a Cloud Logging. Puoi utilizzare questo approccio per i servizi Google Cloud come Google Kubernetes Engine, l'ambiente flessibile di App Engine e le funzioni Cloud Run.Per le macchine virtuali (VM) Compute Engine, puoi installare e configurare Ops Agent o l'agente Logging legacy e poi utilizzare l'agente installato per inviare i log a Cloud Logging.
Per ulteriori informazioni su questi approcci, consulta le sezioni seguenti.
Scrivi i log utilizzando le librerie client o l'API
Puoi scrivere i dati di log utilizzando le
librerie client di Cloud Logging, che chiamano l'API Cloud Logging, o chiamando direttamente l'API Cloud Logging.
Le librerie client possono semplificare la compilazione dei campi JSON speciali acquisendo automaticamente alcune informazioni e fornendo interfacce per compilare correttamente i campi. Tuttavia, per il controllo completo della struttura dei payload, chiama direttamente l'API Cloud Logging e passa la struttura completa di LogEntry
all'API Cloud Logging.
Per ulteriori informazioni, consulta la documentazione di riferimento di entries.write
.
Per esempi di codice, consulta Scrivere log strutturati.
Scrivere log utilizzando gcloud CLI
Puoi scrivere i dati dei log utilizzando gcloud CLI. L'interfaccia supporta log non strutturati e log strutturati. Quando vuoi scrivere un log strutturato, fornisci al comando un oggetto JSON serializzato.
Per una guida rapida, consulta Scrivere voci di log ed eseguire query con Google Cloud CLI.
Per esempi di codice, consulta la documentazione di riferimento di gcloud logging write
.
Scrivere log utilizzando BindPlane
Puoi utilizzare il servizio BindPlane per inviare i log a Logging. Per questi log, i payload sono in formato JSON e sono strutturati in base al sistema di origine. Per informazioni su come trovare e visualizzare i log importati utilizzando BindPlane, consulta la guida rapida di BindPlane.
Scrivere log utilizzando un agente
Per recuperare i log dalle istanze Compute Engine, puoi utilizzare Ops Agent o l'agente Cloud Logging legacy. Entrambi gli agenti possono raccogliere metriche da applicazioni di terze parti e supportano entrambi la registrazione strutturata:
Ops Agent è l'agente consigliato per raccogliere la telemetria dalle istanze Compute Engine. Questo agente combina logging e metriche in un unico agente, fornisce una configurazione basata su YAML e dispone di logging a velocità effettiva elevata.
Per informazioni su come configurare Ops Agent in modo da supportare il logging strutturato o personalizzare la forma di un log strutturato, consulta Configurare Ops Agent.
L'agente Cloud Logging legacy raccoglie i log. Questo agente non raccoglie altre forme di telemetria.
Il resto di questa sezione riguarda in modo specifico l'agente Logging precedente.
Agente Logging: campi JSON speciali
Alcuni campi dell'oggetto JSON sono riconosciuti come speciali dall'agente Logging precedente ed estratti nella struttura LogEntry
. Questi campi JSON speciali possono essere utilizzati per impostare
i seguenti campi in LogEntry
:
severity
spanId
labels
definito dall'utentehttpRequest
Poiché JSON è più preciso e versatile delle righe di testo, puoi utilizzare gli oggetti JSON per scrivere messaggi multiriga e aggiungere metadati.
Per creare voci di log strutturate per le tue applicazioni utilizzando il formato semplificato, consulta la tabella seguente, che elenca i campi e i relativi valori in JSON:
Campo log JSON |
LogEntry
campo
|
Funzione agente Cloud Logging | Valore di esempio |
---|---|---|---|
severity
|
severity
|
L'agente di logging tenta di associare una serie di stringhe di gravità comuni, tra cui l'elenco di stringhe LogSeverity riconosciute dall'API Logging. | "severity":"ERROR"
|
message
|
textPayload
(o parte di
jsonPayload )
|
Il messaggio visualizzato nella riga di inserimento del log in Esplora log. | "message":"There was an error in the application." Nota: message viene salvato come textPayload se è l'unico campo rimanente dopo che l'agente di logging ha spostato gli altri campi per scopi speciali e
detect_json non è stato attivato; in caso contrario, message rimane in jsonPayload . detect_json non è applicabile agli ambienti di logging gestiti come Google Kubernetes Engine. Se la voce di log contiene una analisi dello stack di eccezioni, questa deve essere impostata in questo campo del log JSON message , in modo che possa essere analizzata e salvata in Error Reporting. |
log
(solo
Google Kubernetes Engine
legacy) |
textPayload
|
Si applica solo a Google Kubernetes Engine precedente:
se, dopo aver spostato i campi per scopi speciali, rimane solo un campo log , questo viene salvato come textPayload . |
|
httpRequest
|
httpRequest
|
Un record strutturato nel formato
del campo LogEntry
HttpRequest . |
"httpRequest":{"requestMethod":"GET"}
|
campi correlati al tempo | timestamp
|
Per ulteriori informazioni, consulta Campi relativi al tempo. | "time":"2020-10-12T07:20:50.52Z"
|
logging.googleapis.com/insertId
|
insertId
|
Per ulteriori informazioni, consulta insertId nella pagina LogEntry . |
"logging.googleapis.com/insertId":"42"
|
logging.googleapis.com/labels
|
labels
|
Il valore di questo campo deve essere un record strutturato.
Per ulteriori informazioni, consulta labels nella pagina LogEntry . |
"logging.googleapis.com/labels":
{"user_label_1":"value_1","user_label_2":"value_2"}
|
logging.googleapis.com/operation
|
operation
|
Il valore di questo campo viene utilizzato anche da Logs Explorer per raggruppare le voci di log correlate.
Per ulteriori informazioni, consulta operation nella pagina LogEntry . |
"logging.googleapis.com/operation":
{"id":"get_data","producer":"github.com/MyProject/MyApplication",
"first":"true"}
|
logging.googleapis.com/sourceLocation
|
sourceLocation
|
Informazioni sulla posizione del codice
sorgente associata
all'eventuale voce di log.
Per ulteriori informazioni, consulta LogEntrySourceLocation nella pagina LogEntry . |
"logging.googleapis.com/sourceLocation":
{"file":"get_data.py","line":"142","function":"getData"}
|
logging.googleapis.com/spanId
|
spanId
|
L'ID intervallo all'interno della traccia associata alla voce di log.
Per ulteriori informazioni, consulta spanId nella pagina LogEntry . |
"logging.googleapis.com/spanId":"000000000000004a"
|
logging.googleapis.com/trace
|
trace
|
Nome della risorsa della traccia associata all'eventuale voce di log.
Per ulteriori informazioni, consulta trace nella pagina LogEntry .
|
"logging.googleapis.com/trace":"projects/my-projectid/traces/0679686673a" Nota: se non scrivi in stdout o stderr ,
il valore di questo campo deve essere formattato come
projects/[PROJECT-ID]/traces/[TRACE-ID] ,
in modo che possa essere utilizzato da Logs Explorer e
dal visualizzatore di traccia per raggruppare le voci di log
e visualizzarle in linea con le tracce.
Se autoformat_stackdriver_trace è true e
[V] corrisponde al formato di ResourceTrace
traceId , il campo LogEntry trace ha il valore
projects/[PROJECT-ID]/traces/[V] . |
logging.googleapis.com/trace_sampled
|
traceSampled
|
Il valore di questo campo deve essere true o false .
Per ulteriori informazioni, consulta traceSampled nella pagina LogEntry . |
"logging.googleapis.com/trace_sampled": false
|
Per creare voci di log nel formato semplificato, crea una rappresentazione JSON della voce utilizzando i campi. Tutti i campi sono facoltativi.
Di seguito è riportato un esempio di voce di log JSON semplificata:
{ "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 }
Di seguito è riportato un esempio della voce di log risultante:
{ "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" }
Agente Logging: configurazione
L'agente Logging legacy, google-fluentd
, è un pacchetto specifico per Cloud Logging del collector dei dati di log Fluentd.
L'agente Logging viene fornito con la configurazione predefinita di Fluentd
e utilizza i plug-in di input di Fluentd per estrarre i log eventi da origini esterne
come i file su disco o per analizzare i record di log in arrivo.
Fluentd dispone di un elenco di parser supportati che estraggono i log e li convertono in payload strutturati (JSON).
Configurando un'origine log con format [PARSER_NAME]
, puoi utilizzare i parser integrati forniti da Fluentd. Per informazioni sulla configurazione dell'agente Logging precedente, consulta Configurare l'agente Logging.
I seguenti esempi di codice mostrano la configurazione di Fluentd, il record del log di input e il payload strutturato in uscita, che fa parte di una voce di log di Cloud Logging:
Configurazione di 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>
Record del log (input):
<6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test
Payload strutturato (output):
jsonPayload: { "pri": "6", "host": "192.168.0.1", "ident": "fluentd", "pid": "11111", "message": "[error] Syslog test" }
Per ulteriori informazioni sul funzionamento dell'analizzatore syslog
, consulta la documentazione dettagliata di Fluentd.
Agente Logging: analizzatori sintattici standard abilitati per impostazione predefinita
La tabella seguente include gli analizzatori standard inclusi nell'agente se attivi la registrazione strutturata:
Nome del parser | File di configurazione |
---|---|
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 |
Per istruzioni su come attivare il logging strutturato durante l'installazione dell'agente Logging precedente, consulta la sezione Installazione.
Agente Logging: installazione
Per abilitare il logging strutturato, devi modificare la configurazione predefinita dell'agente Logging legacy durante l'installazione o la reinstallazione. L'attivazione della registrazione strutturata sostituisce i file di configurazione elencati in precedenza, ma non modifica il funzionamento dell'agente stesso.
Quando attivi il logging strutturato, i log elencati vengono convertiti in voci di log con formati diversi rispetto a quelli precedenti all'attivazione dei log strutturati. Se i log vengono inoltrati a destinazioni esterne a Logging, la modifica potrebbe influire su eventuali applicazioni di post-elaborazione. Ad esempio, se inoltri i log a BigQuery, BigQuery rifiuta le nuove voci di log per il resto della giornata perché hanno uno schema errato.
Per istruzioni su come installare l'agente Logging precedente e attivare il logging strutturato, consulta Installazione dell'agente Logging.
Puoi trovare i file di configurazione dell'agente Logging precedente in /etc/google-fluentd/config.d/
, che ora dovrebbe includere i parser standard abilitati per impostazione predefinita.
Agente Logging: configura il formato del log di accesso Apache
Per impostazione predefinita, l'agente Logging legacy archivia i dati dei log di accesso di Apache nel campo jsonPayload
. Ad esempio:
{
"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"
},
...
}
In alternativa, puoi configurare l'agente Logging precedente in modo da estrarre determinati campi nel campo httpRequest
. Ad esempio:
{
"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 configurazione del campo httpRequest
, come mostrato nell'esempio precedente, facilita il monitoraggio: la console Google Cloud presenta tutti i log per una determinata richiesta HTTP in una gerarchia padre-figlio.
Per configurare questa estrazione, aggiungi quanto segue alla fine del
/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>
Per ulteriori dettagli su come configurare le voci di log, consulta Modificare i record dei log.
Agente Logging: configura il formato del log di accesso nginx
Per impostazione predefinita, l'agente Logging legacy archivia i dati dei log di accesso nginx nel campo jsonPayload
. Ad esempio:
{
"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"
},
...
}
In alternativa, puoi configurare l'agente Logging precedente in modo da estrarre determinati campi nel campo httpRequest
. Ad esempio:
{
"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 configurazione del campo httpRequest
, come mostrato nell'esempio precedente, facilita il monitoraggio: la console Google Cloud presenta tutti i log per una determinata richiesta HTTP in una gerarchia padre-figlio.
Per configurare questa estrazione, aggiungi quanto segue alla fine del
/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>
Per ulteriori dettagli su come configurare le voci di log, consulta Modificare i record dei log.
Scrivere il proprio parser
Se i log non sono supportati dagli analizzatori standard, puoi scrivere il tuo analizzatore. I parser sono costituiti da un'espressione regolare utilizzata per trovare corrispondenze tra i record di log e applicare le etichette ai componenti.
I seguenti esempi di codice mostrano una riga di log nel record di log, una configurazione con un'espressione regolare che indica il formato della riga di log e la voce di log archiviata:
Una riga di log nel record del log:
REPAIR CAR $500
Una configurazione con un'espressione regolare che indica il formato della riga di log:
$ 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>
La voce di log risultante:
{ 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" }
Risoluzione dei problemi
Per risolvere i problemi comuni riscontrati durante l'installazione o l'interazione con l'agente Logging precedente, consulta la sezione Risoluzione dei problemi dell'agente.
Passaggi successivi
Per eseguire query e visualizzare le voci di log, consulta Visualizza i log utilizzando Esplora log.
Per leggere le voci di log utilizzando Google Cloud CLI, consulta Lettura delle voci di log.
Per leggere le voci di log utilizzando l'API Logging, consulta il metodo
entries.list
.