Linguagem de consulta do Logging

Neste documento, você verá uma descrição detalhada da linguagem de consulta do Logging que você usa para consultar e filtrar dados do Cloud Logging.

Para informações detalhadas sobre o design da linguagem de consulta do Logging, veja as especificações formais da API do Google para filtragem.

Para exemplos de consultas comuns que podem ser usadas, veja Amostra de consultas usando o Explorador de registros.

Visão geral

É possível usar a linguagem de consulta do Logging na Análise de registros no Console do Google Cloud, na API Logging ou na interface de linha de comando. É possível usar a linguagem de consulta do Logging para consultar dados e gravar filtros a fim de criar coletores e métricas com base em registros.

Uma consulta é uma expressão booleana que especifica um subconjunto de todas as entradas de registro no recurso selecionado do Google Cloud, como um projeto ou uma pasta do Google Cloud.

É possível criar consultas com base no campo indexado LogEntry usando os operadores lógicos AND e OR. Usando o campo resource.type nos exemplos a seguir, a gramática da linguagem de consulta do Logging tem esta aparência:

  • Restrição simples: resource.type = "gae_app"

  • Restrição conjuntiva: resource.type = "gae_app" AND severity = "ERROR"

  • Restrição disjuntiva: resource.type = "gae_app" OR resource.type = "gce_instance"

    • Como alternativa: resource.type = ("gae_app" OR "gce_instance")
  • Expressão conjuntiva/disjuntiva complexa: resource.type = "gae_app" AND (severity = "ERROR" OR "error")

Veja a seguir um exemplo simples de consulta:

resource.type = "gce_instance" AND
severity >= "ERROR" AND
NOT textPayload:robot

Essa consulta corresponde entradas de registro do Compute Engine que têm valores de gravidade de pelo menos ERROR e que o campo textPayload não contenha a string robot em qualquer lugar dentro dela. As comparações de string não diferenciam maiúsculas de minúsculas. Os nomes resource, severity e textPayload são definidos no tipo LogEntry.

Notação de sintaxe

Nas seções a seguir, você tem uma visão geral da sintaxe da linguagem de consulta do Logging e discute como as consultas são estruturadas e como a correspondência é realizada. Alguns dos exemplos usam comentários para fornecer um texto explicativo.

Observações:

  • O tamanho de uma consulta não pode exceder 20.000 caracteres.

  • A linguagem de consulta do Logging não diferencia maiúsculas de minúsculas, exceto em expressões regulares.

Resumo da sintaxe

A sintaxe da linguagem de consulta do Logging pode ser considerada em termos de consultas e comparações.

Uma consulta é uma string que contém uma expressão:

expression = ["NOT"] comparison { ("AND" | "OR") ["NOT"] comparison }

Uma comparação é um valor único ou uma expressão booleana:

"The cat in the hat"
resource.type = "gae_app"

A primeira linha é um exemplo de comparação que é um valor único. Esses tipos de comparações são restrições globais. Cada campo de uma entrada de registro é comparado ao valor usando implicitamente o operador has. Para este exemplo, se qualquer campo em uma LogEntry, ou sua payload, contiver a frase "The cat in the hat" (O gato no chapéu), a comparação será bem-sucedida.

A segunda linha é um exemplo de uma comparação que é uma expressão booleana da forma [FIELD_NAME] [OP] [VALUE]. Os elementos da comparação são descritos abaixo:

  • [FIELD_NAME] é um campo em uma entrada de registro. Por exemplo, resource.type.

  • [OP] é um operador de comparação. Por exemplo, =.

  • [VALUE] é uma expressão numérica de string, de função ou entre parênteses. Por exemplo, "gae_app". Para valores nulos JSON, use NULL_VALUE.

Operadores booleanos

Os operadores booleanos AND e OR são operadores de curto-circuito. O operador NOT tem a precedência mais alta, seguido por OR e AND, nessa ordem. Por exemplo, as duas expressões a seguir são equivalentes:

"a" OR NOT "b" AND NOT "c" OR "d"
("a" OR (NOT "b")) AND ((NOT "c") OR "d")

É possível omitir o operador AND entre comparações. Também é possível substituir o operador NOT pelo operador - (sinal de subtração). Por exemplo, as duas consultas a seguir são as mesmas:

a="b" AND c="d" AND NOT e="f"
a="b" c="d" -e="f"

AND e NOT sempre são usados nesta documentação.

Para todos os filtros, exceto aqueles usados pelas visualizações de registro, é possível usar os operadores AND, OR e NOT. As visualizações de registros são compatíveis apenas com as operações AND e NOT.

Para combinar regras AND e OR na mesma expressão, aninhe as regras usando parênteses. Se você não usar parênteses, sua consulta poderá não funcionar como pretendido.

Os operadores booleanos precisam ser sempre escritos com letras maiúsculas. and, or e not com letras minúsculas são analisados como termos de pesquisa.

Comparações

Comparações têm a seguinte forma:

[FIELD_NAME] [OP] [VALUE]

Os elementos da comparação são descritos abaixo:

  • [FIELD_NAME]: é o nome do caminho de um campo em uma entrada de registro. Os exemplos do nome do campo são:

    resource.type
    resource.labels.zone
    resource.labels.project_id
    insertId
    jsonPayload.httpRequest.protocol
    labels."compute.googleapis.com/resource_id"
    

    Se um componente de um nome de caminho tiver caracteres especiais, o nome do caminho precisa estar entre aspas duplas. Por exemplo, compute.googleapis.com/resource_id precisa estar entre aspas duplas porque contém uma barra /.

    Para detalhes, consulte identificadores de caminho de campo neste documento.

  • [OP]: é um operador de comparação, um dos seguintes:

    =           -- equal
    !=          -- not equal
    > < >= <=   -- numeric ordering
    :           -- "has" matches any substring in the log entry field
    =~          -- regular expression search for a pattern
    !~          -- regular expression search not for a pattern
    

Para saber como pesquisar entradas de registro usando expressões regulares, consulte Como usar expressões regulares.

  • [VALUE]: é uma expressão numérica de string, de função ou entre parênteses. As strings são usadas para representar texto arbitrário, além de valores booleanos, de enumeração e de string de bytes. O [VALUE] é convertido no tipo do campo antes da comparação. Para valores nulos JSON, use NULL_VALUE.

Para filtrar um valor nulo JSON, use a seguinte sintaxe:

jsonPayload.field = NULL_VALUE      -- includes "field" with null value
NOT jsonPayload.field = NULL_VALUE  -- excludes "field" with null value

Se [VALUE] for uma combinação booleana de comparações entre parênteses, o nome do campo e o operador de comparação serão aplicados a cada elemento. Exemplo:

jsonPayload.cat = ("longhair" OR "shorthair")
jsonPayload.animal : ("nice" AND "pet")

A primeira comparação verifica se o campo cat tem o valor “longhair” ou “shorthair”. A segunda verifica se o valor do campo animal contém as palavras "nice" e "pet", em qualquer ordem.

Identificadores de caminho de campo

Todas as entradas de registro são instâncias do tipo LogEntry. O identificador que é (ou começa) do lado esquerdo de uma comparação precisa ter um campo definido no tipo LogEntry. Para detalhes sobre os possíveis identificadores e os valores correspondentes, consulte o tipo LogEntry.

Esta é a lista atual de campos de entrada de registro. Cada campo é seguido do próximo nível de nomes desse campo, se aplicável:

  • httpRequest: {cacheFillBytes, cacheHit, cacheLookup, cacheValidatedWithOriginServer, latency, protocol, referer, remoteIp, requestMethod, requestSize, requestUrl, responseSize, serverIp, status, userAgent}
  • insertId
  • jsonPayload {variável}
  • labels {variável}
  • logName
  • metadata { systemLabels, userLabels }
  • operation{ id, producer, first, last }
  • protoPayload {@type, variável}
  • receiveTimestamp
  • resource { type, labels }
  • severity
  • sourceLocation: { file, line, function }
  • spanId
  • textPayload
  • timestamp
  • trace

Você verá abaixo exemplos de identificadores de caminho de campo que podem ser usados nas comparações:

  • resource.type: se seu primeiro identificador de caminho for resource, o próximo identificador precisa ter um campo no tipo MonitoredResource.

  • httpRequest.latency: se seu primeiro identificador de caminho for httpRequest, o próximo identificador precisa ter um campo no tipo HttpRequest.

  • labels.[KEY] Se seu primeiro identificador de caminho for labels, o próximo identificador, [KEY], precisa ter uma das chaves dos pares de valor-chave que aparecem no campo labels.

  • logName: como o campo logName é uma string, não é possível segui-lo pelos nomes dos subcampos.

Ao consultar campos de mapa ou estrutura, você precisa preservar as letras minúsculas e maiúsculas e a formatação das chaves da expressão.

Por exemplo, jsonPayload é um campo de estrutura. Portanto, um nome de campo aninhado dentro de jsonPayload como jsonPayload.end_time é diferente de jsonPayload.endTime. Da mesma forma, para um campo de mapa como labels, a chave de rótulo labels.env_name é diferente de labels.envName. Por outro lado, ao consultar o campo de buffer de protocolo regular protoPayload, você não precisa preservar maiúsculas e minúsculas.

Para informações sobre os tipos de campo LogEntry, consulte a referência de google.logging.v2.

Caracteres especiais

Se um campo LogEntry contiver caracteres especiais, o campo de registro precisará estar entre aspas. Exemplo:

jsonPayload.":name":apple

jsonPayload."foo.bar":apple

jsonPayload."\"foo\"":apple

Para a lista de caracteres especiais, consulte a seção string em Valores e conversões.

Para mais informações sobre como usar identificadores de caminho de campo que fazem referência a objetos ou matrizes, consulte Tipos de matriz e de objeto neste documento.

Tipos de recursos monitorados

Para consultas mais rápidas, especifique um tipo de recurso monitorado. Para uma lista de tipos de recursos, consulte Tipos de recursos monitorados.

Por exemplo, as VMs do Compute Engine usam o tipo de recurso gce_instance e o uso de instâncias do Amazon EC2 aws_ec2_instance. Veja no exemplo a seguir como limitar as consultas para os dois tipos de VMs:

resource.type = ("gce_instance" OR "aws_ec2_instance")

Os valores do tipo de recurso monitorados nos registros são indexados. O uso de correspondências de substring para eles resulta em consultas mais lentas.

Campos ausentes

Se você usar um nome de campo em uma consulta e esse campo não aparecer em uma entrada, o campo será ausente, indefinido ou padrão:

  • Se o campo fizer parte do payload da entrada de registro (jsonPayload ou protoPayload) ou se ele estiver em um rótulo na seção labels da entrada de registro, o campo, então, é ausente. Usar um campo ausente não exibirá um erro, mas todas as comparações que usem campos ausentes apresentarão uma falha silenciosa.

    Por exemplo: jsonPayload.nearest_store, protoPayload.name.nickname

  • Se estiver definido no tipo LogEntry, o campo será padronizado. As comparações seriam realizadas como se o campo estivesse presente e tivesse o valor padrão.

    Por exemplo: httpRequest.remoteIp, trace, operation.producer

  • Caso contrário, o campo é indefinido, que é um erro detectado antes de a consulta ser usada.

    Por exemplo: thud, operation.thud, textPayload.thud

Para testar se há um campo ausente ou padronizado sem testar um determinado valor no campo, use a comparação :*. Por exemplo, a seguinte comparação será bem-sucedida se o campo operation.id estiver explicitamente presente em uma entrada de registro:

operation.id:*

Observe o comportamento das consultas a seguir:

  • Ao usar o operador booleano NOT em um campo ausente, o resultado será TRUE:

    -- Returns TRUE
    NOT missingField=foo
    
  • Ao usar o operador de comparação diferente != em um campo ausente, o resultado será FALSE:

    -- Returns FALSE
    missingField!=foo
    

Tipos de objetos e matrizes

Cada campo de entrada de registro pode conter um escalar, um objeto ou uma matriz.

  • Um campo escalar armazena um único valor, como 174.4 ou -1. Um string também é considerado um escalar. Os campos que podem ser convertidos em (ou de) uma string, como Duration e Timestamp, também são tipos escalares.

  • Um tipo de objeto armazena uma coleção de valores nomeados, como o seguinte valor JSON:

    {"age": 24, "height": 67}
    

    Consulte o valor dentro de um objeto. Por exemplo, se jsonPayload.x continha o valor anterior, jsonPayload.x.age teria o valor 24.

  • Um campo de matriz armazena uma lista de valores, todos do mesmo tipo. Por exemplo, um campo com medições pode ter uma matriz de números:

    {8.5, 9, 6}
    

    Quando as comparações são realizadas e [FIELD_NAME] é um campo de matriz, cada membro da matriz é comparado a [VALUE] e os resultados são unidos usando o operador OR. Por exemplo, se jsonPayload.shoeSize é um campo de matriz que armazena {8.5, 9, 6}, a comparação:

    jsonPayload.shoeSize < 7
    

    é equivalente a:

    8.5 < 7 OR 9 < 7 OR 6 < 7
    

    Neste exemplo, a comparação geral é avaliada como bem-sucedida.

Valores e conversões

O primeiro passo na avaliação de uma comparação é converter o valor do lado direito para o tipo do campo de entrada de registro. Tipos de campo escalares são permitidos em comparações, junto com dois tipos adicionais que têm os valores representados como strings: Duration e Timestamp. Para uma lista de tipos escalares, consulte a lista de tipos de buffer de protocolo escalar. A tabela a seguir explica quais valores podem ser convertidos para os tipos de campo de registro:

Tipo de campo Valor de consulta permitido
bool

"True" ou "false" em letras minúsculas ou maiúsculas. Exemplos: "True", "true"

bytes

Uma string contendo qualquer sequência de bytes. Exemplo: "\377\377".

Duration

Uma string que contém um número decimal assinado seguido de uma das unidades "ns", "us", "ms", "s", "m" ou "h". As durações são medidas com precisão até a casa dos nanossegundos. Exemplo: "3.2s".

enum

O nome de um tipo de enumeração literal, indiferente a maiúsculas. Exemplos: "WARNING", que é um valor do tipo LogSeverity.

double

Qualquer número, com ou sem sinal e uma parte expoente, ou as strings de valor especial "NaN", "-Infinity" e "Infinity" (em letras maiúsculas ou não). Exemplos: "-3.2e-8", "nan".

intNN

Qualquer inteiro assinado que não exceda o tamanho do tipo. Exemplo: "-3".

string

Qualquer string que contenha texto codificado em UTF-8 ou ASCII de 7 bits. Aspas incorporadas precisam ser precedidas de uma barra invertida.

Os valores de string precisam estar entre aspas duplas para evitar os seguintes caracteres especiais:

  • Strings que começam com + (mais), - (menos) ou . (ponto).

  • Strings com ~ (til), = (igual a), () (parênteses), : (dois pontos), > (maior que), < (menor que), , (vírgula), . (ponto) ou * (asterisco).

  • Qualquer sequência de escape, por exemplo \t.

Timestamp

Uma string no formato RFC 3339 ou ISO 8601. Examples&colon; "2014-10-02T15&colon;01&colon;23.045Z" (RFC 3339), "2014-10-02" (ISO 8601). Em expressões de consulta, os carimbos de data/hora no formato RFC 3339 podem especificar um fuso horário com "Z" ou ±hh:mm. Os carimbos de data/hora são representados com precisão de nanosegundos.

uintNN

Qualquer inteiro não assinado que não exceda o tamanho do tipo. Exemplo: "1234".

Se ocorrer erro na tentativa de conversão, a comparação falhará.

Quando uma conversão exigir uma string, também será possível usar um número ou um texto sem aspas se eles não contiverem caracteres especiais, como espaços e operadores. Da mesma maneira, quando uma conversão exigir um número, será possível usar uma string com um conteúdo que seja número.

Os tipos intNN e uintNN representam tipos inteiros de vários tamanhos, como int32 e uint64. Os valores que serão convertidos em tipos de números inteiros de 64 bits precisam ser gravados como strings. Por exemplo: "9223372036854775807".

Tipos de campos de registro

Veja como o tipo de um campo de entrada de registro é determinado:

  • Os campos de registro definidos no tipo LogEntry e no tipo de componente são campos do buffer de protocolo. Os campos de buffer de protocolo têm tipos explícitos.

  • Os campos de registro que fazem parte de objetos protoPayload também são campos de buffer de protocolo e têm tipos explícitos. O nome do tipo de buffer de protocolo é armazenado no campo "@type" de protoPayload. Para mais informações, veja o mapeamento JSON.

    Ao filtrar um campo associado ao tipo de mensagem Any, o campo value é transferido automaticamente. Portanto, não a inclua na consulta. Para mais informações, consulte Solução de problemas.

  • Os campos de registro dentro de jsonPayload têm tipos que são inferidos do valor do campo quando a entrada de registro é recebida:

    • Os campos com valores são números sem aspas e têm tipo double.
    • Os campos com valores são true ou false e têm tipo bool.
    • Os campos com valores que são strings com tipo string.

    Os inteiros longos (64 bits) são armazenados em campos de string, porque não podem ser representados exatamente como valores double.

  • Os tipos Duration e Timestamp só são reconhecidos em campos de buffer de protocolo. Em outros lugares, esses valores são armazenados em campos de string.

Comentários

Os comentários começam com dois traços (--), e qualquer texto após os traços é ignorado até o final da linha. Os comentários podem ser colocados no início, entre termos e no final de um filtro.

Use comentários para os seguintes casos:

  • Para anotar seus filtros complexos com informações sobre o que uma cláusula faz:

     -- All of our target users are emitted by Compute Engine instances.
     resource.type = "gce_instance"
     -- Looking for logs from "alex".
     jsonPayload.targetUser = "alex"

  • Para ativar ou desativar uma cláusula rapidamente adicionando ou removendo o prefixo do comentário:

     resource.type = "gce_instance"
     -- jsonPayload.targetUser = "alex"
     jsonPayload.targetUser = "kiran"
     -- jsonPayload.targetUser = "sasha"

Operadores de comparação

O significado dos operadores de igualdade (=, !=) e desigualdade (<, <=, >, >=) depende do tipo subjacente do lado esquerdo nome do campo.

  • Todos os tipos numéricos: os símbolos de igualdade e desigualdade têm significado normal para os números.
  • bool: igualdade significa o mesmo valor booliano. A desigualdade é definida por true > false.
  • enum: igualdade significa o mesmo valor de enumeração. A desigualdade usa os valores numéricos subjacentes dos literais de enumeração.
  • Duration: igualdade significa a mesma duração de duração. A desigualdade se baseia no comprimento da duração. Por exemplo: como durações, "1s" > "999ms".
  • Timestamp: igualdade significa o mesmo instante no tempo. Se a e b forem valores Timestamp, a < b significa a é anterior a b.
  • bytes: os operandos são comparados de byte a byte, da esquerda para a direita.
  • string: as comparações ignoram letras maiúsculas e minúsculas. Mais especificamente, primeiro os dois operandos passam pelo processo de normalização unicode NFKC_CF. Depois, usam comparações lexicográficas. No entanto, as pesquisas de expressões regulares não são normalizadas. Para mais informações sobre como pesquisar entradas de registro usando expressões regulares, consulte Como usar expressões regulares.

O operador substring (:) é aplicável a string e bytes e é tratado como igualdade, com a diferença de que o operando à direita só precisa se igualar a parte do campo à esquerda. As correspondências de substring em campos indexados não aproveitam os índices de registro.

Restrições globais

Se a comparação consistir em um único valor, é chamada de restrição global. O Logging usa o operador has (:) para determinar se algum campo em uma entrada de registro ou o respectivo payload contém a restrição global. Se isso acontecer, a comparação será bem-sucedida.

A consulta mais simples gravada em termos de uma restrição global é um valor único:

"The Cat in The Hat"

É possível combinar restrições globais usando os operadores AND e OR para uma consulta mais interessante. Por exemplo, se você desejar exibir todas as entradas de registro que tenham um campo que contenha cat e um campo que contenha hat ou bat, escreva a consulta como:

("cat" AND ("hat" OR "bat"))

Nesse caso, há três restrições globais: cat, hat e bat. Essas restrições globais são aplicadas separadamente e os resultados são combinados, como se a expressão tivesse sido escrita sem parênteses.

Uma restrição global é uma maneira fácil de consultar os registros em busca de um valor específico. Por exemplo, se você estiver procurando em seu registro de atividades por entradas contendo qualquer menção de GCE_OPERATION_DONE, é possível usar a seguinte consulta:

logName = "projects/my-project-id/logs/compute.googleapis.com%2Factivity_log" AND
"GCE_OPERATION_DONE"

Embora as restrições globais sejam fáceis, elas podem ser lentas. Para mais informações, consulte Como encontrar entradas de registro rapidamente neste documento.

Funções

Use funções integradas como restrições globais nas consultas:

function = identifier ( [ argument { , argument } ] )

onde argument é um valor, um nome de campo ou um parênteses expressão. As funções são descritas nas seções a seguir.

log_id

A função log_id retorna entradas de registro que correspondem ao argumento [LOG_ID] indicado no campo logName:

log_id([LOG_ID])

Por exemplo, a consulta a seguir retorna todas as entradas de registro com cloudaudit.googleapis.com%2Factivity [LOG_ID]:

log_id("cloudaudit.googleapis.com/activity")

transmitir

A função cast aceita dois parâmetros: o campo LogEntry a ser convertido e o tipo de dados em que o campo é convertido:

cast([FIELD], [TYPE][, OPTION])

Os parâmetros da expressão anterior são definidos da seguinte maneira:

  • [FIELD]: o nome de um campo na entrada de registro, como logName ou jsonPayload.a_field.

  • [TYPE]: o tipo de dados, como STRING, INT64, FLOAT64, BOOL.

Por exemplo, a consulta a seguir converte o campo timestamp em uma STRING e especifica o fuso horário America/New_York:

cast(timestamp, STRING, TIMEZONE("America/New_York")) =~ "^2023-01-02.*"

regexp_extract

Use a função regexp_extract para encontrar a primeira substring que corresponda a uma expressão regular:

REGEXP_EXTRACT([FIELD], [REGULAR_EXPRESSION])

Na expressão anterior, os campos são definidos da seguinte maneira:

  • [FIELD]: o nome de um campo na entrada de registro, como logName ou jsonPayload.a_field.
  • [REGULAR_EXPRESSION]: a expressão regular RE2 que precisa conter um grupo de captura ((...)). Um grupo que não seja de captura (?:...) precisará ser usado se for necessário um agrupamento adicional para a expressão regular. Vários grupos de captura ou nenhum grupo de captura resultam em erro.

É possível encadear as funções cast e regexp_extract:

CAST(REGEXP_EXTRACT(CAST(timestamp, STRING), "\\d+:\\d+:\\d+\\.(\\d+)"), INT64) < 500

O exemplo anterior converte o campo timestamp como uma string. A expressão regular captura a parte de milissegundos da string timestamp e a converte em um número inteiro para realizar uma comparação numérica. Todas as entradas de registro com carimbos de data/hora em que o campo de milissegundos é menor que 500 são retornadas.

source

A função source corresponde a entradas de registro de um recurso específico nas organizações, pastas e hierarquia de projetos do Google Cloud.

A função source não corresponde aos recursos filhos. Por exemplo, o uso de source(folders/folder_123) corresponde aos registros do recurso folder_123, e não aos registros dos recursos do projeto do Google Cloud em folder_123.

Para consultar registros em um nível de recurso específico, use a seguinte sintaxe:

source(RESOURCE_TYPE/RESOURCE_ID)
Resource Exemplo de consulta
Organização source(organizations/ORGANIZATION_ID)
Pasta source(folders/FOLDER_ID)
Projetos do Google Cloud source(projects/PROJECT_ID)

amostra

A função sample seleciona uma fração do número total de entradas de registro:

sample([FIELD], [FRACTION])

[FIELD] é o nome de um campo na entrada de registro, como logName ou jsonPayload.a_field. O valor do campo determina se a entrada do registro estará na amostra. O tipo de campo precisa ser uma string ou um valor numérico. Definir [FIELD] como insertId é uma boa escolha, porque cada entrada de registro tem um valor diferente para esse campo.

[FRACTION] é a fração de entradas de registro que têm valores para [FIELD] a serem incluídos. É um número maior do que 0,0 e não superior a 1,0. Por exemplo, se você especificar 0.01, a amostra conterá aproximadamente 1% de todas as entradas de registro com valores para [FIELD]. Se [FRACTION] for 1, todas as entradas de registro que tenham valores para [FIELD] serão escolhidas.

Por exemplo: a consulta a seguir retorna 25% das entradas de registro do log syslog:

logName = "projects/my-project/logs/syslog" AND sample(insertId, 0.25)

Detalhes: um algoritmo determinístico, baseado em hash, é usado para determinar se uma entrada de registro está incluída na amostra ou excluída dela. A precisão da amostra resultante depende da distribuição dos valores em hash. Se os valores em hash não forem distribuídos uniformemente, a amostra resultante poderá estar distorcida. No pior dos casos, quando [FIELD] sempre contém o mesmo valor, a amostra resultante contém a [FRACTION] de todas as entradas de registro ou nenhuma entrada de registro.

Se [FIELD] aparecer em uma entrada de registro:

  • será calculado um hash do valor;
  • o valor em hash, que é um número, será dividido pelo valor máximo possível de hash;
  • se a fração resultante for menor que ou igual a [FRACTION], a entrada de registro será incluída na amostra. Caso contrário, ela será excluída da amostra.

Se [FIELD] não aparecer em uma entrada de registro:

  • Se [FIELD] fizer parte da seção de payload da entrada de registro ou labels, a entrada de registro não será selecionada para a amostra, mesmo que [FRACTION] seja 1.
  • caso contrário, a entrada de registro seria tratada como se [FIELD] estivesse na entrada de registro e o valor de [FIELD] fosse o valor padrão. O valor padrão é determinado pelo tipo LogEntry. Para mais informações sobre campos ausentes e padrão, consulte Campos ausentes neste documento.

Para excluir entradas de registro com campos padronizados da amostra, use o operador de verificação de campo, :*. A consulta a seguir produz uma amostra de 1% de entradas de registro que forneceram explicitamente um valor para field:

field:* AND sample(field, 0.01)

ip_in_net

A função ip_in_net determina se um endereço IP em uma entrada de registro está contido em uma sub-rede. É possível usá-la para saber se uma solicitação vem de uma fonte interna ou externa. Exemplo:

ip_in_net([FIELD], [SUBNET])

[FIELD] é um campo com valor de string na entrada de registro em que há um intervalo ou endereço IP. O campo pode ser repetido e, nesse caso, apenas um deles terá um endereço ou intervalo contido na sub-rede.

[SUBNET] é uma constante de string para um intervalo ou endereço IP. Será um erro se [SUBNET] não for um intervalo ou endereço IP válido, conforme descrito mais adiante nesta seção.

Por exemplo: a consulta a seguir testa um endereço IP no payload das entradas de registro do registro my_log:

logName = "projects/my_project/logs/my_log" AND
ip_in_net(jsonPayload.realClientIP, "10.1.2.0/24")

Detalhes: se [FIELD] estiver ausente, padronizado ou não contiver um intervalo ou endereço IP válido em uma entrada de registro, a função retornará "false". Para mais informações sobre campos ausentes e padrão, consulte Campos ausentes neste documento.

Veja a seguir alguns exemplos de endereços IP e intervalos compatíveis:

  • IPv4: 10.1.2.3
  • Sub-rede IPv4: 10.1.2.0/24
  • CIDR IPv6: 1234:5678:90ab:cdef:1234:5678:90ab:cdef
  • Sub-rede CIDR IPv6: 1:2::/48

Função SEARCH

Use a função integrada SEARCH para encontrar strings nos dados de registro:

SEARCH([query])
SEARCH([field], [query])

Ambas as formas da função SEARCH contêm um argumento query, que precisa ser formatado como um literal de string. Na primeira forma, toda a entrada de registro é pesquisada. Na segunda, você especifica o campo da entrada a ser pesquisado.

Especifique o campo query. Se esse campo não for especificado, será retornado um erro.

Quando a função SEARCH é processada, a string query é processada por um analisador de texto que a divide em tokens. O Cloud Logging sempre faz comparações indiferentes a maiúsculas, mesmo para tokens encapsulados com acentos graves. Esse comportamento é diferente do BigQuery, que preserva a capitalização em tokens agrupados com acentos graves. Para informações sobre as regras do analisador, consulte o documento Regras do analisador de texto do BigQuery.

Ao criar uma pesquisa, considere o seguinte:

  • Os tokens não diferenciam maiúsculas de minúsculas. As funções a seguir produzem os mesmos resultados:

    SEARCH("world")
    SEARCH("World")
    

    As funções anteriores correspondem a uma entrada de registro quando um único campo contém o token "world". Como SEARCH executa correspondências exatas e não correspondências de substring, as funções anteriores não correspondem a um campo cujo valor é "worldwide".

  • Se você não especificar o campo a ser pesquisado, a função SEARCH corresponderá a uma entrada de registro quando ela contiver todos os tokens. No entanto, a ordem dos tokens não importa, e eles não precisam ser encontrados no mesmo campo da entrada de registro.

    As funções a seguir produzem os mesmos resultados e correspondem a uma entrada de registro que contém os tokens "hello" e "world":

    SEARCH("hello world")
    SEARCH("World hello")
    
  • Se você especificar o campo a ser pesquisado, a função SEARCH pesquisará apenas esse campo. Uma correspondência ocorre quando esse campo contém todos os tokens. No entanto, a ordem deles não importa.

    As funções a seguir produzem uma correspondência apenas quando o campo textPayload contém os tokens "hello" e "world":

    SEARCH(textPayload, "hello world")
    
  • Para impor uma correspondência exata, mas que não diferencia maiúsculas de minúsculas em uma frase, coloque a frase entre crases. Por exemplo, as funções a seguir correspondem à string "hello world":

    SEARCH("`hello world`")
    SEARCH("`Hello World`")
    SEARCH("`HELLO WORLD`")
    

    Como os acentos graves são usados nas seguintes funções, eles produzem resultados diferentes:

    SEARCH("`hello world`")
    SEARCH("`world hello`")
    

A linguagem de consulta do Logging oferece várias maneiras de pesquisar dados de registro. Para pesquisar uma string, é mais eficiente usar a função SEARCH do que realizar uma pesquisa global ou de substring. No entanto, não é possível usar a função SEARCH para corresponder campos que não sejam de texto. Para orientações sobre como realizar operações de pesquisa, consulte Minimizar pesquisas globais e de substrings.

Como pesquisar por tempo

Na interface, é possível definir limites específicos relacionados à data e hora das entradas de registro a serem exibidas. Por exemplo, se você adicionar as seguintes condições à consulta, a visualização exibirá exatamente as entradas de registro no período de 30 minutos indicado, e não será possível rolar para fora desse período:

timestamp >= "2016-11-29T23:00:00Z"
timestamp <= "2016-11-29T23:30:00Z"

Ao escrever uma consulta com carimbo de data/hora, você precisa usar datas e horas no formato mostrado acima.

Também é possível pesquisar entradas de registro usando atalhos timestamp. Por exemplo, você consegue inserir uma data com um operador de comparação para gerar todas as entradas de registro após um determinado dia:

timestamp > "2016-11-29"

Como usar expressões regulares

É possível usar expressões regulares para criar consultas e filtros para coletores, métricas e onde mais os filtros de registro forem usados. Há a opção de usar expressões regulares no Criador de consultas e com a Google Cloud CLI.

Uma expressão regular é uma sequência de caracteres que define uma pesquisa. A linguagem de consulta do Logging usa a sintaxe RE2. Para uma explicação completa da sintaxe RE2, consulte a wiki da RE2 no GitHub.

As consultas de expressão regular têm as seguintes características:

  • Somente campos do tipo string podem ter correspondência com uma expressão regular.

  • A normalização de strings não é realizada. Por exemplo, kubernetes não é considerado igual a KUBERNETES. Para mais informações, consulte a seção Operadores de comparação.

  • As consultas diferenciam maiúsculas de minúsculas e não são ancoradas por padrão.

  • É possível usar os operadores booleanos entre várias expressões regulares no lado direito do operador de comparação de expressões regulares, =~ e !~.

Uma consulta de expressão regular tem a seguinte estrutura:

Corresponde a um padrão:

jsonPayload.message =~ "regular expression pattern"

Não corresponde a um padrão:

jsonPayload.message !~ "regular expression pattern"

=~ e !~ alteram a consulta para uma consulta de expressão regular, e o padrão que você está tentando corresponder precisa estar entre aspas duplas. Para consultar padrões que contêm aspas duplas, faça o escape deles usando uma barra invertida.

Exemplos de como consultar registros usando expressões regulares

Tipo de consulta Exemplo
Consulta padrão sourceLocation.file =~ "foo"
Consulta com pesquisa que não diferencia maiúsculas de minúsculas labels.subnetwork_name =~ "(?i)foo"
Consulta que contém aspas jsonPayload.message =~ "field1=\"bar.*\""
Consulta que usa um or booleano labels.pod_name =~ "(foo|bar)"
Consulta com o uso de âncoras logName =~ "/my%2Flog$"
Consulta que não corresponde a um padrão labels.pod_name !~ "foo"
Consulta com o uso de operador booleano labels.env =~ ("^prod.*server" OR "^staging.*server")
Consulta que começa com um valor logName =~ "^foo"
Consulta que termina com um valor logName =~ "foo$"

Como encontrar entradas de registro rapidamente

Para encontrar entradas de registro de forma mais eficiente, faça o seguinte:

  • consulte usando campos indexados;
  • minimize o número de entradas de registro a serem pesquisadas.

Usar campos indexados

O Logging sempre indexa os seguintes campos LogEntry:

Também é possível adicionar campos indexados personalizados a qualquer bucket de registros.

As próximas seções explicam como usar campos indexados para minimizar o número de entradas de registro a serem pesquisadas.

Otimizar suas consultas

Para tornar as pesquisas mais rápidas, reduza o número de registros, o número de entradas de registros ou o tempo das pesquisas. Melhor ainda, é possível reduzir os três.

Exemplo: use o nome de registro correto

Especifique o registro que contenha as entradas do seu interesse. Verifique uma das entradas de registro para confirmar o nome do registro real. Por exemplo, a visualização mostra que há um registro na seção do Compute Engine chamada "atividade". Na inspeção mais detalhada das entradas de registro de atividades do administrador, o registro é chamado de "cloudaudit.googleapis.com/activity".

A comparação a seguir está incorreta. Ela não gera correspondências porque usa o nome de registro errado:

logName = "projects/my-project-id/logs/activity"   -- WRONG!

A comparação a seguir está correta. Ela escolhe entradas de registro do registro de auditoria da atividade do administrador. É preciso codificar o nome do registro por URL, como mostrado:

logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"

Exemplo: escolha as entradas de registro corretas

Se souber que as entradas de registro que você quer pertencem a uma determinada instância de VM, especifique-a. Inspecione uma das entradas de registro que quer pesquisar para verificar os nomes corretos dos rótulos. No exemplo a seguir, instance_id é um dos marcadores indexados:

resource.type = "gce_instance" AND
resource.labels.instance_id = "6731710280662790612"
logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"

Exemplo: escolha o período correto

Especifique um período para a pesquisa. Uma maneira rápida de determinar os carimbos de data/hora úteis no formato RFC 3339 é usar o comando Gnu/Linux date:

$ date --rfc-3339=s
2016-06-27 17:39:00-04:00
$ date --rfc-3339=s --date="3 hours ago"
2016-06-27 14:40:00-04:00
$ date --rfc-3339=s --date="5 hours ago"
2016-06-27 12:40:00-04:00

Use os valores desses carimbos de data/hora nas consultas a seguir. Para criar um carimbo de data/hora aceitável para o Logging, substitua o espaço entre a data e a hora pela letra T.

Por exemplo, para pesquisar nas últimas três horas:

timestamp >= "2016-06-27T14:40:00-04:00"

Como outro exemplo, para procurar entre três e cinco horas atrás:

timestamp >= "2016-06-27T12:40:00-04:00" AND
timestamp <= "2016-06-27T14:40:00-04:00"

Minimizar as pesquisas globais e de substring

Evite a tentação de usar atalhos ao digitar consultas de registro.

Exemplo: não use pesquisas globais

Se você está pesquisando uma entrada de registro que contém "Hello, Kitty" no payload:

  • Não use uma pesquisa global. Por um motivo, todas são pesquisas de substring:

       "Hello Kitty"   -- THIS CAUSES A SLOW SEARCH!
       

  • Limite a pesquisa a um único campo, mesmo se tiver que manter a pesquisa de substring:

       textPayload:"Hello Kitty"
       

  • Use um teste de igualdade, se possível:

       textPayload = "Hello Kitty"
       

  • Faça referência a campos individuais em um payload se as entradas de registro tiverem payloads estruturados:

       jsonPayload.my_favorite_cat = "Hello Kitty"
       

  • Use um campo indexado para restringir a pesquisa:

       logName = "projects/my-project_id/logs/somelog" AND
       jsonPayload.my_favorite_cat = "Hello Kitty"
       

  • Use a função SEARCH e especifique o texto completo para fazer a correspondência. A função SEARCH executa uma correspondência indiferente a maiúsculas:

      SEARCH("Hello Kitty")
      

    Não use a função SEARCH e especifique texto parcial. Por exemplo, a função a seguir não corresponde a "Hello Kitty".

      SEARCH("Hello Kit")
      

Como pesquisar exemplos

As entradas de registro mostradas são aquelas que correspondem a uma consulta. Se o menu Pular para data contiver um valor, a tela rolará para esse ponto no tempo. Veja alguns exemplos de consulta:

resource.type=gae_app

Encontra todas as entradas de registro do App Engine. Veja uma lista de tipos de recurso em Lista de recursos monitorados.

Conforme você digita, a visualização sugere conclusões para campos como resource.type.

resource.type=gae_app AND logName:request_log

Encontra entradas de registro para apps do App Engine a partir de nomes de registros que contenham request_log. Leve isto em conta:

  • O operador = se refere à igualdade exata. O tipo de recurso precisa ter exatamente "gae_app", exceto letras maiúsculas e minúsculas.
  • O operador :: significa "has". O campo logName precisa conter request_log, em qualquer letra maiúscula. O nome real do registro é muito mais longo. Usar : pode resultar em pesquisas mais lentas.
  • As duas comparações são unidas por AND. Também é possível usar OR, mas AND será considerado se você não incluir o operador.
resource.type = (gce_instance OR aws_ec2_instance) AND severity >= ERROR

Localiza entradas de registro com dois tipos de recursos: instância de VM do Compute Engine ou instância de VM do AWS EC2. As entradas de registro precisam ter severity pelo menos ERROR, o que equivale a selecionar ERROR no menu de gravidade da interface de consulta básica.

logName = "projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"

Encontra todas as entradas de registro de auditoria da Atividade do administrador no projeto [PROJECT_ID]. Os registros de auditoria usam o mesmo nome em um projeto, mas têm tipos de recurso diferentes. O código do registro, cloudaudit.googleapis.com/activity precisa ser codificado pelo URL no nome do registro. Usar a igualdade na comparação acelera a pesquisa. Para mais informações, consulte Noções básicas sobre registros de auditoria.

unicorn

Encontra entradas de registro contendo unicorn em qualquer campo, em qualquer letra maiúscula. Um termo de pesquisa que não faz parte de uma comparação de campo é uma consulta de "todos os campos".

unicorn phoenix

Encontra entradas de registro que contêm unicorn em algum campo e phoenix em algum campo.

textPayload:(unicorn phoenix)

Encontra entradas de registro com o campo textPayload que contém unicorn e phoenix em qualquer ordem, o AND está implícito entre as duas palavras.

textPayload:"unicorn phoenix"

Encontra entradas de registro com o campo textPayload que contém a string "unicorn phoenix".

NOT textPayload: "unicorn phoenix"

Localiza as entradas de registro em que o campo textPayload não contém a string "unicorn phoenix". Esse tipo de consulta reduz entradas de registro indesejadas.

timestamp >= "2016-11-29T23:00:00Z" timestamp <= "2016-11-29T23:30:00Z"

Encontra entradas de registro dentro de um período de 30 minutos.

Solução de problemas

Problemas de sintaxe

Se você tiver problemas com as expressões de suas consultas, verifique o seguinte:

  • Sua consulta obedece às regras de sintaxe, com parênteses correspondentes e aspas.

  • Os nomes dos campos de entrada de registro estão escritos corretamente.

  • As operações booleanas estão em maiúsculas (AND, OR, NOT).

  • Verifique se você está usando NULL_VALUE para representar valores nulos JSON.

  • As expressões booleanas como restrições globais ou como o lado direito das comparações precisam estar entre parênteses para maior clareza. Por exemplo, as duas consultas abaixo têm a mesma aparência, mas não são:

    insertId = "ABC-1" OR "ABC-2"  -- ERROR!?
    insertId = ("ABC-1" OR "ABC-2")
    
  • Com texto sem aspas, não pode haver nenhum caractere especial. Em caso de dúvida, adicione aspas duplas. Por exemplo, a primeira comparação abaixo é ilegal por causa do operador de substring incorporado (:). A comparação precisa ser escrita com aspas:

    insertId = abc:def  -- ILLEGAL!
    insertId = "abc:def"
    
  • A Google Cloud CLI exige que a consulta esteja entre aspas duplas. Para usar aspas duplas com a finalidade de fazer o escape de caracteres especiais usando o comando gcloud logging, agrupe a consulta inteira com aspas simples:

    gcloud logging read 'resource.type=gce_instance AND jsonPayload.message="Stopped Unattended Upgrades Shutdown."'
    gcloud logging read 'timestamp>="2020-06-17T21:00:00Z"'
    

  • Ao filtrar um campo associado ao tipo de mensagem Any, o campo value é transferido automaticamente. Portanto, não inclua value na consulta.

    Por exemplo, o campo Status em uma mensagem AuditLog tem um campo details do tipo google.protobuf.Any. Para consultar o campo details, omita o campo value ao especificar o filtro:

    • O que fazer

      protoPayload.status.details.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"
      
    • O que não fazer

      protoPayload.status.details.value.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"