Lenguaje de consulta de Logging

En este documento, se describe en términos generales el lenguaje de consulta 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, revisa las especificaciones formales de la API de Google para el filtrado.

Para ver ejemplos de consultas comunes que puedes usar, lee Muestras de consultas con el Explorador de registros.

Descripción general

Puedes usar el lenguaje de consulta de Logging en el Explorador de registros de la consola 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 a fin de 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 una carpeta o un proyecto de Google Cloud.

Puedes compilar consultas basadas en el campo indexado de LogEntry con los operadores lógicos AND y OR. Con el campo resource.type en los siguientes ejemplos, la gramática del lenguaje de consulta de Logging se ve de la siguiente manera:

  • Restricción simple: resource.type = "gae_app"

  • Restricción conjuntiva: resource.type = "gae_app" AND severity = "ERROR"

  • Restricción disyuntiva: resource.type = "gae_app" OR resource.type = "gce_instance"

    • Alternativamente: resource.type = ("gae_app" OR "gce_instance")
  • Expresión disyuntiva o conjuntiva compleja: resource.type = "gae_app" AND (severity = "ERROR" OR "error")

A continuación, se muestra un ejemplo simple de una 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 string 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. 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 consulta de Logging no distingue entre mayúsculas y 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 = "gae_app"

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", entonces, 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]. Los elementos de la comparación se describen a continuación:

  • [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 string, una función o una expresión entre paréntesis. Por ejemplo, "gae_app" Para 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 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 las 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 siempre deben estar en mayúscula. 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]

Los elementos de la comparación se describen a continuación:

  • [FIELD_NAME]: Es el nombre de la ruta de un campo en una entrada de registro. Los ejemplos del nombre de campo son los siguientes:

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

    Si un componente de un nombre de ruta tiene caracteres especiales, el nombre de la ruta 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 con expresiones regulares, consulta Usa 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, 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 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 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 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 campo labels.

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

    -- Returns TRUE
    NOT missingField=foo
    
  • Cuando usas el operador de comparación de desigualdad != en un campo faltante, el resultado es FALSE:

    -- 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. Una string también se considera un escalar. Los campos que se pueden convertir en (o desde) una string, como Duration y Timestamp, 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, entonces jsonPayload.x.age tendría el valor 24.

  • 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 operador OR. Por ejemplo, si jsonPayload.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 escalar. En la siguiente tabla, se explica qué valores se pueden convertir en los tipos de campos 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:

  • Strings que comienzan con + (más), - (menos) o . (punto).

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

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

Timestamp

Una string en formato RFC 3339 o ISO 8601. Examples y coma; “2014-10-02T15&colon;01&colon;23.045Z” (RFC 3339), “2014-10-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 exactitud de nanosegundos.

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" de protoPayload. Para obtener más información, consulta la asignación de JSON.

    Cuando filtras un campo asociado con el tipo de mensaje Any, el campo value se recorre automáticamente. Por lo tanto, no lo incluyas en la consulta. Para 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 o false tienen el tipo bool.
    • Los campos cuyos valores son strings tienen el tipo string.

    Los números enteros largos (de 64 bits) se almacenan en campos de cadenas, porque no se pueden representar como valores double de manera exacta.

  • Los tipos Duration y Timestamp 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 cualquier texto que esté después de ellos se ignorará hasta el final de la línea. Los comentarios se pueden colocar al principio de un filtro, entre términos y al final de un filtro.

Puedes usar los comentarios en los siguientes casos:

  • Para anotar tus filtros complejos con información sobre lo que hace una cláusula, haz lo siguiente:

     -- 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 por true>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 valores Timestamp, 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 cómo buscar entradas de registro con expresiones regulares, consulta Usa 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 forma fácil de consultar tus registros en busca de un valor particular es mediante una restricción global. 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"

Aunque las restricciones globales son sencillas, pueden ser lentas. Para obtener más información, consulta Busca entradas de registro con rapidez 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 convertirá en la conversión y el tipo de datos en el que se convierte 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, como logName o jsonPayload.a_field.

  • [TYPE]: El tipo de datos, como STRING, INT64, FLOAT64 y BOOL.

Por ejemplo, la siguiente consulta convierte el campo timestamp en una STRING 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 substring 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, como logName o jsonPayload.a_field.
  • [REGULAR_EXPRESSION]: Es la expresión regular RE2 que debe contener un grupo de captura ((...)). Se debe usar un grupo (?:...) sin captura si se requiere una agrupación adicional para la expresión regular. Si hay varios grupos de captura o no se usa ningún grupo de captura, se generará 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, se convierte el campo timestamp como una string. La expresión regular captura la porción de milisegundos de la string 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 la jerarquía de organizaciones, carpetas y proyectos de Google Cloud.

La función source no coincide con los recursos secundarios. Por ejemplo, el uso de 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)

sample

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 alrededor 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 secciones labels, 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 tipo LogEntry 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 un literal de string. 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 procesa la cadena query que divide la cadena en tokens. Cloud Logging siempre realiza comparaciones que no distinguen mayúsculas de minúsculas, incluso para los tokens unidos con comillas simples. Este comportamiento difiere del de BigQuery, que conserva las mayúsculas y minúsculas en los tokens unidos con acentos graves. Para obtener información sobre las reglas del analizador, consulta el documento de BigQuery Reglas del analizador de texto.

Al crear 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 único campo contiene el token “world”. Debido a que SEARCH realiza coincidencias exactas y no de substring, las funciones anteriores no coinciden con un campo cuyo valor es "mundial".

  • Si no especificas el campo que se debe buscar, la función SEARCH coincide con una entrada de registro cuando esta contiene todos los tokens. Sin embargo, el orden de los tokens no importa y no es necesario que 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 que se debe buscar, la función SEARCH solo buscará en ese campo. Se produce una coincidencia cuando el 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 imponer una concordancia exacta sin distinguir mayúsculas de minúsculas, pero una concordancia exacta en una frase, escribe la frase entre acentos graves. Por ejemplo, las siguientes funciones coinciden con la string "hello world":

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

    Debido a que las comillas simples se usan en las siguientes funciones, producen diferentes resultados:

    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 eficiente 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 Minimiza las búsquedas globales y de subcadenas.

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, la vista previa muestra exactamente las entradas de registro en el período de 30 minutos indicado y no podrás desplazarte fuera de ese período:

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

Cuando escribes una consulta con una marca de tiempo, debes usar fechas y horas en el formato que se muestra arriba.

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 > "2016-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. Puedes usar expresiones regulares en el compilador de consultas y mediante la Google Cloud CLI.

Una expresión regular es una secuencia de caracteres que define una búsqueda. El lenguaje de consulta de Logging usa la sintaxis RE2. Para obtener una explicación completa de 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 a 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 el lado derecho del operador de comparación de expresiones regulares =~!~.

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")
Consulta 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 más eficiente, haz lo siguiente:

  • Consulta mediante campos indexados.
  • Minimiza la cantidad de entradas de registro que se deben buscar.

Usa campos indexados

Logging siempre indexa los siguientes campos de LogEntry:

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, la vista previa muestra que hay un registro en la sección de Compute Engine 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
2016-06-27 17:39:00-04:00
$ date --rfc-3339=s --date="3 hours ago"
2016-06-27 14:40:00-04:00
$ date --rfc-3339=s --date="5 hours ago"
2016-06-27 12:40:00-04:00

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 >= "2016-06-27T14:40:00-04:00"

Como otro ejemplo, para buscar entre tres y cinco horas atrás, usa esto:

timestamp >= "2016-06-27T12:40:00-04:00" AND
timestamp <= "2016-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 una razón, todas son búsquedas de substrings:

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

  • debes limitar la búsqueda a un solo campo, incluso si debes mantener la búsqueda de substring, como se ve a continuación:

       textPayload:"Hello Kitty"
       

  • debes usar una prueba de igualdad, si puedes, como se ve a continuación:

       textPayload = "Hello Kitty"
       

  • 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"
       

  • 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ón SEARCH realiza una coincidencia que no distingue mayúsculas de 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")
      

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=gae_app

Busca todas las entradas de registro de App Engine. Para obtener una lista de los tipos de recursos, consulta la Lista de recursos supervisados.

A medida que escribes, la vista previa sugiere elementos completados para campos como resource.type.

resource.type=gae_app AND logName:request_log

Busca entradas de registro para apps de App 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 exactamente "gae_app", excepto para mayúsculas y minúsculas.
  • El operador : significa “has”. El campo logName debe contener request_log, en mayúsculas o minúsculas. El nombre real del registro 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 usar OR, pero se supone que es AND si omites el operador.
resource.type = (gce_instance OR aws_ec2_instance) AND severity >= ERROR

Busca entradas de registro con cualquiera 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 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 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 y phoenix en algún campo.

textPayload:(unicorn phoenix)

Busca entradas de registro cuyo campo textPayload contenga unicorn y phoenix 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 >= "2016-11-29T23:00:00Z" timestamp <= "2016-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 dos consultas siguientes 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, la primera comparación a continuació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, el campo value se recorre automáticamente. Por lo tanto, no incluyas value en la consulta.

    Por ejemplo, el campo Status en un mensaje AuditLog tiene un campo details que es del tipo google.protobuf.Any. Para consultar el campo details, omite el campo value cuando especifiques el filtro:

    • Lo que debes hacer

      protoPayload.status.details.conditionNotMet.userVisibleMessage =~ "Specified reservation.*"
      
    • Qué no debes hacer

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