Como gerar e visualizar registros

Nesta página, descrevemos os registros disponíveis ao usar o Cloud Run e como vê-los e gravá-los.

O Cloud Run tem dois tipos de registros, e eles são enviados automaticamente para o Cloud Logging:

  • Registros de solicitações: registros de solicitações enviados aos serviços do Cloud Run. Esses registros são criados automaticamente.
  • Registros de contêiner: registros emitidos das instâncias de contêiner, normalmente de seu próprio código, gravados em locais compatíveis, conforme descrito em Como gravar registros de contêiner.

Como ver registros

É possível ver os registros do seu serviço de duas maneiras:

  • Usar a página do Cloud Run no Console do Cloud.
  • Usar o Visualizador de registros do Cloud Logging no Console do Cloud.

Esses dois métodos de visualização examinam os mesmos registros armazenados no Cloud Logging, mas o Visualizador de registros fornece mais detalhes e mais recursos de filtragem.

Como visualizar registros no Cloud Run

Para ver os registros na página do Cloud Run, siga estas etapas:

  1. Acessar o Cloud Run

  2. Clique no serviço de sua escolha na lista exibida.

  3. Clique na guia REGISTROS para receber os registros de solicitação e contêiner para todas as revisões desse serviço. É possível filtrar por nível de gravidade de registro.

Como ver registros no Cloud Logging

Para ver os registros do Cloud Run no Visualizador de registros do Cloud Logging:

  1. Acesse a página Visualizador de registros no Console do Cloud.

    Acessar a página "Visualizador de registros"

  2. Selecione um projeto atual do Google Cloud na parte superior da página ou crie um novo.

  3. Usando os menus suspensos, selecione o recurso:

    • Revisão do Cloud Run para o Cloud Run (totalmente gerenciado).
    • Kubernetes Container para executar o Cloud Run para Anthos no Google Cloud.

Para mais informações, leia Como ver registros referente ao Logging do pacote de operações do Google Cloud.

Como visualizar registros no Cloud Code

Para ver seus registros no Cloud Code, leia os guias do IntelliJ e do Visual Studio Code.

Como ver registros usando a linha de comando

Para ver os registros do Cloud Run (totalmente gerenciados) em um formato otimizado ("melhorado") para visualização no console, use a linha de comando:

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=SERVICE" --project PROJECT-ID --limit 10

Se você precisar do JSON "não melhorado" real, poderá ler os registros de maneira programática.

Substitua PROJECT-ID pelo ID do projeto do Google Cloud. Para ver o ID do projeto, execute o comando gcloud config get-value project. Substitua SERVICE pelo nome do serviço do Cloud Run.

Como ler registros de maneira programática

Se você quiser ler os registros de maneira programática, use um destes métodos:

Como gravar registros de contêiner

Quando você gravar registros do seu serviço, eles serão coletados automaticamente pelo Cloud Logging, desde que os registros sejam gravados em qualquer um destes locais:

Espera-se que a maioria dos desenvolvedores grave registros usando a saída e o erro padrão.

Os registros de contêiner gravados nesses locais compatíveis são automaticamente associados ao serviço, à revisão e ao local do Cloud Run. As exceções contidas nos registros são capturadas e informadas no Error Reporting.

Como usar texto simples ou JSON estruturado nos registros

Ao gravar registros, é possível enviar uma string de texto simples ou uma única linha de JSON serializado, também chamado de dados "estruturados". Ela é selecionada e analisada pelo Cloud Logging e colocada em jsonPayload. Por outro lado, a mensagem de texto simples é colocada em textPayload.

Como gravar registros estruturados

O snippet a seguir mostra como gravar entradas de registro estruturadas. Ele também mostra como correlacionar mensagens de registro com o registro de solicitação correspondente.

Node.js


// Uncomment and populate this variable in your code:
// $project = 'The project ID of your Cloud Run service';

// Build structured log messages as an object.
const globalLogFields = {};

// Add log correlation to nest all log messages beneath request log in Log Viewer.
const traceHeader = req.header('X-Cloud-Trace-Context');
if (traceHeader && project) {
  const [trace] = traceHeader.split('/');
  globalLogFields[
    'logging.googleapis.com/trace'
  ] = `projects/${project}/traces/${trace}`;
}

// Complete a structured log entry.
const entry = Object.assign(
  {
    severity: 'NOTICE',
    message: 'This is the default display field.',
    // Log viewer accesses 'component' as 'jsonPayload.component'.
    component: 'arbitrary-property',
  },
  globalLogFields
);

// Serialize to a JSON string and output.
console.log(JSON.stringify(entry));

Python

# Uncomment and populate this variable in your code:
# PROJECT = 'The project ID of your Cloud Run service';

# Build structured log messages as an object.
global_log_fields = {}

# Add log correlation to nest all log messages
# beneath request log in Log Viewer.
trace_header = request.headers.get('X-Cloud-Trace-Context')

if trace_header and PROJECT:
    trace = trace_header.split('/')
    global_log_fields['logging.googleapis.com/trace'] = (
        f"projects/{PROJECT}/traces/{trace[0]}")

# Complete a structured log entry.
entry = dict(severity='NOTICE',
             message='This is the default display field.',
             # Log viewer accesses 'component' as jsonPayload.component'.
             component='arbitrary-property',
             **global_log_fields)

print(json.dumps(entry))

Go

A estrutura de cada entrada de registro é fornecida por um tipo Entry:


// Entry defines a log entry.
type Entry struct {
	Message  string `json:"message"`
	Severity string `json:"severity,omitempty"`
	Trace    string `json:"logging.googleapis.com/trace,omitempty"`

	// Stackdriver Log Viewer allows filtering and display of this as `jsonPayload.component`.
	Component string `json:"component,omitempty"`
}

// String renders an entry structure to the JSON format expected by Stackdriver.
func (e Entry) String() string {
	if e.Severity == "" {
		e.Severity = "INFO"
	}
	out, err := json.Marshal(e)
	if err != nil {
		log.Printf("json.Marshal: %v", err)
	}
	return string(out)
}

Quando uma estrutura de entrada é registrada, o método String é chamado para organizá-la no formato JSON esperado pelo Cloud Logging:


func init() {
	// Disable log prefixes such as the default timestamp.
	// Prefix text prevents the message from being parsed as JSON.
	// A timestamp is added when shipping logs to Stackdriver.
	log.SetFlags(0)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	// Uncomment and populate this variable in your code:
	// projectID = "The project ID of your Cloud Run service"

	// Derive the traceID associated with the current request.
	var trace string
	if projectID != "" {
		traceHeader := r.Header.Get("X-Cloud-Trace-Context")
		traceParts := strings.Split(traceHeader, "/")
		if len(traceParts) > 0 && len(traceParts[0]) > 0 {
			trace = fmt.Sprintf("projects/%s/traces/%s", projectID, traceParts[0])
		}
	}

	log.Println(Entry{
		Severity:  "NOTICE",
		Message:   "This is the default display field.",
		Component: "arbitrary-property",
		Trace:     trace,
	})

	fmt.Fprintln(w, "Hello Logger!")
}

Java

Ativar a geração de registros JSON com Logback e SLF4J acionando o Codificador JSON do Logstash (links em inglês) na configuração do logback.xml.

// Build structured log messages as an object.
Object globalLogFields = null;
// Add log correlation to nest all log messages beneath request log in Log Viewer.
String traceHeader = req.headers("x-cloud-trace-context");
if (traceHeader != null && project != null) {
  String trace = traceHeader.split("/")[0];
  globalLogFields =
      kv(
          "logging.googleapis.com/trace",
          String.format("projects/%s/traces/%s", project, trace));
}
// Create a structured log entry using key value pairs.
logger.error(
    "This is the default display field.",
    kv("component", "arbitrary-property"),
    kv("severity", "NOTICE"),
    globalLogFields);
<configuration>
  <appender name="jsonConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <!-- Ignore default logging fields -->
      <fieldNames>
        <timestamp>[ignore]</timestamp>
        <version>[ignore]</version>
        <logger>[ignore]</logger>
        <thread>[ignore]</thread>
        <level>[ignore]</level>
        <levelValue>[ignore]</levelValue>
      </fieldNames>
    </encoder>
  </appender>
  <root level="INFO">
    <appender-ref ref="jsonConsoleAppender"/>
  </root>
</configuration>

Campos JSON especiais nas mensagens

Quando você fornece um registro estruturado como um dicionário JSON, alguns campos especiais são retirados do jsonPayload e gravados no campo correspondente no LogEntry gerado, conforme descrito na documentação sobre campos especiais.

Por exemplo, se o JSON incluir uma propriedade severity, ela será removida do jsonPayload e aparecerá como severity da entrada de registro. A propriedade message é usada como o texto de exibição principal da entrada de registro, se houver. Para mais informações sobre propriedades especiais, leia a seção Recurso de geração de registros abaixo.

Como correlacionar seus registros de contêiner com um registro de solicitação

No Visualizador de registros, os registros correlacionados pelos mesmos trace são visíveis no formato “pai-filho”: quando você clicar no ícone de triângulo à esquerda da entrada de registro de solicitação, os registros do contêiner relacionados a essa solicitação aparecerão aninhados no registro da solicitação.

Os registros de contêiner não são correlacionados automaticamente com os registros de solicitação, a menos que você use uma biblioteca de cliente do Cloud Logging. Para correlacionar registros de contêineres com os registros de solicitação sem usar uma biblioteca de cliente, use uma linha de registro JSON estruturado que contenha um campo logging.googleapis.com/trace com o identificador de trace extraído do cabeçalho X-Cloud-Trace-Context, como mostrado na amostra acima para geração de registros estruturados.

Como controlar o uso do recurso de registro de solicitações

Os registros de solicitação são criados automaticamente. Não é possível controlar a quantidade de registros de solicitação diretamente do Cloud Run, mas é possível usar o recurso de exclusão de registros do Cloud Logging.

Uma observação sobre agentes do Logging

Se você usou o Cloud Logging com determinados produtos do Google Cloud, como o Compute Engine, é possível que tenha usado agentes do Cloud Logging. O Cloud Run não usa agentes do Logging porque tem suporte integrado para a coleta de registros.

Recurso de geração de registros

Clicar em uma entrada de registro no Visualizador de registros abre uma entrada de registro formatada em JSON para que você possa detalhar o que você quer.

Todos os campos em uma entrada de registro, como carimbos de data/hora, gravidade e httpRequest, são padrão e estão descritos na documentação sobre a entrada de registro.

No entanto, há alguns rótulos comuns ou de recursos que são especiais para o Cloud Run. Eles estão listados aqui com o conteúdo de exemplo:

{
 httpRequest: {…}
 insertId:  "5c82b3d1000ece0000000000"
 labels: {
  instanceId:  "00bf4bf00000fb59c906a00000c9e29c2c4e06dce91500000000056008d2b6460f163c0057b97b2345f2725fb2423ee5f0bafd36df887fdb1122371563cf1ff453717282afe000001"
 }
 logName:  "projects/my-project/logs/run.googleapis.com%2Frequests"
 receiveTimestamp:  "2019-03-08T18:26:25.981686167Z"
 resource: {
  labels: {
   configuration_name:  "myservice"
   location:  "us-central1"
   project_id:  "my-project"
   revision_name:  "myservice-00002"
   service_name:  "myservice"
  }
  type:  "cloud_run_revision"
 }
 severity:  "INFO"
 timestamp:  "2019-03-08T18:26:25.970397Z"
}
Campo Valores e observações
instanceId A instância do contêiner que processou a solicitação.
logName Identifica o registro, por exemplo, registro de solicitação, erro padrão, saída padrão etc.
configuration_name O recurso "Configuração" que criou a revisão que atendeu à solicitação.
location Identifica o local do serviço do GCP.
project_id O projeto em que o serviço está implantado.
revision_name A revisão que atendeu à solicitação.
service_name O serviço que atendeu à solicitação.
type cloud_run_revision. O tipo de recurso do Cloud Run.