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 no Explorador 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 criar filtros para 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 do Google Cloud selecionado, 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 = "k8s_cluster"
Restrição conjuntiva:
resource.type = "k8s_cluster" AND severity = "ERROR"
Restrição disjuntiva:
resource.type = "k8s_cluster" OR resource.type = "gce_instance"
- Como alternativa:
resource.type = ("k8s_cluster" OR "gce_instance")
- Como alternativa:
Expressão conjuntiva/disjuntiva complexa:
resource.type = "k8s_cluster" AND (severity = "ERROR" OR "error")
Confira a seguir um exemplo 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 texto explicativo.
Observe o seguinte:
O tamanho de uma consulta não pode exceder 20.000 caracteres.
A linguagem de consulta de geração de registros não diferencia maiúsculas de minúsculas, com exceção das 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 = "k8s_cluster"
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]
. Uma comparação tem três componentes:
[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,"k8s_cluster"
. Para valores nulos JSON, useNULL_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 os usados por visualizações de registro, é possível usar os operadores AND
, OR
e NOT
. As visualizações de registro só oferecem suporte a operações AND
e
NOT
.
Para combinar as regras AND
e OR
na mesma expressão, aninhe as regras usando parênteses. Se você não usar parênteses, a consulta pode não
funcionar conforme o esperado.
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]
Uma comparação tem três componentes:
[FIELD_NAME]: é o identificador do caminho de um campo em uma entrada de registro. Confira abaixo alguns exemplos desses identificadores:
resource.type resource.labels.zone resource.labels.project_id insertId jsonPayload.httpRequest.protocol labels."compute.googleapis.com/resource_id"
Se um componente de um identificador de caminho de campo tiver caracteres especiais, ele precisará 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, useNULL_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 o primeiro identificador de caminho for
resource
, o próximo identificador precisará ter um campo no tipoMonitoredResource
.httpRequest.latency: se o primeiro identificador de caminho for
httpRequest
, o próximo identificador precisará ter um campo no tipoHttpRequest
.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 campolabels
.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
ouprotoPayload
) ou se ele estiver em um rótulo na seçãolabels
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 o campo for definido no tipo
LogEntry
, ele 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
. Umstring
também é considerado um escalar. Os campos que podem ser convertidos em (ou de) uma string, comoDuration
eTimestamp
, 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 valor24
.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 operadorOR
. Por exemplo, sejsonPayload.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 conferir uma lista de tipos escalares, consulte a
lista de tipos escalares para buffer de protocolo. 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:
|
Timestamp |
Uma string no formato
RFC 3339
ou ISO 8601.
Exemplos: "2024-08-02T15:01:23.045Z" (RFC 3339),
"2024-08-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 |
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"
deprotoPayload
. Para mais informações, veja o mapeamento JSON.Quando você filtra um campo associado ao tipo de mensagem
Any
, o campovalue
é percorrido 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
oufalse
e têm tipobool
. - 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 campos com valores são números sem aspas e têm tipo
Os tipos
Duration
eTimestamp
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 de um filtro, entre termos e no final de um filtro.
Você pode usar comentários nos seguintes casos:
Para fazer anotações nos 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 rapidamente uma cláusula adicionando ou removendo o prefixo de 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 portrue
>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 valoresTimestamp
, 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"
Em vez de usar restrições globais, que podem ser lentas, recomendamos
que você use a
função SEARCH
integrada
e consulte campos indexados. Para mais informações,
consulte Como encontrar entradas de registro rapidamente neste documento.
remotas
Use funções integradas como restrições globais nas consultas:
function = identifier ( [ argument { , argument } ] )
em que argument
é um valor, um nome de campo ou uma expressão entre parênteses.
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")
elenco
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, comologName
oujsonPayload.a_field
.[TYPE]
: o tipo de dados, comoSTRING
,INT64
,FLOAT64
,BOOL
.TIMESTAMP
ouDURATION
: alguns tipos de dados oferecem outras opções, como especificar um fuso horário do banco de dados de fuso horário da IANA para o tipo de dadosTIMESTAMP
.
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 corresponde 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, comologName
oujsonPayload.a_field
.[REGULAR_EXPRESSION]
: a expressão regular RE2 que precisa conter um grupo de captura ((...)
). Um grupo não de captura(?:...)
precisa ser usado se um agrupamento adicional for necessário para a expressão regular. Vários grupos de captura ou a ausência de grupos de captura resultam em um 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 transmite 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 que contêm
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 na
hierarquia de projetos do Google Cloud, organizações e pastas.
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 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)
Recurso | 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 oulabels
, 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 tipoLogEntry
. 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. Por 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, a entrada de registro inteira é
pesquisada. Na segunda, você especifica o campo da entrada a ser pesquisado.
Especifique o campo query
. Se esse campo não for especificado, um
erro será retornado.
Quando a função SEARCH
é processada, a string query
é processada por
um analisador de texto que divide a string em tokens. O Cloud Logging sempre
realiza comparações sem distinção entre maiúsculas e minúsculas, mesmo para tokens
encapsulados com chaves invertidas. Esse comportamento é diferente do BigQuery,
que preserva a caixa alta em tokens envolvidos com chaves invertidas.
Para saber mais sobre as regras do analisador, consulte o documento do BigQuery
Regras do analisador de texto.
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 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
vai 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
só vai pesquisar esse campo. Uma correspondência ocorre quando esse campo contém todos os tokens. No entanto, a ordem dos tokens não importa.As funções a seguir produzem uma correspondência somente quando o campo
textPayload
contém os tokens "hello" e "world":SEARCH(textPayload, "hello world")
Para impor uma correspondência exata sem diferenciação entre maiúsculas e minúsculas em uma frase, coloque a frase entre aspas simples. Por exemplo, as funções a seguir correspondem à string "hello world":
SEARCH("`hello world`") SEARCH("`Hello World`") SEARCH("`HELLO WORLD`")
Como os colchetes são usados nas funções a seguir, 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 fazer uma pesquisa global ou de substring.
No entanto, não é possível usar a função SEARCH
para campos que não sejam de texto.
Para orientações sobre como realizar operações de pesquisa, consulte
Minimizar pesquisas globais e de substring.
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 à sua consulta, o painel de resultados vai mostrar exatamente as entradas de registro no período de 30 minutos indicado, e você não poderá rolar a página fora desse período:
timestamp >= "2023-11-29T23:00:00Z" timestamp <= "2023-11-29T23:30:00Z"
Ao escrever uma consulta com um carimbo de data/hora, você precisa usar datas e horas no formato mostrado anteriormente.
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 > "2023-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. Por exemplo, é possível usar expressões regulares no Explorador de registros e na 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 aKUBERNETES
. 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 eficiente, faça o seguinte:
- consulte usando campos indexados;
- minimize o número de entradas de registro a serem pesquisadas.
Usar campos indexados
O registro sempre indexa os seguintes campos LogEntry
:
- resource.type
- resource.labels.*
- logName
- severity
- timestamp
- insertId
- operation.id
- trace
- httpRequest.status
- labels.*
- split.uid
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.
Otimize 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, você pode 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, o painel de resultados mostra que a seção do Compute Engine contém um registro chamado "activity". 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 2023-06-27 17:39:00-04:00 $ date --rfc-3339=s --date="3 hours ago" 2023-06-27 14:40:00-04:00 $ date --rfc-3339=s --date="5 hours ago" 2023-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 >= "2023-06-27T14:40:00-04:00"
Como outro exemplo, para procurar entre três e cinco horas atrás:
timestamp >= "2023-06-27T12:40:00-04:00" AND timestamp <= "2023-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 correspondência. A funçãoSEARCH
executa uma correspondência que não diferencia maiúsculas de minúsculas:SEARCH("
Hello Kitty
")Não use a função
SEARCH
e especifique um texto parcial. Por exemplo, a função abaixo 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=k8s_cluster
Encontra todas as entradas de registro do Google Kubernetes Engine. Veja uma lista de tipos de recurso em Lista de recursos monitorados.
Conforme você digita, o painel de consulta sugere conclusões para campos como
resource.type
.resource.type=k8s_cluster AND logName:request_log
Encontra entradas de registro para clusters do Google Kubernetes 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"k8s_cluster"
, exceto letras maiúsculas e minúsculas. - O operador
:
: significa "has". O campologName
precisa conterrequest_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 mescladas por
AND
. Também é possível usarOR
, masAND
será usado se você não incluir o operador.
- 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 menosERROR
, 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 ephoenix
em algum campo.textPayload:(unicorn phoenix)
Encontra entradas de registro com o campo
textPayload
que contémunicorn
ephoenix
em qualquer ordem, oAND
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 >= "2023-11-29T23:00:00Z" timestamp <= "2023-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 a seguir têm a mesma aparência, mas não são:
insertId = "ABC-1" OR "ABC-2" -- ERROR!? insertId = ("ABC-1" OR "ABC-2")
O texto sem aspas não pode conter nenhum caractere especial. Em caso de dúvida, adicione aspas duplas. Por exemplo, no exemplo abaixo, a primeira comparação é 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"'
Quando você filtra um campo associado ao tipo de mensagem
Any
, o campovalue
é percorrido automaticamente. Portanto, não incluavalue
na consulta.Por exemplo, o campo
Status
em uma mensagemAuditLog
tem um campodetails
do tipogoogle.protobuf.Any
. Para consultar o campodetails
, omita o campovalue
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.*"