En este documento, se describe de forma general el lenguaje de consulta de registro que usas para consultar y filtrar los datos de Cloud Logging.
Para obtener información detallada sobre el diseño del lenguaje de consulta de Logging, consulta las especificaciones formales de la API de Google para filtrar.
Para ver ejemplos de consultas comunes que te pueden interesar, consulta Consultas de muestra con el Explorador de registros.
Descripción general
Puedes usar el lenguaje de consulta de Logging en el Explorador de registros de la console de Google Cloud, la API de Logging o la interfaz de línea de comandos. Puedes usar el lenguaje de consulta de Logging para consultar datos y escribir filtros para crear receptores y métricas basadas en registros.
Una consulta es una expresión booleana que especifica un subconjunto de todas las entradas de registro en el recurso de Google Cloud seleccionado, como un proyecto o una carpeta de Google Cloud.
Puedes compilar consultas basadas en el LogEntry
campo indexado con los operadores lógicos AND
y OR
.
Si usas el campo resource.type
en los siguientes ejemplos, la gramática del lenguaje de consulta de registro se ve de la siguiente manera:
Restricción simple:
resource.type = "k8s_cluster"
Restricción conjuntiva:
resource.type = "k8s_cluster" AND severity = "ERROR"
Restricción disyuntiva:
resource.type = "k8s_cluster" OR resource.type = "gce_instance"
- Como alternativa, puedes usar
resource.type = ("k8s_cluster" OR "gce_instance")
.
- Como alternativa, puedes usar
Expresión conjuntiva/disyuntiva compleja:
resource.type = "k8s_cluster" AND (severity = "ERROR" OR "error")
El siguiente es un ejemplo de una consulta:
resource.type = "gce_instance" AND severity >= "ERROR" AND NOT textPayload:robot
Esta consulta busca coincidencias en las entradas de registro de Compute Engine que tienen valores de gravedad de al menos ERROR
y cuyo campo textPayload
no contiene la cadena robot
. Las comparaciones de strings no distinguen entre mayúsculas y minúsculas. Los nombres resource
, severity
y textPayload
se definen en el tipo LogEntry
.
Notación de la sintaxis
En las siguientes secciones, se proporciona una descripción general de la sintaxis del lenguaje de consulta de Logging y se analiza en detalle cómo se estructuran las consultas y cómo se realiza la coincidencia. Algunos de los ejemplos usan comentarios para proporcionar texto explicativo.
Ten en cuenta lo siguiente:
La longitud de una consulta no puede superar los 20,000 caracteres.
El lenguaje de consulta de Logging no distingue mayúsculas de minúsculas, a excepción de las expresiones regulares.
Resumen de la sintaxis
La sintaxis del lenguaje de consulta de Logging se puede considerar en términos de consultas y comparaciones.
Una consulta es una string que contiene una expresión:
expression = ["NOT"] comparison { ("AND" | "OR") ["NOT"] comparison }
Una comparación es un valor único o una expresión booleana:
"The cat in the hat" resource.type = "k8s_cluster"
La primera línea es un ejemplo de una comparación que es un valor único. Estos tipos de comparaciones son restricciones globales. Cada campo de una entrada de registro se compara con el valor mediante el uso implícito del operador has. Para este ejemplo, si algún campo en una LogEntry
, o su carga útil, contiene la frase “The cat in the hat” (El gato en el sombrero), la comparación es exitosa.
La segunda línea es un ejemplo de una comparación que es una expresión booleana de la forma [FIELD_NAME] [OP] [VALUE]
. Una comparación tiene tres componentes:
[FIELD_NAME]
es un campo en una entrada de registro. Por ejemplo,resource.type
[OP]
es un operador de comparación. Por ejemplo,=
[VALUE]
es un número, una expresión entre paréntesis, una cadena o una función. Por ejemplo,"k8s_cluster"
Para los valores nulos de JSON, usaNULL_VALUE
.
Operadores booleanos
Los operadores booleanos AND
y OR
son operadores de cortocircuito.
El operador NOT
tiene la prioridad más alta, seguido de OR
y AND
en ese orden. Por ejemplo, las dos expresiones siguientes son equivalentes:
"a" OR NOT "b" AND NOT "c" OR "d" ("a" OR (NOT "b")) AND ((NOT "c") OR "d")
Puedes omitir el operador AND
entre las comparaciones. También puedes reemplazar el operador NOT
por el operador -
(menos). Por ejemplo, las siguientes dos consultas son equivalentes:
a="b" AND c="d" AND NOT e="f" a="b" c="d" -e="f"
En esta documentación, siempre se usa AND
y NOT
.
Para todos los filtros, excepto los que usan las vistas de registro, puedes usar los operadores AND
, OR
y NOT
. Las vistas de registro solo admiten operaciones AND
y NOT
.
Para combinar reglas AND
y OR
en la misma expresión, debes anidar las
reglas con paréntesis. Si no usas paréntesis, es posible que tu consulta no funcione según lo previsto.
Los operadores booleanos se deben escribir siempre en mayúscula. Los operadores and
, or
y not
en minúscula se analizan como términos de búsqueda.
Comparaciones
Las comparaciones tienen el formato siguiente:
[FIELD_NAME] [OP] [VALUE]
Una comparación tiene tres componentes:
[FIELD_NAME]: Es el identificador de ruta de acceso de un campo en una entrada de registro. Los siguientes son ejemplos de estos identificadores:
resource.type resource.labels.zone resource.labels.project_id insertId jsonPayload.httpRequest.protocol labels."compute.googleapis.com/resource_id"
Si un componente de un identificador de ruta de campo tiene caracteres especiales, el componente debe estar entre comillas dobles. Por ejemplo,
compute.googleapis.com/resource_id
debe estar entre comillas dobles porque contiene una barra diagonal/
.Para obtener más detalles, consulta identificadores de rutas de campo en este documento.
[OP]: Es un operador de comparación, uno de los siguientes:
= -- 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 aprender a buscar entradas de registro mediante expresiones regulares, consulta Cómo usar expresiones regulares.
- [VALUE]: Es un número, una expresión entre paréntesis, una string o una función.
Las strings se usan para representar textos arbitrarios, además de valores booleanos, de enumeración y de string de bytes. El
[VALUE]
se convierte al tipo de campo antes de la comparación. Para los valores nulos de JSON, usaNULL_VALUE
.
Para filtrar por un valor nulo de JSON, usa la siguiente sintaxis:
jsonPayload.field = NULL_VALUE -- includes "field" with null value NOT jsonPayload.field = NULL_VALUE -- excludes "field" with null value
Si [VALUE]
es una combinación booleana de comparaciones entre paréntesis, entonces el nombre del campo y el operador de comparación se aplican a cada elemento.
Por ejemplo:
jsonPayload.cat = ("longhair" OR "shorthair") jsonPayload.animal : ("nice" AND "pet")
Con la primera comparación, se verifica que el campo cat
tenga el valor “longhair” (cabello largo) o “shorthair” (cabello corto). Con la segunda, se comprueba que el valor del campo animal
contenga las dos palabras “nice” (lindo) y “pet” (mascota), en cualquier orden.
Identificadores de rutas de campo
Todas las entradas de registro son instancias del tipo LogEntry
. El identificador que es (o comienza en) el lado izquierdo de una comparación debe ser un campo definido en el tipo LogEntry
. Para obtener detalles sobre los identificadores posibles y sus valores, consulta el tipo LogEntry
.
A continuación, se muestra la lista actual de los campos de entrada de registro. Cada campo va seguido del nivel de nombres siguiente para ese campo, si corresponde:
httpRequest
: {cacheFillBytes
,cacheHit
,cacheLookup
,cacheValidatedWithOriginServer
,latency
,protocol
,referer
,remoteIp
,requestMethod
,requestSize
,requestUrl
,responseSize
,serverIp
,status
,userAgent
}insertId
jsonPayload
{ variable }labels
{ variable }logName
metadata
{systemLabels
,userLabels
}operation
{id
,producer
,first
,last
}protoPayload
{@type
, variable }receiveTimestamp
resource
{type
,labels
}severity
sourceLocation
: {file
,line
,function
}spanId
textPayload
timestamp
trace
Los siguientes son ejemplos de identificadores de rutas de campo que puedes usar en tus comparaciones:
resource.type: Si tu primer identificador de ruta es
resource
, el identificador siguiente debe ser un campo del tipoMonitoredResource
.httpRequest.latency: Si tu primer identificador de ruta es
httpRequest
, el siguiente identificador debe ser un campo del tipoHttpRequest
.labels.[KEY]: Si tu primer identificador de ruta es
labels
, el identificador siguiente,[KEY]
, debe ser una de las claves de los pares clave-valor que aparecen en el campolabels
.logName: Debido a que el campo
logName
es una string, no puede haber ningún nombre de subcampo luego de este.
Cuando consultas los campos mapa o struct, debes conservar las mayúsculas y minúsculas del formato de sus claves y darles formato.
Por ejemplo, jsonPayload
es un campo de struct, por lo que un nombre de campo anidado dentro de jsonPayload
como jsonPayload.end_time
difiere de jsonPayload.endTime
. Del mismo modo, para un campo de mapa como labels
, la clave de la etiqueta labels.env_name
es diferente de labels.envName
. Por el contrario, cuando consultas el campo de búfer de protocolo normal protoPayload, no necesitas conservar el caso.
Para obtener información sobre los tipos de campo LogEntry
, consulta la referencia google.logging.v2.
Caracteres especiales
Si un campo LogEntry
contiene caracteres especiales, el campo de registro debe estar entre comillas.
Por ejemplo:
jsonPayload.":name":apple jsonPayload."foo.bar":apple jsonPayload."\"foo\"":apple
Para obtener la lista de caracteres especiales, consulta la sección string
en Valores y conversiones.
Para obtener más información sobre el uso de identificadores de rutas de campo que hacen referencia a objetos o arreglos, consulta Tipos de objetos y arreglos en este documento.
Tipos de recursos supervisados
Para realizar consultas más rápidas, especifica un tipo de recurso supervisado. Para obtener una lista de tipos de recursos, consulta Tipos de recursos supervisados.
Por ejemplo, las VM de Compute Engine usan el tipo de recurso gce_instance
y las instancias de Amazon EC2 usan aws_ec2_instance
. En el siguiente ejemplo, se muestra cómo limitar tus consultas a ambos tipos de VM:
resource.type = ("gce_instance" OR "aws_ec2_instance")
Los valores del tipo de recurso supervisado en los registros se indexan. El uso de coincidencias de substring para ellos hace que las consultas sean más lentas.
Campos faltantes
Si usas un nombre de campo en una consulta y ese campo no aparece en una entrada de registro, entonces el campo es un campo faltante, indefinido o predeterminado:
Si el campo es parte de la carga útil de la entrada de registro (
jsonPayload
oprotoPayload
) o si está en una etiqueta de la secciónlabels
de la entrada de registro, el campo es un campo faltante. El uso de un campo faltante no mostrará un error, pero todas las comparaciones que usan campos faltantes fallarán de forma silenciosa.Ejemplos:
jsonPayload.nearest_store
,protoPayload.name.nickname
Si el campo está definido en el tipo
LogEntry
, entonces, está predeterminado. Las comparaciones se realizan como si el campo estuviera presente y tuviera su valor predeterminado.Ejemplos:
httpRequest.remoteIp
,trace
,operation.producer
De lo contrario, el campo está indefinido, que es un error que se detecta antes de que se use la consulta.
Ejemplos:
thud
,operation.thud
,textPayload.thud
Para comprobar si hay un campo faltante o predeterminado sin probar un valor particular en el campo, usa la comparación :*
. Por ejemplo, la siguiente comparación se realiza de forma correcta si el campo operation.id
está presente de modo explícito en una entrada de registro:
operation.id:*
Ten en cuenta el comportamiento de las siguientes consultas:
Cuando usas el operador booleano
NOT
en un campo faltante, el resultado esTRUE
:-- Returns TRUE NOT missingField=foo
Cuando usas el operador de comparación de desigualdad
!=
en un campo faltante, el resultado esFALSE
:-- Returns FALSE missingField!=foo
Tipos de objetos y arreglos
Cada campo de entrada de registro puede contener un escalar, un objeto o un arreglo.
Un campo escalar almacena un valor único, como
174.4
o-1
. Unastring
también se considera un escalar. Los campos que se pueden convertir en (o desde) una string, comoDuration
yTimestamp
, también son tipos escalares.Un tipo de objeto almacena una recopilación de valores con nombre, como el valor JSON siguiente:
{"age": 24, "height": 67}
Puedes hacer referencia a un valor dentro de un objeto. Por ejemplo, si
jsonPayload.x
contiene el valor anterior, entoncesjsonPayload.x.age
tendría el valor24
.Un campo de arreglos almacena una lista de valores, todos del mismo tipo. Por ejemplo, un campo que contiene medidas podría tener el arreglo de números siguiente:
{8.5, 9, 6}
Cuando se realizan comparaciones y
[FIELD_NAME]
es un campo de arreglo, cada miembro del arreglo se compara con[VALUE]
, y los resultados se unen mediante el operadorOR
. Por ejemplo, sijsonPayload.shoeSize
es un campo de arreglo que almacena{8.5, 9, 6}
, la comparación siguiente:jsonPayload.shoeSize < 7
es equivalente a esto:
8.5 < 7 OR 9 < 7 OR 6 < 7
En este ejemplo, la comparación en general se evalúa como exitosa.
Valores y conversiones
El primer paso a la hora de evaluar una comparación es convertir el valor del lado derecho al tipo del campo de entrada de registro. Los tipos de campos de escalares están permitidos en las comparaciones, junto con dos tipos adicionales cuyos valores se representan como strings: Duration
y Timestamp
. Para obtener una lista de tipos de escalares, consulta la lista de tipos de búfer de protocolo de escalares. En la siguiente tabla, se explica qué valores se pueden convertir en los tipos de campo de registro:
Tipo de campo | Valor de consulta permitido |
---|---|
bool |
“Verdadero” o “falso” en mayúsculas o minúsculas. Ejemplos: “Verdadero”, “verdadero”. |
bytes |
Una string que contiene cualquier secuencia de bytes. Ejemplo: “\377\377”. |
Duration |
Una string que contiene un número decimal con firma seguido de una de las unidades “ns”, “us”, “m”, “s”, “m” o “h”. Las duraciones son precisas, se miden en nanosegundos. Ejemplo: “3.2s”. |
enum |
El nombre de un tipo de enumeración literal, con distinción de mayúsculas y minúsculas. Ejemplos: “WARNING”, que es un valor del tipo LogSeverity. |
double |
Cualquier número, sin un signo o con y una parte del exponente o las strings de valores especiales “-Infinity”, “Infinity” y “Nan” (en mayúscula o no). Ejemplos: “-3.2e-8”, “nan”. |
intNN |
Cualquier número entero con firma que no exceda el tamaño del tipo. Ejemplo: “-3”. |
string |
Cualquier string que contenga texto codificado en UTF-8 o ASCII de 7 bits. Las comillas incorporadas se deben escapar con una barra invertida. Los valores de string deben estar entre comillas dobles para escapar los siguientes caracteres especiales:
|
Timestamp |
Una string en formato RFC 3339 o ISO 8601.
Examples y coma; “2024-08-02T15:01:23.045Z” (RFC 3339), “2024-08-02” (ISO 8601). En las expresiones de consulta, las marcas de tiempo en formato RFC 3339 pueden especificar una zona horaria con “Z” o |
uintNN |
Cualquier número entero sin firma que no exceda el tamaño del tipo. Ejemplo: “1234”. |
Si falla un intento de conversión, también falla la comparación.
Cuando una conversión necesita una string, también puedes usar un número o un texto sin comillas si no contienen caracteres especiales como espacios y operadores. De manera similar, cuando una conversión necesita un número, puedes usar una string cuyo contenido sea un número.
Los tipos intNN
y uintNN
representan tipos de números enteros de varios tamaños, como int32
y uint64
. Cuando escribes un valor para convertirlo en un tipo de número entero de 64 bits, debes escribir el valor como una string, por ejemplo “9223372036854775807”.
Tipos de campos de registro
A continuación, se muestra cómo se determina el tipo de un campo de entrada de registro:
Los campos de registro que se definen en un tipo
LogEntry
y en el tipo de componente son campos de búfer de protocolo. Los campos de búfer de protocolo tienen tipos explícitos.Los campos de registro que forman parte de los objetos
protoPayload
también son campos de búfer de protocolo y tienen tipos explícitos. El nombre del tipo de búfer de protocolo se almacena en el campo"@type"
deprotoPayload
. Para obtener más información, consulta la asignación de JSON.Cuando filtras un campo asociado con el tipo de mensaje
Any
, se recorre automáticamente el campovalue
. Por lo tanto, no la incluyas en la consulta. Si deseas obtener más información, consulta Solución de problemas.Los campos de registro dentro de
jsonPayload
tienen tipos que se infieren del valor del campo cuando se recibe la entrada de registro:- Los campos cuyos valores son números sin comillas tienen el tipo
double
. - Los campos cuyos valores son
true
ofalse
tienen el tipobool
. - Los campos cuyos valores son strings tienen el tipo
string
.
Los números enteros largos (de 64 bits) se almacenan en campos de cadenas, ya que no se pueden representar como valores
double
de manera exacta.- Los campos cuyos valores son números sin comillas tienen el tipo
Los tipos
Duration
yTimestamp
solo se reconocen en los campos de búfer de protocolo. En otros lugares, esos valores se almacenan en campos de strings.
Comentarios
Los comentarios comienzan con dos guiones (--
) y se ignora todo el texto que los sigue hasta el final de la línea. Los comentarios se pueden colocar al comienzo de un filtro, entre términos y al final de un filtro.
Puedes usar comentarios en los siguientes casos:
Para anotar tus filtros complejos con información sobre lo que hace una cláusula, sigue estos pasos:
-- All of our target users are emitted by Compute Engine instances. resource.type = "gce_instance" -- Looking for logs from "alex". jsonPayload.targetUser = "alex"
Para habilitar o inhabilitar rápidamente una cláusula agregando o quitando el prefijo de comentario, haz lo siguiente:
resource.type = "gce_instance" -- jsonPayload.targetUser = "alex" jsonPayload.targetUser = "kiran" -- jsonPayload.targetUser = "sasha"
Operadores de comparación
El significado de los operadores de igualdad (=
, !=
) y de desigualdad (<
, <=
, >
, >=
) depende del tipo del nombre del campo izquierdo subyacente.
- Todos los tipos numéricos: La igualdad y la desigualdad tienen su significado normal para los números.
bool
: La igualdad representa el mismo valor booleano. La desigualdad se define portrue
>false
.enum
: La igualdad representa el mismo valor de enumeración. La desigualdad usa los valores numéricos subyacentes de los literales de enumeración.Duration
: La igualdad representa la misma duración. La desigualdad se basa en la duración. Ejemplo: como duraciones,"1s"
>"999ms"
.Timestamp
: La igualdad representa el mismo instante. Si a y b son valoresTimestamp
, a < b significa que a está antes que b.bytes
: Los operandos se comparan byte por byte, de izquierda a derecha.string
: Las comparaciones no distinguen entre mayúsculas o minúsculas. En particular, primero se normalizan ambos operandos mediante la normalización de NFKC_CF Unicode y, luego, usan comparaciones lexicográficas. Sin embargo, no se normalizan las búsquedas de expresiones regulares. Para obtener más información sobre la búsqueda de entradas de registro mediante expresiones regulares, consulta Cómo usar expresiones regulares.
El operador de substring (:
) se puede aplicar a string
y bytes
, y se maneja como una igualdad, excepto que el operando de la derecha solo necesita ser igual a una parte del campo de la izquierda. Las coincidencias de substrings en los campos indexados no aprovechan los índices de registro.
Restricciones globales
Si la comparación consiste de un valor único, se denomina restricción global. Logging usa el operador has (:
) para determinar si algún campo en una entrada de registro o su carga útil contiene la restricción global.
Si es así, entonces, la comparación tiene éxito.
La consulta más simple escrita en términos de una restricción global es un valor único:
"The Cat in The Hat"
Puedes combinar restricciones globales mediante los operadores AND
y OR
para obtener una consulta más interesante. Por ejemplo, si deseas mostrar todas las entradas de registro que tienen un campo que contiene cat
y un campo que contiene hat
o bat
, escribe la consulta del siguiente modo:
("cat" AND ("hat" OR "bat"))
En este caso, existen tres restricciones globales: cat
, hat
y bat
. Estas restricciones globales se aplican por separado y los resultados se combinan, como si la expresión se hubiera escrito sin paréntesis.
Una restricción global es una forma de consultar tus registros en busca de un valor particular.
Por ejemplo, si buscas en tu registro de actividad entradas que contienen alguna mención de GCE_OPERATION_DONE
, puedes usar la siguiente consulta:
logName = "projects/my-project-id/logs/compute.googleapis.com%2Factivity_log" AND "GCE_OPERATION_DONE"
En lugar de usar restricciones globales, que pueden ser lentas, te recomendamos que uses la función SEARCH
integrada y consultes los campos indexados. Para obtener más información, consulta Encuentra entradas de registro rápido en este documento.
Funciones
Puedes usar funciones integradas como restricciones globales en las consultas:
function = identifier ( [ argument { , argument } ] )
En el ejemplo anterior, argument
es un valor, un nombre de campo o una expresión entre paréntesis.
Las funciones se describen en las siguientes secciones.
log_id
La función log_id
muestra entradas de registro que coinciden con el argumento [LOG_ID]
determinado del campo logName
:
log_id([LOG_ID])
Por ejemplo, mediante la siguiente consulta, se muestran todas las entradas de registro con un [LOG_ID]
cloudaudit.googleapis.com%2Factivity
:
log_id("cloudaudit.googleapis.com/activity")
transmitir
La función cast
acepta dos parámetros: el campo LogEntry
que se transmitirá y el tipo de datos al que se convertirá el campo:
cast([FIELD], [TYPE][, OPTION])
Los parámetros de la expresión anterior se definen de la siguiente manera:
[FIELD]
: Es el nombre de un campo en la entrada de registro, comologName
ojsonPayload.a_field
.[TYPE]
: Es el tipo de datos, comoSTRING
,INT64
,FLOAT64
oBOOL
.TIMESTAMP
oDURATION
: Algunos tipos de datos ofrecen opciones adicionales, como especificar una zona horaria de la base de datos de zonas horarias de IANA para el tipo de datosTIMESTAMP
.
Por ejemplo, la siguiente consulta convierte el campo timestamp
en una cadena y especifica la zona horaria America/New_York
:
cast(timestamp, STRING, TIMEZONE("America/New_York")) =~ "^2023-01-02.*"
regexp_extract
Usa la función regexp_extract
para encontrar la primera subcadena que coincida con una expresión regular:
REGEXP_EXTRACT([FIELD], [REGULAR_EXPRESSION])
En la expresión anterior, los campos se definen de la siguiente manera:
[FIELD]
: Es el nombre de un campo en la entrada de registro, comologName
ojsonPayload.a_field
.[REGULAR_EXPRESSION]
: Es la expresión regular RE2 que debe contener un grupo de captura ((...)
). Se debe usar un grupo(?:...)
que no capture si se requiere un agrupamiento adicional para la expresión regular. Si hay varios grupos de captura o no hay ninguno, se produce un error.
Puedes encadenar las funciones cast
y regexp_extract
:
CAST(REGEXP_EXTRACT(CAST(timestamp, STRING), "\\d+:\\d+:\\d+\\.(\\d+)"), INT64) < 500
En el ejemplo anterior, el campo timestamp
se convierte en una cadena. La expresión regular captura la parte de milisegundos de la cadena timestamp
y la convierte en un número entero para realizar una comparación numérica. Se muestran todas las entradas de registro que contienen marcas de tiempo en las que el campo de milisegundos es inferior a 500.
source
La función source
hace coincidir las entradas de registro de un recurso en particular en las organizaciones, carpetas y jerarquía de los proyectos de Google Cloud.
La función source
no coincide con los recursos secundarios. Por ejemplo, si usas source(folders/folder_123)
, coincide con los registros del recurso folder_123
y no con los registros de los recursos del proyecto de Google Cloud dentro de folder_123
.
Para consultar registros en un nivel de recurso en particular, usa la siguiente sintaxis:
source(RESOURCE_TYPE/RESOURCE_ID)
Recurso | Consulta de ejemplo |
---|---|
Organización | source(organizations/ ORGANIZATION_ID) |
Carpeta | source(folders/ FOLDER_ID) |
Proyectos de Google Cloud | source(projects/ PROJECT_ID) |
muestra
La función sample
selecciona una fracción de la cantidad total de entradas de registro:
sample([FIELD], [FRACTION])
[FIELD]
es el nombre de un campo en la entrada de registro, como logName
o jsonPayload.a_field
. El valor del campo determina si la entrada de registro está en la muestra. El tipo de campo debe ser una string o un valor numérico.
Configurar [FIELD]
como insertId
es una buena opción, ya que cada entrada de registro tiene un valor diferente para ese campo.
[FRACTION]
es la fracción de entradas de registro que tienen valores que [FIELD]
debe incluir. Es un número mayor que 0.0 y menor o igual que 1.0. Por ejemplo, si especificas 0.01
, la muestra contiene un valor aproximado del uno por ciento de todas las entradas de registro que tienen valores para [FIELD]
. Si [FRACTION]
es 1, se eligen todas las entradas de registro que tienen valores para [FIELD]
.
Ejemplo: La siguiente consulta muestra el 25% de las entradas del registro syslog
:
logName = "projects/my-project/logs/syslog" AND sample(insertId, 0.25)
Detalles: Se usa un algoritmo determinista, en función de los hashes, para determinar si una entrada de registro se incluye o no en la muestra. La precisión del ejemplo resultante depende de la distribución de los valores de hash.
Si los valores de hash no están distribuidos de manera uniforme, la muestra resultante se puede sesgar.
En el peor de los casos, cuando [FIELD]
siempre contiene el mismo valor, la muestra resultante contiene la [FRACTION]
de todas las entradas de registro o ninguna de ellas.
Si [FIELD]
aparece en una entrada de registro, sucede lo siguiente:
- Se calcula un hash del valor.
- El valor de hash, que es un número, se divide por el valor de hash máximo posible.
- Si la fracción resultante es menor o igual que
[FRACTION]
, la entrada de registro se incluye en la muestra; de lo contrario, se excluye de esta.
Si [FIELD]
no aparece en una entrada de registro, sucede lo siguiente:
- Si
[FIELD]
es parte de la carga útil de la entrada de registro o seccioneslabels
, la entrada de registro no está seleccionada para la muestra, incluso si[FRACTION]
es 1. - De lo contrario, a la entrada de registro se la trata como si
[FIELD]
estuviera en la entrada de registro y el valor de[FIELD]
fuera el valor predeterminado. El tipoLogEntry
determina el valor predeterminado. Para obtener más información sobre los campos faltantes y predeterminados, consulta Campos faltantes en este documento.
Para excluir las entradas de registro con campos predeterminados de la muestra, usa el operador de campo existente :*
. La consulta siguiente genera una muestra del 1% de entradas de registro que proporcionaron un valor para field
de forma explícita:
field:* AND sample(field, 0.01)
ip_in_net
La función ip_in_net
determina si una dirección IP en una entrada de registro está contenida dentro una subred. Puedes usarlo para saber si una solicitud proviene de una fuente interna o externa. Por ejemplo:
ip_in_net([FIELD], [SUBNET])
[FIELD]
es un campo con un valor de string en la entrada de registro que contiene un rango o una dirección IP. El campo puede repetirse; en ese caso, solo uno de los campos repetidos debe tener una dirección o un rango contenido en la subred.
[SUBNET]
es una constante de string para una dirección IP o un rango. Es un error si [SUBNET]
no es un rango o una dirección IP legal, como se describe más adelante en esta sección.
Ejemplo: La siguiente consulta prueba una dirección IP en la carga útil de entradas del registro my_log
:
logName = "projects/my_project/logs/my_log" AND ip_in_net(jsonPayload.realClientIP, "10.1.2.0/24")
Detalles: En caso de que en una entrada de registro faltara [FIELD]
, estuviera predeterminado o no contuviera una dirección IP o un rango legal, la función mostrará falso. Para obtener más información sobre los campos faltantes y predeterminados, consulta Campos faltantes en este documento.
A continuación, se incluyen algunos ejemplos de las direcciones IP y rangos admitidos:
- IPv4:
10.1.2.3
- Subred IPv4:
10.1.2.0/24
- CIDR IPv6:
1234:5678:90ab:cdef:1234:5678:90ab:cdef
- Subred CIDR IPv6:
1:2::/48
Función SEARCH
Puedes usar la función integrada SEARCH
para encontrar cadenas en tus datos de registro:
SEARCH([query]) SEARCH([field], [query])
Ambas formas de la función SEARCH
contienen un argumento query
, que debe tener el formato de una cadena literal. En la primera forma, se busca en toda la entrada de registro. En la segunda forma, especificas el campo de la entrada de registro que quieres buscar.
Debes especificar el campo query
. Si no se especifica este campo, se muestra un error.
Cuando se procesa la función SEARCH
, un analizador de texto que divide la cadena en tokens la procesa.query
El registro de Cloud siempre realiza comparaciones que no distinguen mayúsculas de minúsculas, incluso para los tokens unidos con acentos graves. Este comportamiento difiere del de BigQuery, que conserva el caso en tokens unidos con acentos graves.
Para obtener información sobre las reglas del analizador, consulta el documento de BigQuery Text analyzer rules.
Cuando crees una búsqueda, ten en cuenta lo siguiente:
Los tokens no distinguen mayúsculas de minúsculas. Las siguientes funciones producen los mismos resultados:
SEARCH("world") SEARCH("World")
Las funciones anteriores coinciden con una entrada de registro cuando un solo campo contiene el token “mundo”. Debido a que
SEARCH
realiza coincidencias exactas y no coincidencias de subcadena, las funciones anteriores no coinciden con un campo cuyo valor es "en todo el mundo".Si no especificas el campo en el que se debe realizar la búsqueda, la función
SEARCH
coincide con una entrada de registro cuando esa entrada contiene todos los tokens. Sin embargo, el orden de los tokens no importa, y no es necesario que los tokens se encuentren en el mismo campo de la entrada de registro.Las siguientes funciones producen los mismos resultados y coinciden con una entrada de registro que contiene los tokens "hello" y "world":
SEARCH("hello world") SEARCH("World hello")
Si especificas el campo en el que se realizará la búsqueda, la función
SEARCH
solo realizará la búsqueda en ese campo. Se produce una coincidencia cuando ese campo contiene todos los tokens. Sin embargo, el orden de los tokens no importa.Las siguientes funciones producen una coincidencia solo cuando el campo
textPayload
contiene los tokens “hello” y “world”:SEARCH(textPayload, "hello world")
Para aplicar una concordancia exacta que no distingue mayúsculas de minúsculas en una frase, colócala entre acentos graves. Por ejemplo, las siguientes funciones coinciden con la cadena "hello world":
SEARCH("`hello world`") SEARCH("`Hello World`") SEARCH("`HELLO WORLD`")
Debido a que se usan acentos graves en las siguientes funciones, producen resultados diferentes:
SEARCH("`hello world`") SEARCH("`world hello`")
El lenguaje de consulta de Logging admite diferentes maneras de buscar tus datos de registro. Cuando se busca una cadena, es más eficaz usar la función SEARCH
que realizar una búsqueda global o una búsqueda por subcadenas.
Sin embargo, no puedes usar la función SEARCH
para hacer coincidir campos que no sean de texto.
Para obtener orientación sobre cómo realizar operaciones de búsqueda, consulta Cómo minimizar las búsquedas globales y de substring.
Busca por tiempo
En la interfaz, puedes establecer límites específicos para la fecha y la hora de las entradas de registro que se mostrarán. Por ejemplo, si agregas las siguientes condiciones a tu consulta, el panel de resultados mostrará con exactitud las entradas de registro en el período indicado de 30 minutos y no podrás desplazarte fuera de ese período:
timestamp >= "2023-11-29T23:00:00Z" timestamp <= "2023-11-29T23:30:00Z"
Cuando escribes una consulta con una marca de tiempo, debes usar fechas y horas en el formato que se mostró anteriormente.
También puedes buscar entradas de registro mediante combinaciones de teclas de timestamp
. Por ejemplo, puedes ingresar una fecha con un operador de comparación para obtener todas las entradas de registro que se produjeron después de un día determinado:
timestamp > "2023-11-29"
Usa expresiones regulares
Puedes usar expresiones regulares a fin de compilar consultas y crear filtros para usar en los receptores, en las métricas y en donde sea que se usen los filtros de registro. Por ejemplo, puedes usar expresiones regulares en el Explorador de registros y con Google Cloud CLI.
Una expresión regular es una secuencia de caracteres que define una búsqueda. En el lenguaje de consulta de Logging, se usa la sintaxis RE2. Para obtener una explicación completa sobre la sintaxis RE2, consulta la wiki de RE2 en GitHub.
Las consultas de expresiones regulares tienen las siguientes características:
Solo los campos del tipo string pueden coincidir con una expresión regular.
No se realiza la normalización de strings. Por ejemplo,
kubernetes
no se considera equivalente aKUBERNETES
. Para obtener más información, consulta la sección Operadores de comparación.Las consultas distinguen mayúsculas de minúsculas y no están ancladas de forma predeterminada.
Los operadores booleanos se pueden usar entre varias expresiones regulares en el lado derecho del operador de comparación de expresiones regulares
=~
y!~
.
Una consulta de expresión regular tiene la siguiente estructura:
Si coincide con un patrón, se verá así:
jsonPayload.message =~ "regular expression pattern"
Si no coincide con un patrón, se verá así:
jsonPayload.message !~ "regular expression pattern"
=~
y !~
cambian la consulta a una consulta de expresión regular. El patrón con el que intentas realizar la coincidencia debe estar entre comillas dobles. Para consultar patrones que contengan comillas dobles, escápalas mediante el uso de una barra inversa.
Ejemplos de consultas de registros mediante expresiones regulares
Tipo de consulta | Ejemplo |
---|---|
Consulta estándar | sourceLocation.file =~ "foo" |
Consulta mediante una búsqueda en la que no se distingue entre mayúsculas y minúsculas | labels.subnetwork_name =~ "(?i)foo" |
Consulta que contiene comillas | jsonPayload.message =~ "field1=\"bar.*\"" |
Consulta mediante un valor booleano or |
labels.pod_name =~ "(foo|bar)" |
Consulta mediante anclas | logName =~ "/my%2Flog$" |
Consulta que no coincide con un patrón | labels.pod_name !~ "foo" |
Consulta mediante un operador booleano | labels.env =~ ("^prod.*server" OR "^staging.*server") |
Búsqueda que comienza con un valor | logName =~ "^foo" |
Consulta que termina con un valor | logName =~ "foo$" |
Busca entradas de registro con rapidez
Para encontrar entradas de registro de manera eficiente, haz lo siguiente:
- Consulta mediante campos indexados.
- Minimiza la cantidad de entradas de registro que se deben buscar.
Usa campos indexados
El registro siempre indexa los siguientes campos LogEntry
:
- resource.type
- resource.labels.*
- logName
- severity
- timestamp
- insertId
- operation.id
- trace
- httpRequest.status
- labels.*
- split.uid
También puedes agregar campos indexados personalizados a cualquier bucket de registros.
En las siguientes secciones, se explica cómo usar campos indexados para minimizar la cantidad de entradas de registro que se buscarán.
Optimiza tus consultas
Puedes hacer que tus búsquedas sean más rápidas si reduces la cantidad de registros, de entradas de registro o el intervalo de tus búsquedas. Aún mejor, puedes reducir los tres.
Ejemplo: Usa el nombre de registro correcto
Especifica el registro que contiene las entradas de registro que te interesan. Asegúrate de conocer el nombre de registro real mediante la inspección de una de tus entradas de registro. Por ejemplo, el panel de resultados muestra que la sección de Compute Engine contiene un registro llamado “activity”. En un análisis más detallado de las entradas de registro de la actividad del administrador, el registro se llama “cloudaudit.googleapis.com/activity”.
La comparación siguiente es incorrecta. No coincide con nada porque usa el nombre de registro incorrecto, como se ve a continuación:
logName = "projects/my-project-id/logs/activity" -- WRONG!
La comparación siguiente es correcta. Elige entradas de registro del registro de auditoría de la actividad del administrador. Debes codificar como URL el nombre del registro, como se muestra a continuación:
logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"
Ejemplo: elige el nombre de registro correcto
Si sabes que las entradas de registro que deseas provienen de una instancia de VM particular, especifícalas. Verifica los nombres de las etiquetas correctas mediante la inspección de una de las entradas de registro que deseas buscar. En el siguiente ejemplo, instance_id
es una de las etiquetas indexadas:
resource.type = "gce_instance" AND resource.labels.instance_id = "6731710280662790612" logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"
Ejemplo: Elige el período correcto
Especifica un período para buscar. Una forma rápida de determinar las marcas de tiempo útiles en el formato RFC 3339 es usar el comando date
de GNU/Linux:
$ 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
Usa los valores de estas marcas de tiempo en las siguientes consultas. A fin de crear una marca de tiempo que Logging acepte, reemplaza el espacio entre la fecha y la hora por la letra T
.
Por ejemplo, usa esto para buscar dentro de las últimas tres horas:
timestamp >= "2023-06-27T14:40:00-04:00"
Como otro ejemplo, para buscar entre tres y cinco horas atrás, usa esto:
timestamp >= "2023-06-27T12:40:00-04:00" AND timestamp <= "2023-06-27T14:40:00-04:00"
Minimiza las búsquedas globales y de substring
Evita usar combinaciones de teclas cuando escribas las consultas de registro.
Ejemplo: No uses búsquedas globales
Si buscas una entrada de registro con “Hello, Kitty” en la carga útil, ten en cuenta la siguiente información:
No uses una búsqueda global. Por un motivo, todas son búsquedas de substrings, como se ve a continuación:
"Hello Kitty" -- THIS CAUSES A SLOW SEARCH!
Sí debes limitar la búsqueda a un campo único, incluso si debes mantener la búsqueda de substring, como se ve a continuación:
textPayload:"Hello Kitty"
Sí debes usar una prueba de igualdad, si puedes, como se ve a continuación:
textPayload = "Hello Kitty"
Sí debes hacer referencia a los campos individuales en una carga útil, si tus entradas de registro tienen cargas útiles estructuradas, como se ve a continuación:
jsonPayload.my_favorite_cat = "Hello Kitty"
Sí debes usar un campo indexado para restringir la búsqueda, como se ve a continuación:
logName = "projects/my-project_id/logs/somelog" AND jsonPayload.my_favorite_cat = "Hello Kitty"
Usa la función
SEARCH
y especifica el texto completo que debe coincidir. La funciónSEARCH
realiza una coincidencia sin distinción entre mayúsculas y minúsculas:SEARCH("
Hello Kitty
")No uses la función
SEARCH
y especifica texto parcial. Por ejemplo, la siguiente función no coincide con “Hello Kitty”.SEARCH("
Hello Kit
")
Busca ejemplos
Las entradas de registro que se muestran son las que coinciden con una consulta. Si el menú Saltar a un momento específico contiene un valor, la pantalla se desplazará a ese punto en el tiempo. Estos son algunos ejemplos de consultas:
resource.type=k8s_cluster
Encuentra todas las entradas de registro de Google Kubernetes Engine. Para obtener una lista de los tipos de recursos, consulta la Lista de recursos supervisados.
A medida que escribes, el panel de consulta ofrece sugerencias para completar campos como
resource.type
.resource.type=k8s_cluster AND logName:request_log
Busca entradas de registro para clústeres de Google Kubernetes Engine a partir de los nombres de registro que contienen
request_log
. Ten en cuenta los aspectos siguientes:- El operador
=
es la igualdad exacta. El tipo de recurso debe ser"k8s_cluster"
con exactitud, salvo para mayúsculas y minúsculas. - El operador
:
significa “has”. El campologName
debe contenerrequest_log
, en mayúsculas o minúsculas. El nombre del registro real es mucho más largo. Usar:
puede hacer que las búsquedas sean más lentas. - Las dos comparaciones están unidas por
AND
. También puedes usarOR
, pero se suponeAND
si omites el operador.
- El operador
resource.type = (gce_instance OR aws_ec2_instance) AND severity >= ERROR
Busca entradas de registro con alguno de los dos tipos de recursos: instancia de VM de Compute Engine o instancia de VM de AWS EC2. Las entradas de registro deben tener
severity
de al menosERROR
, lo que equivale a seleccionar ERROR en el menú de gravedad de la interfaz de consulta básica.logName = "projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
Busca todas las entradas de registro de auditoría de la actividad del administrador en el proyecto
[PROJECT_ID]
. Todos los registros de auditoría usan el mismo nombre de registro en un proyecto, pero tienen tipos de recursos diferentes. El ID del registro,cloudaudit.googleapis.com/activity
, debe estar codificado como URL en el nombre del registro. Usar la igualdad en la comparación acelera la búsqueda. Para obtener más información, consulta Comprende los registros de auditoría.unicorn
Busca entradas de registro que contengan
unicorn
en algún campo, en mayúscula o minúscula. Un término de búsqueda que no forma parte de una comparación de campos es una consulta de “todos los campos”.unicorn phoenix
Busca entradas de registro que contengan
unicorn
yphoenix
en algún campo.textPayload:(unicorn phoenix)
Busca entradas de registro cuyo campo
textPayload
contengaunicorn
yphoenix
en cualquier orden;AND
está implícito entre las dos palabras.textPayload:"unicorn phoenix"
Busca entradas de registro cuyo campo
textPayload
contenga la string"unicorn phoenix"
.NOT textPayload: "unicorn phoenix"
Busca entradas de registro cuyo campo
textPayload
no contenga la string"unicorn phoenix"
. Este tipo de consulta reduce la cantidad de entradas de registro no deseadas.timestamp >= "2023-11-29T23:00:00Z" timestamp <= "2023-11-29T23:30:00Z"
Busca entradas de registro dentro de un período de 30 minutos.
Soluciona problemas
Problemas de sintaxis
Si tienes problemas con las expresiones de tus consultas avanzadas, verifica que se cumplan las siguientes cuestiones:
Tu consulta obedece a las reglas de sintaxis; los paréntesis y las comillas coinciden.
Los nombres de los campos de entrada de registro están escritos de forma correcta.
Las operaciones booleanas están en letras mayúsculas (
AND
,OR
,NOT
).Asegúrate de usar
NULL_VALUE
para representar los valores nulos de JSON.Las expresiones booleanas, como las restricciones globales o como el lado derecho de las comparaciones están entre paréntesis para mayor claridad. Por ejemplo, las siguientes dos consultas parecen ser iguales, pero no lo son:
insertId = "ABC-1" OR "ABC-2" -- ERROR!? insertId = ("ABC-1" OR "ABC-2")
El texto sin comillas no debe contener ningún carácter especial. Si tienes dudas, agrega comillas dobles. Por ejemplo, en el siguiente ejemplo, la primera comparación es ilegal debido al operador de substring incorporado (
:
). La comparación debe escribirse entre comillas:insertId = abc:def -- ILLEGAL! insertId = "abc:def"
Google Cloud CLI requiere que la consulta esté entre comillas dobles. Si quieres usar comillas dobles para escapar los caracteres especiales mediante el comando
gcloud logging
, en su lugar, encierra toda la consulta entre comillas simples:gcloud logging read 'resource.type=gce_instance AND jsonPayload.message="Stopped Unattended Upgrades Shutdown."' gcloud logging read 'timestamp>="2020-06-17T21:00:00Z"'
Cuando filtras un campo asociado con el tipo de mensaje
Any
, se recorre automáticamente el campovalue
. Por lo tanto, no incluyasvalue
en la consulta.Por ejemplo, el campo
Status
en un mensajeAuditLog
tiene un campodetails
que es de tipogoogle.protobuf.Any
. Para consultar el campodetails
, omite el campovalue
cuando especifiques el filtro:Qué hacer
protoPayload.status.details.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"
Qué no debes hacer
protoPayload.status.details.value.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"