Este documento aborda o conceito de registo estruturado e os métodos para adicionar estrutura aos campos de payload das entradas de registo. Quando o payload do registo é formatado como um objeto JSON e esse objeto é armazenado no campo jsonPayload
, a entrada do registo é denominada registo estruturado. Para estes registos, pode criar consultas que pesquisem caminhos JSON específicos e pode indexar campos específicos no payload do registo. Por outro lado, quando o payload do registo é formatado como uma string e armazenado no campo textPayload
, a entrada do registo é não estruturada.
Pode pesquisar o campo de texto, mas não pode indexar o respetivo conteúdo.
Para criar entradas de registo estruturadas, faça qualquer uma das seguintes ações:
- Chame o método da API
entries.write
e forneça umLogEntry
totalmente formatado. - Use o comando
gcloud logging write
.
- Use uma biblioteca cliente do Cloud Logging que escreve registos estruturados.
- Use o serviço BindPlane.
Use um agente para escrever registos:
Alguns Google Cloud serviços contêm um agente de registo integrado que envia os dados escritos para
stdout
oustderr
como registos para o Cloud Logging. Pode usar esta abordagem para Google Cloud serviços como o Google Kubernetes Engine, o ambiente flexível do App Engine e as funções do Cloud Run.Para máquinas virtuais (VMs) do Compute Engine, pode instalar e configurar o agente Ops ou o agente Logging antigo e, em seguida, usar o agente instalado para enviar registos para o Cloud Logging.
Para mais informações acerca destas abordagens, consulte as secções seguintes.
Escreva registos através das bibliotecas cliente ou da API
Pode escrever dados de registo através das
bibliotecas cliente do Cloud Logging, que
chamam a API Cloud Logging, ou chamando diretamente a API Cloud Logging.
As bibliotecas de cliente podem simplificar o preenchimento dos campos JSON especiais capturando automaticamente algumas informações e fornecendo interfaces para preencher os campos adequadamente. No entanto, para ter controlo total sobre a estrutura dos seus payloads, chame diretamente a API Cloud Logging e transmita a estrutura LogEntry
completa para a API Cloud Logging.
Para mais informações, consulte a referência entries.write
.
Para ver exemplos de código, consulte o artigo Escrever registos estruturados.
Escreva registos através da CLI gcloud
Pode escrever dados de registo através da CLI gcloud. A interface suporta registos não estruturados e registos estruturados. Quando quiser escrever um registo estruturado, forneça ao comando um objeto JSON serializado.
Para um início rápido, consulte o artigo Escreva e consulte entradas de registo com a CLI do Google Cloud.
Para ver exemplos de código, consulte a referência de
gcloud logging write
.
Escreva registos com o BindPlane
Pode usar o serviço BindPlane para enviar registos para o Logging. Para estes registos, as cargas úteis estão no formato JSON e são estruturadas de acordo com o sistema de origem. Para obter informações sobre como encontrar e ver registos carregados através do BindPlane, consulte o guia de início rápido do BindPlane.
Escreva registos usando um agente
Para obter registos das suas instâncias do Compute Engine, pode usar o agente Ops ou o agente do Cloud Logging antigo. Ambos os agentes podem recolher métricas de aplicações de terceiros e ambos oferecem suporte para registo estruturado:
O agente Ops é o agente recomendado para recolher telemetria das suas instâncias do Compute Engine. Este agente combina o registo e as métricas num único agente, oferece uma configuração baseada em YAML e inclui registo de elevado débito.
Para ver informações sobre como configurar o agente Ops para suportar o registo estruturado ou personalizar o formulário de um registo estruturado, consulte o artigo Configure o agente Ops.
O agente do Cloud Logging antigo recolhe registos. Este agente não recolhe outras formas de telemetria.
O restante desta secção é específico do agente de registo antigo.
Agente de registos: campos JSON especiais
Alguns campos no objeto JSON são reconhecidos como especiais pelo agente de registo antigo e extraídos para a estrutura LogEntry
. Estes campos JSON especiais podem ser usados para definir os seguintes campos em LogEntry
:
severity
spanId
labels
definida pelo utilizadorhttpRequest
Uma vez que o JSON é mais preciso e versátil do que as linhas de texto, pode usar objetos JSON para escrever mensagens de várias linhas e adicionar metadados.
Para criar entradas de registo estruturadas para as suas aplicações através do formato simplificado, consulte a tabela seguinte, que lista os campos e os respetivos valores em JSON:
Campo de registo JSON |
LogEntry
campo
|
Função do agente do Cloud Logging | Valor de exemplo |
---|---|---|---|
severity
|
severity
|
O agente Logging tenta encontrar correspondência com várias strings de gravidade comuns, incluindo a lista de strings LogSeverity reconhecidas pela API Logging. | "severity":"ERROR"
|
message
|
textPayload
(ou parte de
jsonPayload )
|
A mensagem que aparece na linha de entrada do registo no Logs Explorer. | "message":"There was an error in the application." Nota: message é guardado como textPayload se for o único campo restante após o agente de registo mover os outros campos de fins especiais e
detect_json não tiver sido ativado; caso contrário, message permanece em jsonPayload . detect_json não é aplicável a ambientes de registo geridos, como o Google Kubernetes Engine. Se a entrada do registo contiver um rastreio da pilha de exceções, o rastreio da pilha de exceções deve ser definido neste campo do registo JSON message , para que o rastreio da pilha de exceções possa ser analisado e guardado no Error Reporting. |
log (Apenas Google Kubernetes Engine antigo) |
textPayload
|
Aplica-se apenas ao Google Kubernetes Engine antigo:
se, após mover os campos de fins especiais, restar apenas um campo log , esse campo é guardado como textPayload . |
|
httpRequest
|
httpRequest
|
Um registo estruturado no formato do campo LogEntry
HttpRequest . |
"httpRequest":{"requestMethod":"GET"}
|
campos relacionados com o tempo | timestamp
|
Para mais informações, consulte a secção Campos relacionados com o tempo. | "time":"2020-10-12T07:20:50.52Z"
|
logging.googleapis.com/insertId
|
insertId
|
Para mais informações,
consulte insertId
na página LogEntry . |
"logging.googleapis.com/insertId":"42"
|
logging.googleapis.com/labels
|
labels
|
O valor deste campo tem de ser um registo estruturado.
Para mais informações, consulte
labels na página LogEntry . |
"logging.googleapis.com/labels":
{"user_label_1":"value_1","user_label_2":"value_2"}
|
logging.googleapis.com/operation
|
operation
|
O valor deste campo também é usado pelo Logs Explorer para agrupar entradas de registo relacionadas.
Para mais informações,
consulte operation na página LogEntry . |
"logging.googleapis.com/operation":
{"id":"get_data","producer":"github.com/MyProject/MyApplication",
"first":"true"}
|
logging.googleapis.com/sourceLocation
|
sourceLocation
|
Informações de localização do código-fonte associadas à entrada do registo, se existirem.
Para mais informações,
consulte LogEntrySourceLocation
na página LogEntry . |
"logging.googleapis.com/sourceLocation":
{"file":"get_data.py","line":"142","function":"getData"}
|
logging.googleapis.com/spanId
|
spanId
|
O ID do intervalo na
rastreio associado à
entrada do registo.
Para mais informações,
consulte spanId
na página LogEntry . |
"logging.googleapis.com/spanId":"000000000000004a"
|
logging.googleapis.com/trace
|
trace
|
Nome do recurso do rastreio
associado à
entrada do registo
se existir.
Para mais informações,
consulte trace
na página LogEntry .
|
"logging.googleapis.com/trace":"projects/my-projectid/traces/0679686673a" Nota: se não estiver a escrever para stdout ou stderr ,
o valor deste campo deve ser formatado como
projects/[PROJECT-ID]/traces/[TRACE-ID] ,
para que possa ser usado pelo Explorador de registos e
pelo visualizador de rastreios para agrupar entradas de registo
e apresentá-las em linha com os rastreios.
Se autoformat_stackdriver_trace for verdadeiro e [V] corresponder ao formato de ResourceTrace, o campo traceId LogEntry tem o valor trace .projects/[PROJECT-ID]/traces/[V] |
logging.googleapis.com/trace_sampled
|
traceSampled
|
O valor deste campo tem de ser true ou false .
Para mais informações,
consulte traceSampled
na página LogEntry . |
"logging.googleapis.com/trace_sampled": false
|
Para criar entradas de registo no formato simplificado, crie uma representação JSON da entrada através dos campos. Todos os campos são opcionais.
Segue-se um exemplo de uma entrada de registo JSON simplificada:
{ "severity":"ERROR", "message":"There was an error in the application.", "httpRequest":{ "requestMethod":"GET" }, "time":"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 }
Segue-se um exemplo da entrada de registo resultante:
{ "insertId": "42", "jsonPayload": { "message": "There was an error in the application", "time": "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-10-12T07:20:50.52Z", "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-10-12T07:20:57.52Z", "spanId": "000000000000004a" }
Agente de registos: configuração
O agente de registos antigo, google-fluentd
, é uma embalagem específica do Cloud Logging do coletor de dados de registo Fluentd.
O agente Logging é fornecido com a configuração predefinida do Fluentd e usa plug-ins de entrada do Fluentd para extrair registos de eventos de origens externas, como ficheiros no disco, ou para analisar registos de registos recebidos.
O Fluentd tem uma lista de analisadores suportados que extraem registos e os convertem em payloads estruturados (JSON).
Ao configurar uma origem de registos com format [PARSER_NAME]
, pode basear-se nos analisadores incorporados fornecidos pelo Fluentd. Para ver informações sobre a configuração do agente Logging antigo, consulte o artigo Configure o agente Logging.
Os seguintes exemplos de código mostram a configuração do Fluentd, o registo de registo de entrada e a carga útil estruturada de saída, que faz parte de uma entrada de registo do Cloud Logging:
Configuração do 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>
Registo de registo (entrada):
<6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog test
Payload estruturado (resultado):
jsonPayload: { "pri": "6", "host": "192.168.0.1", "ident": "fluentd", "pid": "11111", "message": "[error] Syslog test" }
Para mais informações sobre o funcionamento do analisador syslog
, consulte a documentação detalhada do Fluentd.
Agente de registos: analisadores padrão ativados por predefinição
A tabela seguinte inclui os analisadores padrão incluídos no agente se ativar o registo estruturado:
Nome do analisador | Ficheiro de configuração |
---|---|
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 |
Para obter instruções sobre como ativar o registo estruturado ao instalar o agente de registo antigo, consulte a secção Instalação.
Agente de registos: instalação
Para ativar o registo estruturado, tem de alterar a configuração predefinida do agente de registo antigo quando o instalar ou reinstalar. A ativação do registo estruturado substitui os ficheiros de configuração indicados anteriormente, mas não altera o funcionamento do próprio agente.
Quando ativa o registo estruturado, os registos apresentados são convertidos em entradas de registo com formatos diferentes dos que tinham antes de ativar os registos estruturados. Se os registos estiverem a ser encaminhados para destinos fora do Logging, a alteração pode afetar quaisquer aplicações de pós-processamento. Por exemplo, se encaminhar registos para o BigQuery, o BigQuery rejeita as novas entradas de registo durante o resto do dia por terem um esquema incorreto.
Para ver instruções sobre como instalar o agente Logging antigo e ativar o registo estruturado, consulte o artigo Instalar o agente Logging.
Pode encontrar os ficheiros de configuração do agente Logging antigo em
/etc/google-fluentd/config.d/
, que devem agora incluir os
analisadores padrão ativados por predefinição.
Agente de registos: configure o formato do registo de acesso do Apache
Por predefinição, o agente Logging antigo armazena os dados do registo de acesso do Apache no campo jsonPayload
. Por exemplo:
{
"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"
},
...
}
Em alternativa, pode configurar o agente Logging antigo para extrair determinados campos para o campo httpRequest
. Por exemplo:
{
"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"
},
...
}
A configuração do campo httpRequest
, conforme mostrado no exemplo anterior, ajuda a
rastrear: a consola Google Cloud apresenta todos os registos de um determinado pedido HTTP
numa hierarquia principal-secundário.
Para configurar esta extração, adicione o seguinte ao final do elemento
/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>
Para mais detalhes sobre como configurar as entradas do registo, consulte o artigo Modificar registos do registo.
Agente de registos: configure o formato do registo de acesso do nginx
Por predefinição, o agente de registo antigo armazena os dados do registo de acesso do nginx no campo jsonPayload
. Por exemplo:
{
"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"
},
...
}
Em alternativa, pode configurar o agente Logging antigo para extrair determinados campos para o campo httpRequest
. Por exemplo:
{
"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"
},
...
}
A configuração do campo httpRequest
, conforme mostrado no exemplo anterior, ajuda a
rastrear: a consola Google Cloud apresenta todos os registos de um determinado pedido HTTP
numa hierarquia principal-secundário.
Para configurar esta extração, adicione o seguinte ao final do elemento
/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>
Para mais detalhes sobre como configurar as entradas do registo, consulte o artigo Modificar registos do registo.
Escreva o seu próprio analisador
Se os seus registos não forem suportados pelos analisadores padrão, pode escrever o seu próprio analisador. Os analisadores consistem numa expressão regular que é usada para fazer corresponder registos e aplicar etiquetas às partes.
Os exemplos de código seguintes mostram uma linha de registo no registo de registo, uma configuração com uma expressão regular que indica o formato da linha de registo e a entrada de registo armazenada:
Uma linha de registo no registo de registos:
REPAIR CAR $500
Uma configuração com uma expressão regular que indica o formato da linha de registo:
$ 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>
A entrada do registo resultante:
{ 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" }
Resolver problemas
Para resolver problemas comuns encontrados com a instalação ou a interação com o agente de registo antigo, consulte o artigo Resolução de problemas do agente.
O que se segue?
Para consultar e ver entradas de registo, consulte o artigo Veja registos através do Explorador de registos.
Para ler entradas de registo através da CLI Google Cloud, consulte o artigo Ler entradas de registo.
Para ler entradas de registo através da API Logging, consulte o método
entries.list
.