En este documento se describe, a grandes rasgos, el lenguaje de consultas de Logging que se usa para consultar y filtrar 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 habituales que puedes usar, consulta Consultas de ejemplo con el Explorador de registros.
Información general
Puedes usar el lenguaje de consulta de Logging en el Explorador de registros de laGoogle Cloud consola, la API Logging o la interfaz de línea de comandos. Puede usar el lenguaje de consultas de almacenamiento de registros para consultar datos y escribir filtros para crear sumideros y métricas basadas en registros.
Una consulta es una expresión booleana que especifica un subconjunto de todas las entradas de registro del Google Cloud recurso Google Cloud seleccionado, como un proyecto o una carpeta.
Puede crear consultas basadas en el LogEntry
campo indexado con los operadores lógicos AND
y OR
.
Si usamos el campo resource.type
en los siguientes ejemplos, la gramática del lenguaje de consulta de Logging será la siguiente:
Restricción sencilla:
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"
- Alternativa:
resource.type = ("k8s_cluster" OR "gce_instance")
- Alternativa:
Expresión conjuntiva o disyuntiva compleja:
resource.type = "k8s_cluster" AND (severity = "ERROR" OR "error")
A continuación, se muestra un ejemplo de consulta:
resource.type = "gce_instance" AND severity >= "ERROR" AND NOT textPayload:robot
Esta consulta coincide con 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
en ninguna parte. Las comparaciones de cadenas no distinguen entre mayúsculas y minúsculas. Los nombres resource
, severity
y textPayload
se definen en el tipo LogEntry
.
Notación de sintaxis
En las siguientes secciones se ofrece una descripción general de la sintaxis del lenguaje de consulta de Logging y se explica en detalle cómo se estructuran las consultas y cómo se realiza la coincidencia. En algunos ejemplos se 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 las consultas de Logging no distingue entre mayúsculas y minúsculas, excepto en el caso de las expresiones regulares y los operadores lógicos, como
AND
yOR
. Los operadores lógicos deben escribirse con mayúsculas.
Resumen de la sintaxis
La sintaxis del lenguaje de las consultas de Logging se puede entender en términos de consultas y comparaciones.
Una consulta es una cadena 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 solo valor. Estos tipos de comparaciones son restricciones globales. Cada campo de una entrada de registro se compara con el valor mediante el operador has de forma implícita. En este ejemplo, si algún campo de un LogEntry
o su carga útil contiene la frase "The cat in the hat", la comparación se realizará correctamente.
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 de una entrada de registro. Por ejemplo,resource.type
.[OP]
es un operador de comparación. Por ejemplo,=
.[VALUE]
es un número, una cadena, una función o una expresión entre paréntesis. Por ejemplo,"k8s_cluster"
. En el caso de 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 comparaciones. También puedes sustituir el operador NOT
por el operador -
(menos). Por ejemplo, las dos consultas siguientes son iguales:
a="b" AND c="d" AND NOT e="f" a="b" c="d" -e="f"
En esta documentación siempre se usan AND
y NOT
.
En todos los filtros, excepto en los que usan las vistas de registro, puedes usar los operadores AND
, OR
y NOT
. Las vistas de registro solo admiten las 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 como esperabas.
Los operadores booleanos siempre deben escribirse en mayúsculas. and
, or
y not
en minúsculas se analizan como términos de búsqueda.
Comparación
Las comparaciones tienen el siguiente formato:
[FIELD_NAME] [OP] [VALUE]
Una comparación tiene tres componentes:
[FIELD_NAME]: es el identificador de la ruta de un campo de una entrada de registro. Estos son algunos 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, debe incluirse entre comillas dobles. Por ejemplo,
compute.googleapis.com/resource_id
debe ir entre comillas dobles porque contiene una barra inclinada/
.Para obtener más información, consulta los identificadores de ruta de campo de 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 saber cómo buscar entradas de registro mediante expresiones regulares, consulta el artículo Usar expresiones regulares.
- [VALUE]: es un número, una cadena, una función o una expresión entre paréntesis.
Las cadenas se usan para representar texto arbitrario, además de valores booleanos, de enumeración y de cadena de bytes. El valor
[VALUE]
se convierte al tipo del campo antes de la comparación. En el caso de 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 entre paréntesis de comparaciones, se aplican el nombre del campo y el operador de comparación a cada elemento.
Por ejemplo:
jsonPayload.cat = ("longhair" OR "shorthair") jsonPayload.animal : ("nice" AND "pet")
La primera comparación comprueba que el campo cat
tenga el valor "longhair" o "shorthair". La segunda comprueba que el valor del campo animal
contiene las palabras "nice" y "pet" en cualquier orden.
Identificadores de ruta de campo
Todas las entradas de registro son instancias del tipo LogEntry
. El identificador que es (o empieza) el lado izquierdo de una comparación debe ser un campo definido en el tipo LogEntry
. Para obtener información sobre los posibles identificadores y sus valores, consulta el tipo LogEntry
.
Esta es la lista actual de campos de entrada de registro. Después de cada campo, se muestra el siguiente nivel de nombres de ese campo, si procede:
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
A continuación, se muestran ejemplos de identificadores de ruta de campo que puedes usar en tus comparaciones:
resource.type si el primer identificador de ruta es
resource
, el siguiente identificador 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 el primer identificador de ruta es
labels
, el siguiente identificador,[KEY]
, debe ser una de las claves de los pares clave-valor que aparecen en el campolabels
.logName como el campo
logName
es una cadena, no puede ir seguido de ningún nombre de subcampo.
Cuando consultes campos map o struct, debes conservar las mayúsculas y minúsculas y el formato de sus claves en tu expresión.
Por ejemplo, jsonPayload
es un campo de estructura, por lo que un nombre de campo anidado en jsonPayload
, como jsonPayload.end_time
, es diferente de jsonPayload.endTime
. Del mismo modo, en el caso de un campo de mapa como labels
, la clave de la etiqueta labels.env_name
es diferente de labels.envName
. Por el contrario, cuando se consulta el campo de búfer de protocolo normal protoPayload, no es necesario conservar las mayúsculas y minúsculas.
Para obtener información sobre los tipos de campo LogEntry
, consulta la referencia de google.logging.v2.
Caracteres especiales
Si un campo LogEntry
contiene caracteres especiales, el campo de registro debe ir entre comillas.
Por ejemplo:
jsonPayload.":name":apple jsonPayload."foo.bar":apple jsonPayload."\"foo\"":apple
Para ver la lista de caracteres especiales, consulta la sección string
de Valores y conversiones.
Para obtener más información sobre cómo usar identificadores de ruta de campo que hagan referencia a objetos o matrices, consulta la sección Tipos de objetos y matrices de este documento.
Tipos de recursos monitorizados
Para que las consultas sean más rápidas, especifica un tipo de recurso monitorizado. Para ver una lista de tipos de recursos, consulta Tipos de recursos supervisados.
Por ejemplo, las VMs 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 las consultas a ambos tipos de máquinas virtuales:
resource.type = ("gce_instance" OR "aws_ec2_instance")
Los valores del tipo de recurso monitorizado de los registros se indexan. Si usas coincidencias de subcadenas, las consultas serán más lentas.
Faltan campos
Si usas un nombre de campo en una consulta y ese campo no aparece en una entrada de registro, el campo está ausente, sin definir o tiene un valor predeterminado:
Si el campo forma 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 falta. Si usas un campo que falta, no se mostrará ningún error, pero todas las comparaciones que utilicen campos que falten fallarán sin mostrar ningún mensaje.Ejemplos:
jsonPayload.nearest_store
,protoPayload.name.nickname
Si el campo se define en el
LogEntry
type, el campo se establece de forma predeterminada. 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 es undefined, que es un error que se detecta antes de que se use la consulta.
Ejemplos:
thud
,operation.thud
,textPayload.thud
Para comprobar si existe un campo que falta o que tiene un valor predeterminado sin comprobar un valor concreto en el campo, utilice la comparación :*
. Por ejemplo, la siguiente comparación se realiza correctamente si el campo operation.id
está presente de forma explícita en una entrada de registro:
operation.id:*
Observa el comportamiento de las siguientes consultas:
Si usas el operador booleano
NOT
en un campo que falta, el resultado es el siguiente:TRUE
-- Returns TRUE NOT missingField=foo
Cuando usas el operador de comparación distinto de
!=
en un campo que falta, el resultado esFALSE
:-- Returns FALSE missingField!=foo
Tipos de objetos y de matrices
Cada campo de entrada de registro puede contener un escalar, un objeto o un array.
Un campo escalar almacena un solo valor, como
174.4
o-1
. Unstring
también se considera un escalar. Los campos que se pueden convertir en una cadena (o desde una cadena), comoDuration
yTimestamp
, también son tipos escalares.Un tipo de objeto almacena una colección de valores con nombre, como el siguiente valor JSON:
{"age": 24, "height": 67}
Puedes hacer referencia al valor de un objeto. Por ejemplo, si
jsonPayload.x
contuviera el valor anterior,jsonPayload.x.age
tendría el valor24
.Un campo de matriz almacena una lista de valores, todos del mismo tipo. Por ejemplo, un campo que contiene medidas puede tener una matriz de números:
{8.5, 9, 6}
Cuando se realizan comparaciones y
[FIELD_NAME]
es un campo de matriz, cada miembro de la matriz se compara con[VALUE]
y los resultados se unen mediante el operadorOR
. Por ejemplo, sijsonPayload.shoeSize
es un campo de matriz que almacena{8.5, 9, 6}
, la comparación:jsonPayload.shoeSize < 7
equivale a:
8.5 < 7 OR 9 < 7 OR 6 < 7
En este ejemplo, la comparación general se evalúa como correcta.
Valores y conversiones
El primer paso para evaluar una comparación es convertir el valor del lado derecho al tipo del campo de entrada de registro. Se permiten tipos de campos escalares en comparaciones, así como dos tipos adicionales cuyos valores se representan como cadenas: Duration
y Timestamp
. Para ver una lista de los tipos escalares, consulta la lista de tipos de búfer de protocolo escalares. En la siguiente tabla se explica qué valores se pueden convertir a los tipos de campos de registro:
Tipo de campo | Valor de consulta permitido |
---|---|
bool |
"True" o "false" en cualquier caso. Ejemplos: "True", "true" |
bytes |
Cadena que contiene cualquier secuencia de bytes. Ejemplo: "\377\377". |
Duration |
Cadena que contiene un número decimal con signo seguido de una de las unidades "ns", "us", "ms", "s", "m" u "h". Las duraciones tienen una precisión de nanosegundos. Por ejemplo, "3.2s". |
enum |
Nombre de un literal de tipo de enumeración, sin distinguir entre mayúsculas y minúsculas. Ejemplos: "WARNING", que es un valor del tipo LogSeverity. |
double |
Cualquier número, con o sin signo y con una parte de exponente, o las cadenas de valor especiales "NaN", "-Infinity" e "Infinity" (con o sin mayúsculas). Ejemplos: "-3.2e-8", "nan". |
intNN |
Cualquier entero con signo que no supere el tamaño del tipo. Ejemplo: "-3". |
string |
Cualquier cadena que contenga texto codificado en UTF-8 o ASCII de 7 bits. Las comillas insertadas deben incluir una barra invertida. Los valores de cadena deben ir entre comillas dobles para escapar los siguientes caracteres especiales:
|
Timestamp |
Cadena en formato RFC 3339 o ISO 8601.
Ejemplos: "2024-08-02T15:01:23.045Z" (RFC 3339) y "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 signo que no supere el tamaño del tipo. Ejemplo: "1234". |
Si no se puede realizar una conversión, la comparación falla.
Cuando una conversión requiere una cadena, también puede usar un número o texto sin comillas si no contienen caracteres especiales, como espacios y operadores. Del mismo modo, cuando una conversión requiere un número, puede usar una cadena 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 que se va a convertir en un tipo de número entero de 64 bits, escribes el valor como una cadena, como "9223372036854775807".
Tipos de campos de registro
Así se determina el tipo de un campo de entrada de registro:
Los campos de registro definidos en el 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 objetos
protoPayload
también son campos de protocol buffer y tienen tipos explícitos. El nombre del tipo de protocolo de búfer se almacena en el campo"@type"
deprotoPayload
. Para obtener más información, consulta la asignación de JSON.Cuando filtras por un campo asociado al tipo de mensaje
Any
, se recorre automáticamente el campovalue
. Por lo tanto, no lo incluyas en la consulta. Para obtener más información, consulta Solución de problemas.Los campos de registro 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 cadenas tienen el tipo
string
.
Los números enteros largos (de 64 bits) se almacenan en campos de cadena, ya que no se pueden representar exactamente como valores
double
.- 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 casos, esos valores se almacenan en campos de cadena.
Comentarios
Los comentarios empiezan con dos guiones (--
) y el texto que sigue a los guiones se ignora hasta el final de la línea. Los comentarios se pueden colocar al principio, entre los términos y al final de un filtro.
Puedes usar comentarios en los siguientes casos:
Para añadir anotaciones a los filtros complejos con información sobre la función de una cláusula, siga 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, añade o quita el prefijo de comentario:
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 !=
) y desigualdad (<
, <=
, >
y >=
) depende del tipo subyacente del nombre de campo de la izquierda.
- Todos los tipos numéricos: la igualdad y la desigualdad tienen su significado normal para los números.
bool
: igualdad significa que tienen el mismo valor booleano. La desigualdad se define comotrue
>false
.enum
: igualdad significa el mismo valor de enumeración. La desigualdad usa los valores numéricos subyacentes de los literales de enumeración.Duration
: igualdad significa que la duración es la misma. La desigualdad se basa en la duración. Por ejemplo, como duraciones,"1s"
>"999ms"
.Timestamp
: igualdad significa el mismo instante en el tiempo. Si a y b son valores deTimestamp
, a < b significa que a es anterior a b.bytes
: los operandos se comparan byte a byte, de izquierda a derecha.string
: las comparaciones no distinguen entre mayúsculas y minúsculas. En concreto, ambos operandos se normalizan primero mediante la normalización Unicode NFKC_CF y, a continuación, se comparan lexicográficamente. Sin embargo, las búsquedas con expresiones regulares no se normalizan. Para obtener más información sobre cómo buscar entradas de registro mediante expresiones regulares, consulta el artículo Usar expresiones regulares.
El operador de subcadena (:
) se aplica a string
y bytes
, y se gestiona como la igualdad, excepto que el operando de la derecha solo tiene que ser igual a una parte del campo de la izquierda. Las coincidencias de subcadenas en campos indexados no aprovechan las ventajas de los índices de registro.
Restricciones globales
Si la comparación consta de un solo valor, se denomina restricción global. El registro usa el operador has (:
) para determinar si algún campo de una entrada de registro o su carga útil contiene la restricción global.
Si es así, la comparación se realiza correctamente.
La consulta más sencilla escrita en términos de una restricción global es un valor único:
"The Cat in The Hat"
Puedes combinar restricciones globales con los operadores AND
y OR
para hacer una consulta más interesante. Por ejemplo, si quieres mostrar todas las entradas de registro que tengan un campo que contenga cat
y otro que contenga hat
o bat
, escribe la consulta de la siguiente manera:
("cat" AND ("hat" OR "bat"))
En este caso, hay 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 los registros de un valor concreto.
Por ejemplo, si buscas en tu registro de actividad entradas que contengan 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 utilices la función SEARCH
integrada y que consultes los campos indexados. Para obtener más información, consulta la sección Buscar entradas de registro rápidamente de este documento.
Functions
Puedes usar funciones integradas como restricciones globales en las consultas:
function = identifier ( [ argument { , argument } ] )
donde 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
es útil para crear una vista de registro personalizada en un contenedor de registro que contenga entradas de registro de muchos Google Cloud proyectos, carpetas u organizaciones.
El único argumento de la función log_id
es un ID de registro no codificado en URL:
log_id(non-URL-encoded log ID)
Por ejemplo, la siguiente consulta devuelve todos los registros de auditoría de actividad:
log_id("cloudaudit.googleapis.com/activity")
En la consulta anterior, el argumento solo consta de caracteres alfanuméricos y caracteres especiales (/
, _
, -
y .
).
enviar
La función cast
acepta dos parámetros: el campo LogEntry
que se va a convertir y el tipo de datos al que se va a convertir el campo:
cast([FIELD], [TYPE][, OPTION])
Los parámetros de la expresión anterior se definen de la siguiente manera:
[FIELD]
: el nombre de un campo de la entrada de registro, comologName
ojsonPayload.a_field
.[TYPE]
: 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 la 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, TIME_ZONE("America/New_York")) =~ "^2025-04-02.*"
regexp_extract
Usa la función regexp_extract
para buscar 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]
: el nombre de un campo de la entrada de registro, comologName
ojsonPayload.a_field
.[REGULAR_EXPRESSION]
: la expresión regular RE2 que debe contener un grupo de captura ((...)
). Si se necesita un grupo adicional para la expresión regular, se debe usar un grupo sin captura(?:...)
. Si hay varios grupos de captura o ninguno, se produce un error.
Puedes encadenar las funciones cast
y regexp_extract
:
CAST(REGEXP_EXTRACT(CAST(timestamp, STRING), "\\d+:\\d+:(\\d+)"), INT64) < 30
En el ejemplo anterior, el campo timestamp
se convierte en una cadena. La expresión regular captura el valor del campo de segundos de la cadena timestamp
y, a continuación, lo convierte en un número entero para realizar una comparación numérica. La consulta
result muestra una entrada de registro cuando el campo de segundos de su marca de tiempo es inferior a
30.
fuente
La función source
coincide con las entradas de registro de un recurso concreto en la jerarquía de organizaciones, carpetas y Google Cloud proyectos.
La función source
no coincide con los recursos secundarios. Por ejemplo, si usas source(folders/folder_123)
, se buscarán coincidencias en los registros del recurso folder_123
, pero no en los registros de los recursos del proyecto Google Cloud dentro de folder_123
.
Para consultar los registros de un nivel de recurso concreto, utiliza la siguiente sintaxis:
source(RESOURCE_TYPE/RESOURCE_ID)
Recurso | Consulta de ejemplo |
---|---|
Organización | source(organizations/ ORGANIZATION_ID) |
Carpeta | source(folders/ FOLDER_ID) |
Google Cloud proyectos | source(projects/ PROJECT_ID) |
muestra
La función sample
selecciona una fracción del número total de entradas de registro:
sample([FIELD], [FRACTION])
[FIELD]
es el nombre de un campo de 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 cadena o un valor numérico.
Asignar el valor [FIELD]
a 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 de [FIELD]
que se van a incluir. Es un número mayor que 0,0 y no superior a 1,0. Por ejemplo, si especifica 0.01
, la muestra contiene aproximadamente el 1 % de todas las entradas de registro que tienen valores para [FIELD]
. Si [FRACTION]
es 1, se eligen todas las entradas de registro que tengan valores para [FIELD]
.
Ejemplo: La siguiente consulta devuelve el 25 % de las entradas de registro del registro syslog
:
logName = "projects/my-project/logs/syslog" AND sample(insertId, 0.25)
Detalles:
Se usa un algoritmo determinista basado en el cifrado hash para determinar si una entrada de registro se incluye o se excluye de la muestra. La precisión de la muestra resultante depende de la distribución de los valores cifrados.
Si los valores cifrados con hash no se distribuyen de forma uniforme, la muestra resultante puede estar sesgada.
En el peor de los casos, cuando [FIELD]
siempre contiene el mismo valor, la muestra resultante contiene el [FRACTION]
de todas las entradas de registro o ninguna.
Si [FIELD]
aparece en una entrada de registro, significa lo siguiente:
- Se calcula un hash del valor.
- El valor cifrado, que es un número, se divide entre el valor cifrado 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 la muestra.
Si [FIELD]
no aparece en una entrada de registro, significa que:
- Si
[FIELD]
forma parte de las secciones de carga útil olabels
de la entrada de registro, no se seleccionará para la muestra, aunque[FRACTION]
sea 1. - De lo contrario, la entrada de registro se trata como si
[FIELD]
estuviera en la entrada de registro y el valor de[FIELD]
fuera el valor predeterminado. El valor predeterminado viene determinado por el tipoLogEntry
. Para obtener más información sobre los campos que faltan y los que tienen valores predeterminados, consulta la sección Campos que faltan de este documento.
Para excluir del ejemplo las entradas de registro con campos predeterminados, usa el operador field-exists, :*
. La siguiente consulta genera una muestra del 1 % de las entradas de registro que han proporcionado explícitamente un valor para field
:
field:* AND sample(field, 0.01)
ip_in_net
La función ip_in_net
determina si una dirección IP de una entrada de registro está incluida en una subred. Puedes usarlo para saber si una solicitud procede de una fuente interna o externa. Por ejemplo:
ip_in_net([FIELD], [SUBNET])
[FIELD]
es un campo con valor de cadena en la entrada de registro que contiene una dirección o un intervalo de direcciones IP. El campo puede repetirse, en cuyo caso solo uno de los campos repetidos debe tener una dirección o un intervalo contenidos en la subred.
[SUBNET]
es una constante de cadena para una dirección IP o un intervalo. Se produce un error si [SUBNET]
no es una dirección o un intervalo de direcciones IP válidos, tal como se describe más adelante en esta sección.
Ejemplo: La siguiente consulta prueba una dirección IP en la carga útil de las entradas de registro del registro my_log
:
logName = "projects/my_project/logs/my_log" AND ip_in_net(jsonPayload.realClientIP, "10.1.2.0/24")
Detalles: Si falta [FIELD]
en una entrada de registro, se le asigna un valor predeterminado o no contiene una dirección o un intervalo de IP válidos, la función devuelve el valor false. Para obtener más información sobre los campos que faltan y los que tienen valores predeterminados, consulta la sección Campos obligatorios de este documento.
A continuación se muestran ejemplos de direcciones e intervalos IP admitidos:
- IPv4:
10.1.2.3
- Subred IPv4:
10.1.2.0/24
- CIDR IPv6:
1234:5678:90ab:cdef:1234:5678:90ab:cdef
- Subred IPv6 de CIDR:
1:2::/48
SEARCH
función
Puedes usar la función SEARCH
integrada para buscar 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 un literal de cadena. En el primer formulario, se busca toda la entrada de registro. En el segundo formulario, especifica el campo de la entrada de registro que quieres buscar.
Debes especificar el campo query
. Si no se especifica este campo, se devuelve un error.
Cuando se procesa la función SEARCH
, la cadena query
se procesa mediante un analizador de texto que divide la cadena en tokens. Cloud Logging siempre realiza comparaciones que no distinguen entre mayúsculas y minúsculas, incluso en el caso de los tokens envueltos entre comillas inversas. Este comportamiento es diferente al de BigQuery, que conserva las mayúsculas y minúsculas en los tokens envueltos entre comillas inversas.
Para obtener información sobre las reglas del analizador, consulta el documento de BigQuery Reglas del analizador de texto.
Cuando crees una búsqueda, ten en cuenta lo siguiente:
Los tokens no distinguen entre mayúsculas y 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 "world". Como
SEARCH
busca coincidencias exactas y no coincidencias de subcadenas, las funciones anteriores no coinciden con un campo cuyo valor sea "worldwide".Si no especifica el campo en el que quiere buscar, la función
SEARCH
coincidirá con una entrada de registro cuando esta contenga 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 quieres buscar, la función
SEARCH
solo buscará en ese campo. Se produce una coincidencia cuando ese campo contiene todos los tokens, pero el orden de los tokens no importa.Las siguientes funciones solo producen una coincidencia cuando el campo
textPayload
contiene los tokens "hello" y "world":SEARCH(textPayload, "hello world")
Para imponer una concordancia exacta que no distinga entre mayúsculas y minúsculas en una frase, escribe la frase entre comillas inversas. Por ejemplo, las siguientes funciones coinciden con la cadena "hello world":
SEARCH("`hello world`") SEARCH("`Hello World`") SEARCH("`HELLO WORLD`")
Como se usan comillas inversas en las siguientes funciones, se obtienen resultados diferentes:
SEARCH("`hello world`") SEARCH("`world hello`")
El lenguaje de las consultas de Logging admite diferentes formas de buscar en los datos de registro. Cuando se busca una cadena, es más eficiente usar la función SEARCH
que realizar una búsqueda global o una búsqueda de subcadenas.
Sin embargo, no puedes usar la función SEARCH
para buscar coincidencias en campos que no sean de texto.
Para obtener información sobre cómo realizar operaciones de búsqueda, consulta el artículo Minimizar las búsquedas globales y de subcadenas.
Buscar por hora
En la interfaz, puedes definir límites específicos en la fecha y la hora de las entradas de registro que se muestran. Por ejemplo, si añade las siguientes condiciones a su consulta, en el panel de resultados se mostrarán exactamente las entradas de registro del periodo de 30 minutos indicado y no podrá desplazarse fuera de ese intervalo de fechas:
timestamp >= "2023-11-29T23:00:00Z" timestamp <= "2023-11-29T23:30:00Z"
Cuando escribas una consulta con una marca de tiempo, debes usar fechas y horas en el formato que se ha mostrado anteriormente.
También puedes buscar entradas de registro con las combinaciones de teclas timestamp
. Por ejemplo, puedes introducir una fecha con un operador de comparación para obtener todas las entradas de registro posteriores a un día concreto:
timestamp > "2023-11-29"
Usar expresiones regulares
Puede usar expresiones regulares para crear consultas y filtros para receptores, métricas y cualquier otro lugar en el que se usen 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. El lenguaje de las consultas de Logging usa la sintaxis RE2. Para obtener una explicación completa de la sintaxis de RE2, consulta la wiki de RE2 en GitHub.
Las consultas de expresiones regulares tienen las siguientes características:
Solo se pueden asociar campos de tipo cadena con una expresión regular.
No se realiza la normalización de cadenas. Por ejemplo,
kubernetes
no se considera igual queKUBERNETES
. Para obtener más información, consulta la sección Operadores de comparación.Las consultas distinguen entre mayúsculas y minúsculas, y no están ancladas de forma predeterminada.
Los operadores booleanos se pueden usar entre varias expresiones regulares en la parte derecha de los operadores de comparación de expresiones regulares,
=~
y!~
.
Una consulta de expresión regular tiene la siguiente estructura:
Coincidir con un patrón:
jsonPayload.message =~ "regular expression pattern"
No coincide con ningún patrón:
jsonPayload.message !~ "regular expression pattern"
=~
y !~
cambian la consulta a una consulta de expresión regular, y el patrón que estás intentando buscar debe estar entre comillas dobles. Para buscar patrones que contengan comillas dobles, debes usar una barra
inversa.
Ejemplos de consultas de registros mediante expresiones regulares
Tipo de consulta | Ejemplo |
---|---|
Consulta estándar | sourceLocation.file =~ "foo" |
Consulta con búsqueda que no distingue entre mayúsculas y minúsculas | labels.subnetwork_name =~ "(?i)foo" |
Consulta que contiene comillas | jsonPayload.message =~ "field1=\"bar.*\"" |
Consultar con un valor booleano or |
labels.pod_name =~ "(foo|bar)" |
Consultar mediante anclas | logName =~ "/my%2Flog$" |
Consulta que no coincide con un patrón | labels.pod_name !~ "foo" |
Consulta con un operador booleano | labels.env =~ ("^prod.*server" OR "^staging.*server") |
Consulta que empieza por un valor | logName =~ "^foo" |
Consulta que termina con un valor | logName =~ "foo$" |
Encontrar entradas de registro rápidamente
Para encontrar entradas de registro de forma eficiente, haz lo siguiente:
- Consulta con campos indexados.
- Minimiza el número de entradas de registro que se deben buscar.
Usar campos indexados
El registro siempre indexa los siguientes campos LogEntry
:
- resource.type
- resource.labels.*
- logName
- gravedad
- timestamp
- insertId
- operation.id
- trace
- httpRequest.status
- labels.*
- split.uid
También puedes añadir campos indexados personalizados a cualquier contenedor de registro o usar la función SEARCH
para acelerar tu consulta.
Optimizar las consultas
Para que tus búsquedas sean más rápidas, reduce el número de registros, el número de entradas de registro o el intervalo de tiempo de tus búsquedas. Y lo mejor es que puedes reducir los tres.
Ejemplo: usar la función SEARCH
En lugar de hacer búsquedas globales o de subcadenas, puedes usar la función SEARCH
para usar índices y optimizar tus consultas.
Ejemplo: Usar el nombre de registro correcto
Especifica el registro que contiene las entradas que te interesan. Asegúrate de conocer el nombre real del registro inspeccionando una de tus entradas de registro. Por ejemplo, el panel de resultados muestra que la sección Compute Engine contiene un registro llamado "activity". Si examinas con más detalle las entradas del registro de auditoría de actividad del administrador, verás que el registro se llama "cloudaudit.googleapis.com/activity".
La siguiente comparación es incorrecta. No coincide con nada porque usa el nombre de registro incorrecto:
logName = "projects/my-project-id/logs/activity" -- WRONG!
La siguiente comparación es correcta. Elige entradas de registro de auditoría de actividad de administración. Debes codificar la URL del nombre del registro, tal como se muestra a continuación:
logName = "projects/my-project-id/logs/cloudaudit.googleapis.com%2Factivity"
Ejemplo: elegir las entradas de registro adecuadas
Si sabes que las entradas de registro que quieres proceden de una instancia de VM concreta, especifícala. Comprueba que los nombres de las etiquetas sean correctos inspeccionando una de las entradas de registro que quieras 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: elegir el periodo adecuado
Especifica el periodo en el que quieres buscar. Una forma rápida de determinar marcas de tiempo útiles en 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. Para crear una marca de tiempo aceptable para Logging, sustituye el espacio entre la fecha y la hora por la letra T
.
Por ejemplo, para buscar en las últimas tres horas:
timestamp >= "2023-06-27T14:40:00-04:00"
Por ejemplo, para buscar contenido publicado entre hace tres y cinco horas, haz lo siguiente:
timestamp >= "2023-06-27T12:40:00-04:00" AND timestamp <= "2023-06-27T14:40:00-04:00"
Minimizar las restricciones disyuntivas
Las consultas que solo usan restricciones conjuntivas, AND
, pueden aprovechar mejor los índices. Puedes usar la restricción disyuntiva, OR
, pero estas consultas pueden ser lentas y no pueden usar índices.
Por ejemplo, SEARCH("foo") AND SEARCH("bar")
usa índices y será más rápida que una consulta como SEARCH("foo") OR SEARCH("bar")
.
Minimizar las búsquedas globales y de subcadenas
Evita la tentación de tomar atajos al escribir consultas.
Ejemplo: No uses búsquedas globales
Si buscas una entrada de registro con "Hello Kitty" en la carga útil, haz lo siguiente:
No uses la búsqueda global. Por un lado, todas son búsquedas de subcadenas:
"Hello Kitty" -- THIS CAUSES A SLOW SEARCH!
No limites la búsqueda a un solo campo, aunque debas mantener la búsqueda de subcadenas:
textPayload:"Hello Kitty"
Usa una prueba de igualdad si puedes:
textPayload = "Hello Kitty"
Haz referencia a campos concretos de una carga útil si tus entradas de registro tienen cargas útiles estructuradas:
jsonPayload.my_favorite_cat = "Hello Kitty"
Usa un campo indexado para restringir la búsqueda:
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 búsqueda que no distingue entre mayúsculas y minúsculas:SEARCH("
Hello Kitty
")No uses la función
SEARCH
y especifiques texto parcial. Por ejemplo, la siguiente función no coincide con "Hello Kitty".SEARCH("
Hello Kit
")
Ejemplos de búsqueda
Las entradas de registro que se muestran son las que coinciden con una consulta. Si el menú Ir a hora contiene un valor, la pantalla se desplazará hasta ese momento. Aquí tienes algunos ejemplos de consultas:
resource.type=k8s_cluster
Busca todas las entradas de registro de Google Kubernetes Engine. Para ver una lista de tipos de recursos, consulta Lista de recursos monitorizados.
Mientras escribes, el panel de consultas sugiere opciones para completar campos como
resource.type
.resource.type=k8s_cluster AND logName:request_log
Busca entradas de registro de clústeres de Google Kubernetes Engine a partir de nombres de registro que contengan
request_log
. Ten en cuenta varios aspectos:- El operador
=
es una igualdad exacta. El tipo de recurso debe ser exactamente"k8s_cluster"
, excepto por las mayúsculas y minúsculas. - El operador
:
significa "tiene". El campologName
debe contenerrequest_log
, con independencia de las mayúsculas y minúsculas. El nombre de registro real es mucho más largo. Usar:
puede ralentizar las búsquedas. - Las dos comparaciones se unen mediante
AND
. También puedes usarOR
, peroAND
se da por supuesto si no incluyes el operador.
- El operador
resource.type = (gce_instance OR aws_ec2_instance) AND severity >= ERROR
Busca entradas de registro con uno de estos 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.logName = "projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
Busca todas las entradas del registro de auditoría de 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 diferentes tipos de recursos. El ID de registro,cloudaudit.googleapis.com/activity
, debe estar codificado por URL en el nombre del registro. Usar la igualdad en la comparación acelera la búsqueda. Para obtener más información, consulta el artículo Interpretar los registros de auditoría.unicorn
Busca entradas de registro que contengan
unicorn
en cualquier campo y con cualquier combinación de mayúsculas y minúsculas. 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
en algún campo yphoenix
en algún campo.textPayload:(unicorn phoenix)
Busca entradas de registro cuyo campo
textPayload
contenga tantounicorn
comophoenix
en cualquier orden. ElAND
está implícito entre las dos palabras.textPayload:"unicorn phoenix"
Busca entradas de registro cuyo campo
textPayload
contenga la cadena"unicorn phoenix"
.NOT textPayload: "unicorn phoenix"
Busca entradas de registro cuyo campo
textPayload
no contenga la cadena"unicorn phoenix"
. Este tipo de consulta reduce las entradas de registro no deseadas.timestamp >= "2023-11-29T23:00:00Z" timestamp <= "2023-11-29T23:30:00Z"
Busca entradas de registro en un periodo de 30 minutos.
Solución de problemas
Problemas de sintaxis
Si tienes problemas con las expresiones de tus consultas, comprueba lo siguiente:
Tu consulta cumple las reglas de sintaxis, con paréntesis y comillas coincidentes.
Los nombres de los campos de entrada de registro están escritos correctamente.
Las operaciones booleanas se escriben en mayúsculas (
AND
,OR
yNOT
).Asegúrate de usar
NULL_VALUE
para representar los valores nulos de JSON.Las expresiones booleanas como restricciones globales o como el lado derecho de las comparaciones deben incluirse entre paréntesis para mayor claridad. Por ejemplo, las dos consultas siguientes parecen 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 caracteres especiales. En caso de duda, añade comillas dobles. Por ejemplo, en el siguiente caso, la primera comparación no es válida porque se ha insertado el operador de subcadena (
:
). 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. Para usar comillas dobles para escapar caracteres especiales con el comando
gcloud logging
, 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 por un campo asociado al tipo de mensaje
Any
, se recorre automáticamente el campovalue
. Por lo tanto, no incluyasvalue
en la consulta.Por ejemplo, el campo
Status
de un mensajeAuditLog
tiene un campodetails
de tipogoogle.protobuf.Any
. Para consultar el campodetails
, omite el campovalue
al especificar el filtro:Qué debes hacer
protoPayload.status.details.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"
Qué no debes hacer
protoPayload.status.details.value.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"