Lenguaje de las consultas de Logging

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")
  • 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 y OR. 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, usa NULL_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, usa NULL_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 tipo MonitoredResource.

  • httpRequest.latency si tu primer identificador de ruta es httpRequest, el siguiente identificador debe ser un campo del tipo HttpRequest.

  • 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 campo labels.

  • 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 o protoPayload) o si está en una etiqueta de la sección labels 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 es FALSE:

    -- 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. Un string también se considera un escalar. Los campos que se pueden convertir en una cadena (o desde una cadena), como Duration y Timestamp, 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 valor 24.

  • 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 operador OR. Por ejemplo, si jsonPayload.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:

  • Cadenas que empiezan por + (más), - (menos) o . (punto).

  • Cadenas con ~ (tilde), = (igual), () (paréntesis), : (dos puntos), > (mayor que), < (menor que), , (coma), . (punto) o * (asterisco).

  • Cualquier secuencia de escape, por ejemplo, \t.

Timestamp

Cadena en formato RFC 3339 o ISO 8601. Ejemplos: "2024-08-02T15&colon;01&colon;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 ±hh:mm. Las marcas de tiempo se representan con una precisión de nanosegundos.

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" de protoPayload. 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 campo value. 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 o false tienen el tipo bool.
    • 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 tipos Duration y Timestamp 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 como true>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 de Timestamp, 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, como logName o jsonPayload.a_field.

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

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, como logName o jsonPayload.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 o labels 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 tipo LogEntry. 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 que KUBERNETES. 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:

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ón SEARCH 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 campo logName debe contener request_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 usar OR, pero AND se da por supuesto si no incluyes 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 menos ERROR, 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 y phoenix en algún campo.

textPayload:(unicorn phoenix)

Busca entradas de registro cuyo campo textPayload contenga tanto unicorn como phoenix en cualquier orden. El AND 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 y NOT).

  • 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 campo value. Por lo tanto, no incluyas value en la consulta.

    Por ejemplo, el campo Status de un mensaje AuditLog tiene un campo details de tipo google.protobuf.Any. Para consultar el campo details, omite el campo value 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.*"