Consultas en SQL de muestra

Este documento contiene consultas de muestra que puedes usar para consultar tus datos de registros y de seguimiento.

Compatibilidad con el lenguaje SQL

Las consultas que se usan en la página Análisis de registros admiten funciones de GoogleSQL, con algunas excepciones.

Los siguientes comandos SQL no son compatibles con las consultas en SQL que se emiten con la página Análisis de registros:

  • Comandos DDL y DML
  • Funciones definidas por el usuario de JavaScript
  • Funciones de BigQuery ML
  • Variables de SQL

Las siguientes opciones solo se admiten cuando consultas un conjunto de datos vinculado con las páginas de BigQuery Studio y Looker Studio, o con la herramienta de línea de comandos de bq:

  • Funciones definidas por el usuario de JavaScript
  • Funciones de BigQuery ML
  • Variables de SQL

Prácticas recomendadas

Para establecer el período de tu consulta, te recomendamos que uses el selector de período. Por ejemplo, para ver los datos de la semana pasada, selecciona Últimos 7 días en el selector de período. También puedes usar el selector de período para especificar una hora de inicio y finalización, especificar una hora para ver alrededor y cambiar las zonas horarias.

Datos de registros

Si incluyes un campo timestamp en la cláusula WHERE, no se usará el parámetro de configuración del selector de período. En el siguiente ejemplo, se muestra cómo filtrar por marca de tiempo:

-- Matches log entries whose timestamp is within the most recent 1 hour.
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Datos de seguimiento

Si incluyes un campo start_time en la cláusula WHERE, no se usará el parámetro de configuración del selector de período. En el siguiente ejemplo, se muestra cómo filtrar por marca de tiempo:

-- Matches trace spans whose start_time is within the most recent 1 hour.
WHERE start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Para obtener más información sobre cómo filtrar por tiempo, consulta Funciones de tiempo y Funciones de marca de tiempo.

Antes de comenzar

  1. Accede a tu cuenta de Google Cloud . Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Habilita la API de Observability.

    Roles necesarios para habilitar las APIs

    Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin), que contiene el permiso serviceusage.services.enable. Obtén más información para otorgar roles.

    Habilitar la API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Habilita la API de Observability.

    Roles necesarios para habilitar las APIs

    Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin), que contiene el permiso serviceusage.services.enable. Obtén más información para otorgar roles.

    Habilitar la API

  8. Para obtener los permisos que necesitas para cargar la página de Log Analytics, escribir, ejecutar y guardar consultas privadas en tus datos de seguimiento, pídele a tu administrador que te otorgue los siguientes roles de IAM:

    • Usuario con acceso a vistas de observabilidad (roles/observability.viewAccessor) en las vistas de observabilidad que deseas consultar. Este rol admite condiciones de IAM, que te permiten restringir el otorgamiento a una vista específica. Si no adjuntas una condición al otorgamiento del rol, la principal podrá acceder a todas las vistas de observabilidad. Las vistas de observabilidad están disponibles en versión preliminar pública.
    • Usuario de Observability Analytics (roles/observability.analyticsUser) en tu proyecto. Este rol contiene los permisos necesarios para guardar y ejecutar consultas privadas, y para ejecutar consultas compartidas.
    • Visor de registros (roles/logging.viewer) en tu proyecto.
    • Descriptor de acceso de vista de registros (roles/logging.viewAccessor) en el proyecto que almacena las vistas de registros que deseas consultar.

    Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

    También puedes obtener los permisos necesarios a través de roles personalizados o cualquier otro rol predefinido.

Cómo usar las búsquedas en esta página

  1. En la consola de Google Cloud , ve a la página Análisis de registros:

    Ir a Análisis de registros

    Si usas la barra de búsqueda para encontrar esta página, selecciona el resultado cuyo subtítulo es Logging.

  2. En el panel Consulta, haz clic en  SQL y, luego, copia y pega una consulta en el panel de consulta en SQL.

    Datos de registros

    Antes de copiar una consulta, en la cláusula FROM, reemplaza los siguientes campos

    • PROJECT_ID: Es el identificador del proyecto.
    • LOCATION: Es la ubicación de la vista de registros o la vista de estadísticas.
    • BUCKET_ID: Es el nombre o el ID del bucket de registros.
    • LOG_VIEW_ID: Es el identificador de la vista de registros, que se limita a 100 caracteres y solo puede incluir letras, dígitos, guiones bajos y guiones.

    A continuación, se muestra el formato de la cláusula FROM para una vista de registro:

    FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
    

    Los ejemplos de registros en esta página consultan una vista de registro. Para consultar una vista de Analytics, usa el siguiente formato de ruta de acceso: `analytics_view.PROJECT_ID.LOCATION.ANALYTICS_VIEW_ID`. En la expresión anterior, PROJECT_ID es el ID de tu proyecto, y LOCATION y ANALYTICS_VIEW_ID son la ubicación y el nombre de tu vista de Analytics.

    Datos de seguimiento

    A continuación, se muestra el formato de la causa FROM para consultar la vista _AllSpans:

    FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
    

    La cláusula FROM contiene los siguientes campos:

    • PROJECT_ID: Es el identificador del proyecto.
    • LOCATION: Es la ubicación del bucket de observabilidad.
    • _Trace es el nombre del bucket de observabilidad.
    • Spans es el nombre del conjunto de datos.
    • _AllSpans es el nombre de la vista.

Para usar las consultas que se muestran en este documento en la página de BigQuery Studio o la herramienta de línea de comandos de bq, edita la cláusula FROM y, luego, ingresa la ruta de acceso al conjunto de datos vinculado.

Datos de registros

Por ejemplo, para consultar la vista _AllLogs en el conjunto de datos vinculado llamado mydataset que se encuentra en el proyecto myproject, la ruta de acceso es myproject.mydataset._AllLogs.

Datos de seguimiento

Por ejemplo, para consultar la vista _AllSpans en el conjunto de datos vinculado llamado my_linked_dataset que se encuentra en el proyecto myproject, la ruta de acceso es `myproject.my_linked_dataset._AllSpans`.

Casos de uso habituales

En esta sección, se enumeran varios casos de uso comunes que pueden ayudarte a crear tus consultas personalizadas.

Cómo mostrar las entradas de registro en el bucket de registros predeterminado

Para consultar el bucket _Default, ejecuta la siguiente consulta:

SELECT
  timestamp, severity, resource.type, log_name, text_payload, proto_payload, json_payload
FROM
  `PROJECT_ID.LOCATION._Default._AllLogs`
-- Limit to 1000 entries
LIMIT 1000

Extrae el valor del campo por expresión regular

Para extraer un valor de una cadena con una expresión regular, usa la función REGEXP_EXTRACT:

SELECT
  -- Display the timestamp, and the part of the name that begins with test.
  timestamp, REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Get the value of jobName, which is a subfield in a JSON structure.
  JSON_VALUE(json_payload.jobName) IS NOT NULL
ORDER BY timestamp DESC
LIMIT 20

Para obtener más información, consulta la documentación de REGEXP_EXTRACT.

Para las coincidencias de subcadenas, como la consulta anterior, el uso de la función CONTAINS_SUBSTR genera una consulta más eficiente.

Mostrar todos los datos de registro

Para consultar la vista _AllSpans, ejecuta la siguiente consulta:

-- Display all data.
SELECT *
FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
-- Limit to 10 entries.
LIMIT 10

Mostrar información de tramos comunes

Para mostrar información común del intervalo, como la hora de inicio y la duración, ejecuta la siguiente consulta:

SELECT
  start_time,
  -- Set the value of service name based on the first non-null value in the list.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,
  name AS span_name,
  duration_nano,
  status.code AS status,
  trace_id,
  span_id
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
LIMIT 10

Para obtener más información, consulta Expresiones condicionales.

Mostrar los percentiles 50 y 99 de la latencia del intervalo

Para mostrar los percentiles 50 y 99 de la latencia de cada servicio de RPC, ejecuta la siguiente consulta:

SELECT
  -- Compute 50th and 99th percentiles for each service
  STRING(attributes['rpc.service']) || '/' || STRING(attributes['rpc.method']) AS rpc_service_method,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS duration_nano_p50,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS duration_nano_p99
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans whose kind field has a value of 2 (SPAN_KIND_SERVER).
  kind = 2
GROUP BY rpc_service_method

Para obtener más información sobre la enumeración, consulta la documentación de OpenTelemetry: SpanKind.

Para ver los resultados de forma gráfica, puedes crear un gráfico con la dimensión configurada en rpc_service_method. Puedes agregar dos medidas, una para el promedio del valor de duration_nano_p50 y otra para el promedio del campo duration_nano_p99.

Filtra entradas de registro

Para aplicar un filtro a tu consulta, agrega una cláusula WHERE. La sintaxis que usas en esta cláusula depende del tipo de datos del campo. En esta sección, se proporcionan varios ejemplos para diferentes tipos de datos.

Cómo filtrar entradas de registro por tipo de carga útil

Las entradas de registro pueden tener uno de los tres tipos de carga útil. Para filtrar las entradas de registro por el tipo de carga útil, usa una de las siguientes cláusulas:

  • Cargas útiles de texto

    -- Matches log entries that have a text payload.
    WHERE text_payload IS NOT NULL
    
  • Cargas útiles de JSON

    -- Matches log entries that have a JSON payload.
    WHERE json_payload IS NOT NULL
    
  • Cargas útiles de tipo proto

    -- Matches log entries that have a proto payload.
    -- Because proto_payload has a data type of RECORD, this statement tests
    -- whether a mandatory subfield exits.
    WHERE proto_payload.type IS NOT NULL
    

En los resultados de la consulta, los campos json_payload y proto_payload se renderizan en JSON, por lo que puedes navegar por ellos.

Cómo filtrar los datos de registro por marca de tiempo

Para filtrar las entradas de registro por su marca de tiempo, te recomendamos que uses el selector de período. Sin embargo, también puedes especificar timestamp en la cláusula WHERE:

-- Matches log entries whose timestamp is within the most recent hour
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Para obtener más información sobre cómo filtrar por tiempo, consulta Funciones de tiempo y Funciones de marca de tiempo.

Filtrar por recurso

Para filtrar tus datos de registro y seguimiento por recurso, agrega una instrucción resource.type a la cláusula WHERE:

-- Matches log entries whose resource type is gce_instance
WHERE resource.type = "gce_instance"

Filtrar por gravedad

Para filtrar tus datos de registro por gravedad, agrega una instrucción severity a la cláusula WHERE:

-- Matches log entries whose severity is INFO or ERROR
WHERE severity IS NOT NULL AND severity IN ('INFO', 'ERROR')

También puedes filtrar tus entradas de registro por el campo severity_number, que es un número entero. Por ejemplo, la siguiente cláusula coincide con todas las entradas de registro cuyo nivel de gravedad es al menos NOTICE:

-- Matches log entries whose severity level is at least NOTICE
WHERE severity_number IS NOT NULL AND severity_number > 200

Para obtener información sobre los valores enumerados, consulta LogSeverity.

Filtrar por nombre de registro

Para filtrar tus datos de registro por nombre de registro, agrega una instrucción log_name o log_id a la cláusula WHERE:

  • El nombre del registro especifica la ruta del recurso:

    -- Matches log entries that have the following log ID.
    WHERE log_name="projects/cloud-logs-test-project/logs/cloudaudit.googleapis.com%2Factivity"
    
  • El ID de registro omite la ruta de acceso al recurso:

    -- Matches log entries that have the following log id.
    WHERE log_id = "cloudaudit.googleapis.com/data_access"
    

Cómo filtrar entradas de registro por etiqueta de recurso

Las etiquetas de recursos se almacenan como una estructura JSON. Para filtrar por el valor de un campo dentro de una estructura JSON, usa la función JSON_VALUE:

SELECT
  timestamp, JSON_VALUE(resource.labels.zone) AS zone, json_payload, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries whose resource type is gce_instance and whose zone is
  -- us-central1-f. Because resource has data type JSON, you must use JSON_VALUE
  -- to get the value for subfields, like zone.
  resource.type = "gce_instance" AND
  JSON_VALUE(resource.labels.zone) = "us-central1-f"
ORDER BY timestamp ASC

La consulta anterior se basa en el formato de las etiquetas de recursos, ya que se almacenan en una entrada de registro. A continuación, se muestra un ejemplo del campo de recursos:

{
   type: "gce_instance"
   labels: {
      instance_id: "1234512345123451"
      project_id: "my-project"
      zone: "us-central1-f"
   }
}

Para obtener información sobre todas las funciones que pueden recuperar y transformar datos JSON, consulta Funciones JSON.

Filtrar por solicitud HTTP

Para consultar solo las entradas de registro que tienen un campo de solicitud HTTP, usa la siguiente cláusula:

-- Matches log entries that have a HTTP request_method field.
-- Don't compare http_request to NULL. This field has a data type of RECORD.
WHERE http_request.request_method IS NOT NULL

También puedes usar la instrucción IN:

-- Matches log entries whose HTTP request_method is GET or POST.
WHERE http_request.request_method IN ('GET', 'POST')

Filtrar por estado HTTP

Para consultar solo las entradas de registro que tienen un estado HTTP, usa la siguiente cláusula:

-- Matches log entries that have an http_request.status field.
WHERE http_request.status IS NOT NULL

Cómo filtrar por un campo dentro de un tipo de datos JSON

Para consultar solo las entradas de registro cuando el subcampo de un campo con un tipo de datos JSON tiene un valor específico, extrae el valor con la función JSON_VALUE:

-- Compare the value of the status field to NULL.
WHERE JSON_VALUE(json_payload.status) IS NOT NULL

La cláusula anterior es ligeramente diferente de la siguiente:

-- Compare the status field to NULL.
WHERE json_payload.status IS NOT NULL

La primera cláusula prueba si el valor del campo de estado es NULL. La segunda cláusula prueba si existe el campo de estado. Supongamos que una vista de registro contiene dos entradas de registro. Para una entrada de registro, el campo json_payload tiene el siguiente formato:

{
    status: {
        measureTime: "1661517845"
    }
}

Para la otra entrada de registro, el campo json_payload tiene una estructura diferente:

{
    @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
    jobName: "projects/my-project/locations/us-central1/jobs/test1"
    relativeUrl: "/food=cake"
    status: "NOT_FOUND"
    targetType: "APP_ENGINE_HTTP"
}

La cláusula WHERE json_payload.status IS NOT NULL coincide con ambas entradas de registro. Sin embargo, la cláusula WHERE JSON_VALUE(json_payload.status) IS NOT NULL solo coincide con la segunda entrada de registro.

Cómo filtrar entradas de registro

Para aplicar un filtro a tu consulta, agrega una cláusula WHERE. La sintaxis que usas en esta cláusula depende del tipo de datos del campo. En esta sección, se proporcionan varios ejemplos para diferentes tipos de datos.

Filtrar por tipos de datos de cadena

El campo name se almacena como un String.

  • Para analizar solo los intervalos en los que se especifica name, usa la siguiente cláusula:

    -- Matches spans that have a name field.
    WHERE name IS NOT NULL
    
  • Para analizar solo los intervalos en los que name tiene el valor "POST", usa la siguiente cláusula:

    -- Matches spans whose name is POST.
    WHERE STRPOS(name, "POST") > 0
    
  • Para analizar solo los intervalos en los que name contiene el valor "POST", usa el operador LIKE junto con comodines:

    -- Matches spans whose name contains POST.
    WHERE name LIKE "%POST%"
    

Filtrar por tipos de datos de números enteros

El campo kind es un número entero que puede tomar valores entre cero y cinco:

  • Para analizar solo los intervalos en los que se especifica kind, usa la siguiente cláusula:

    -- Matches spans that have field named kind.
    WHERE kind IS NOT NULL
    
  • Para analizar los intervalos cuyo valor de kind es uno o dos, usa la siguiente cláusula:

    -- Matches spans whose kind value is 1 or 2.
    WHERE kind IN (1, 2)
    

Filtrar por tipos de datos de RECORD

Algunos campos del esquema de seguimiento tienen un tipo de datos RECORD. Estos campos pueden almacenar una o más estructuras de datos, o bien almacenar entradas repetidas de la misma estructura de datos.

Filtrar por estado o código de estado

El campo status es un ejemplo de un campo cuyo tipo de datos es RECORD. Este campo almacena una estructura de datos, con miembros etiquetados como code y message.

  • Para analizar solo los tramos cuando el campo status.code tiene un valor de 1, agrega la siguiente cláusula:

    -- Matches spans that have a status.code field that has a value of 1.
    WHERE status.code = 1
    

    El campo status.code se almacena como un número entero.

  • Para analizar los intervalos en los que el campo status no es EMPTY, agrega la siguiente cláusula:

    -- Matches spans that have status field. When the status field exists, it
    -- must contain a subfield named code.
    -- Don't compare status to NULL, because this field has a data type of RECORD.
    WHERE status.code IS NOT NULL
    

Los campos events y links se almacenan con un tipo de datos RECORD, pero son campos repetidos.

  • Para hacer coincidir los intervalos que tienen al menos un evento, usa la siguiente cláusula:

    -- Matches spans that have at least one event. Don't compare events to NULL.
    -- The events field has data type of RECORD and contains a repeated fields.
    WHERE ARRAY_LENGTH(events) > 0
    
  • Para que coincidan los períodos que tienen un evento cuyo campo name tiene el valor de message, usa la siguiente cláusula:

    WHERE
      -- Exists is true when any event in the array has a name field with the
      -- value of message.
      EXISTS(
        SELECT 1
        FROM UNNEST(events) AS ev
        WHERE ev.name = 'message'
      )
    

Cómo filtrar por tipos de datos JSON

El campo attributes es del tipo JSON. Cada atributo individual es un par clave-valor.

  • Para analizar solo los intervalos en los que se especifica attributes, usa la siguiente cláusula:

    -- Matches spans where at least one attribute is specified.
    WHERE attributes IS NOT NULL
    
  • Para analizar solo los intervalos en los que la clave de atributo llamada component tiene un valor de "proxy", usa la siguiente cláusula:

    -- Matches spans that have an attribute named component with a value of proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') = 'proxy'
    

    También puedes usar una instrucción LIKE junto con comodines para realizar una prueba de contención:

    -- Matches spans that have an attribute named component whose value contains proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') LIKE '%proxy%'
    

Agrupa y agrega entradas de registro

En esta sección, se amplían los ejemplos anteriores y se ilustra cómo puedes agrupar y agregar entradas de registro. Si no especificas una agrupación, pero sí una agregación, se imprimirá un resultado porque SQL trata todas las filas que satisfacen la cláusula WHERE como un grupo.

Todas las expresiones SELECT deben incluirse en los campos de grupo o agregarse.

Agrupa las entradas de registro por marca de tiempo

Para agrupar los datos por marca de tiempo, usa la función TIMESTAMP_TRUNC, que trunca una marca de tiempo en una granularidad especificada, como HOUR:

SELECT
  -- Truncate the timestamp by hour.
  TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
  JSON_VALUE(json_payload.status) AS status,
  -- Count the number log entries in each group.
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries that have a status field whose value isn't NULL.
  json_payload IS NOT NULL AND JSON_VALUE(json_payload.status) IS NOT NULL
GROUP BY
  -- Group by hour and status
  hour,status
ORDER BY hour ASC

Para obtener más información, consulta la documentación de TIMESTAMP_TRUNC y las funciones de fecha y hora.

Agrupa las entradas de registro por recurso

La siguiente consulta muestra cómo agrupar las entradas de registro por el tipo de recurso y, luego, contar la cantidad de entradas de registro en cada grupo:

SELECT
   -- Count the number of log entries for each resource type
   resource.type, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY resource.type
LIMIT 100

Agrupa las entradas de registro por gravedad

La siguiente consulta muestra cómo agrupar las entradas de registro por gravedad y, luego, contar la cantidad de entradas de registro en cada grupo:

SELECT
  -- Count the number of log entries for each severity.
  severity, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  severity IS NOT NULL
GROUP BY severity
ORDER BY severity
LIMIT 100

Agrupa las entradas de registro por su log_id

La siguiente consulta muestra cómo agrupar las entradas de registro por ID de registro y, luego, contar la cantidad de entradas de registro en cada grupo:

SELECT
  -- Count the number of log entries for each log ID.
  log_id, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY log_id
ORDER BY count DESC
LIMIT 100

Calcula la latencia promedio de las solicitudes HTTP por URL

La siguiente consulta ilustra cómo agrupar las entradas de registro por la URL y la ubicación de la solicitud HTTP, y, luego, contar la cantidad de entradas de registro en cada grupo:

SELECT
  -- Compute the average latency for each group. Because the labels field has a
  -- data type of JSON, use JSON_VALUE to get the value of checker_location.
  JSON_VALUE(labels.checker_location) AS location,
  AVG(http_request.latency.seconds) AS secs, http_request.request_url
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries when the request_method field is GET.
  http_request IS NOT NULL AND http_request.request_method IN ('GET')
GROUP BY
  -- Group by request URL and location
  http_request.request_url, location
ORDER BY location
LIMIT 100

Calcula el promedio de bytes enviados para una prueba de subred

La siguiente consulta muestra cómo agrupar las entradas de registro según la ubicación especificada en las etiquetas de recursos y, luego, calcular la cantidad de entradas de registro en cada grupo:

SELECT
  -- Compute the average number of bytes sent per location. Because labels has
  -- a data type of JSON, use JSON_VALUE to get the value of the location field.
  -- bytes_sent is a string. Must cast to a FLOAT64 before computing average.
  JSON_VALUE(resource.labels.location) AS location,
  AVG(CAST(JSON_VALUE(json_payload.bytes_sent) AS FLOAT64)) AS bytes
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  resource.type = "gce_subnetwork" AND json_payload IS NOT NULL
GROUP BY
  -- Group by location
  location
LIMIT 100

Para obtener más información, consulta Funciones de JSON y Funciones de conversión.

Cuenta las entradas de registro con un campo que coincide con un patrón

Para devolver la substring que coincide con una expresión regular, usa la función REGEXP_EXTRACT:

SELECT
  -- Extract the value that begins with test.
  -- Count the number of log entries for each name.
  REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  json_payload.jobName IS NOT NULL
GROUP BY name
ORDER BY count
LIMIT 20

Para ver ejemplos adicionales, consulta la documentación de REGEXP_EXTRACT.

Agrega y agrupa datos de seguimiento

En esta sección, se ilustra cómo puedes agrupar y agregar intervalos. Si no especificas una agrupación, pero sí una agregación, se imprimirá un resultado, ya que SQL trata todas las entradas que satisfacen la cláusula WHERE como un solo grupo.

Todas las expresiones SELECT deben incluirse en los campos de grupo o agregarse.

Agrupa los períodos por hora de inicio

Para agrupar los datos por hora de inicio, usa la función TIMESTAMP_TRUNC, que trunca una marca de tiempo en una granularidad especificada, como HOUR:

SELECT
  -- Truncate the start time to the hour. Count the number of spans per group.
  TIMESTAMP_TRUNC(start_time, HOUR) AS hour,
  status.code AS code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans shows start time is within the previous 12 hours.
  start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)
GROUP BY
  -- Group by hour and status code.
  hour, code
ORDER BY hour DESC

Para obtener más información, consulta la documentación de TIMESTAMP_TRUNC y las funciones de fecha y hora.

Recuento de intervalos por código de estado

Para mostrar el recuento de intervalos con un código de estado específico, ejecuta la siguiente consulta:

SELECT
  -- Count the number of spans for each status code.
  status.code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE status.code IS NOT NULL
GROUP BY status.code

Si reemplazas status.code por kind, la consulta anterior informa la cantidad de intervalos para cada valor de la enumeración kind. Del mismo modo, si reemplazas status.code por name, los resultados de la consulta mostrarán la cantidad de entradas para cada nombre de intervalo.

Calcula la duración promedio de todos los intervalos

Para mostrar la duración promedio después de agrupar los datos de los tramos por nombre, ejecuta la siguiente consulta:

SELECT
  -- Group by name, and then compute the average duration for each group.
  name,
  AVG(duration_nano) AS nanosecs,
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY name
ORDER BY nanosecs DESC

Calcula la duración promedio y los percentiles por nombre de servicio

La siguiente consulta calcula el recuento de tramos y varias estadísticas para cada servicio:

SELECT
  -- Set the service name by the first non-null value.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,

  -- Count the number spans for each service name. Also compute statistics.
  COUNT(*) AS span_count,
  AVG(duration_nano) AS avg_duration_nano,
  MIN(duration_nano) AS min_duration_nano,
  MAX(duration_nano) AS max_duration_nano,

  -- Calculate percentiles for duration
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS p50_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(95)] AS p95_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS p99_duration_nano,

  -- Count the number of unique trace IDs. Also, collect up to 5 unique
  -- span names and status codes.
  COUNT(DISTINCT trace_id) AS distinct_trace_count,
  ARRAY_AGG(DISTINCT name IGNORE NULLS LIMIT 5) AS sample_span_names,
  ARRAY_AGG(DISTINCT status.code IGNORE NULLS LIMIT 5) AS sample_status_codes
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY service_name
ORDER BY span_count DESC

En esta sección, se describen dos enfoques que puedes usar para buscar en varias columnas de la vista que consultas:

  • Búsquedas basadas en tokens: Especificas la ubicación de la búsqueda, una consulta de búsqueda y, luego, usas la función SEARCH. Dado que la función SEARCH tiene reglas específicas sobre cómo se buscan los datos, te recomendamos que leas la documentación de SEARCH.

  • Búsquedas basadas en subcadenas: Proporcionas la ubicación de la búsqueda, un literal de cadena y, luego, usas la función CONTAINS_SUBSTR. El sistema realiza una prueba que no distingue mayúsculas de minúsculas para determinar si el literal de cadena existe en una expresión. La función CONTAINS_SUBSTR devuelve TRUE cuando existe el literal de cadena y FALSE en caso contrario. El valor de búsqueda debe ser un literal STRING, pero no el literal NULL.

La siguiente consulta conserva solo las filas que tienen un campo que coincide exactamente con "35.193.12.15":

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- The use of backticks prevents the string from being tokenized.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  SEARCH(t,"`35.193.12.15`")
ORDER BY timestamp ASC
LIMIT 20

Cuando se omiten las comillas inversas en la cadena de consulta, esta se divide según las reglas definidas en la documentación de SEARCH. Por ejemplo, cuando se ejecuta la siguiente instrucción, la cadena de consulta se divide en cuatro tokens: "35", "193", "12" y "15":

  SEARCH(t,"35.193.12.15")

La instrucción SEARCH anterior coincide con una fila cuando un solo campo coincide con los cuatro tokens. El orden de los tokens no importa.

Puedes incluir varias instrucciones SEARCH en una consulta. Por ejemplo, en la consulta anterior, podrías reemplazar el filtro en el ID de registro por una instrucción como la siguiente:

  SEARCH(t,"`cloudaudit.googleapis.com/data_access`")

La instrucción anterior busca en todos los campos de las entradas de registro en la vista de registro, mientras que la instrucción original solo busca en el campo log_id de las entradas de registro.

Para realizar varias búsquedas en varios campos, separa las cadenas individuales con un espacio. Por ejemplo, la siguiente instrucción coincide con las filas en las que un campo contiene "Hello World", "feliz" y "días":

  SEARCH(t,"`Hello World` happy days")

Por último, puedes buscar campos específicos en lugar de buscar en una tabla completa. Por ejemplo, la siguiente instrucción solo busca en las columnas llamadas text_payload y json_payload:

   SEARCH((text_payload, json_payload) ,"`35.222.132.245`")

Para obtener información sobre cómo se procesan los parámetros de la función SEARCH, consulta la página de referencia de BigQuery Funciones de búsqueda.

Por ejemplo, la siguiente consulta recupera todas las entradas del registro de auditoría de acceso a los datos con una dirección IP específica cuyos registros de fecha y hora se encuentran en un período específico. Por último, la consulta ordena los resultados y, luego, muestra los 20 más antiguos:

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- CONTAINS_SUBSTR performs a contains-test.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  CONTAINS_SUBSTR(t,"35.193.12.15")
ORDER BY timestamp ASC
LIMIT 20

Consulta varias vistas

Las instrucciones de consulta analizan una o más tablas o expresiones y muestran las filas de resultados calculados. Por ejemplo, puedes usar instrucciones de consulta para combinar los resultados de las instrucciones SELECT en diferentes tablas o conjuntos de datos de diversas maneras y, luego, seleccionar las columnas de los datos combinados.

Para unir vistas, se aplican las siguientes restricciones:

  1. Las ubicaciones de las vistas satisfacen una de las siguientes condiciones:

    • Todas las vistas tienen la misma ubicación.
    • Todas las vistas se encuentran en la ubicación global o us.
  2. Cuando los recursos de almacenamiento usan claves de encriptación administradas por el cliente (CMEK), se debe cumplir una de las siguientes condiciones:

    • Los recursos de almacenamiento que usan CMEK utilizan la misma clave de Cloud KMS.
    • Los recursos de almacenamiento que usan la CMEK tienen un ancestro común, y ese ancestro especifica una clave de Cloud KMS predeterminada que se encuentra en la misma ubicación que los recursos de almacenamiento.

    Cuando uno o más recursos de almacenamiento usan la CMEK, el sistema encripta los datos temporales que genera la unión con la clave común de Cloud KMS o la clave predeterminada de Cloud KMS del elemento superior.

Por ejemplo, supongamos que tienes dos vistas que residen en la misma ubicación. Luego, puedes unir estas vistas cuando se cumpla alguna de las siguientes condiciones:

  • Los recursos de almacenamiento no usan CMEK.
  • Un recurso de almacenamiento usa CMEK y el otro no.
  • Ambos recursos de almacenamiento usan la CMEK y la misma clave de Cloud KMS.
  • Ambos recursos de almacenamiento usan CMEK, pero con claves diferentes. Sin embargo, los recursos comparten un ancestro que especifica una clave de Cloud KMS predeterminada que se encuentra en la misma ubicación que los recursos de almacenamiento.

    Por ejemplo, supongamos que la jerarquía de recursos para un bucket de registros y un bucket de observabilidad incluye la misma organización. Puedes unir vistas en esos buckets cuando, para esa organización, configuraste los parámetros de configuración predeterminados de recursos para Cloud Logging y para los buckets de observabilidad con la misma clave predeterminada de Cloud KMS para la ubicación de almacenamiento.

Cómo unir dos vistas de registro por el ID de seguimiento

Para combinar información de dos tablas, usa uno de los operadores de unión:

SELECT
  -- Do an inner join on two tables by using the span ID and trace ID.
  -- Don't join only by span ID, as this field isn't globally unique.
  -- From the first view, show the timestamp, severity, and JSON payload.
  -- From the second view, show the JSON payload.
  a.timestamp, a.severity, a.json_payload, b.json_payload, a.span_id, a.trace
FROM  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1` a
JOIN  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2` b
ON
  a.span_id = b.span_id AND
  a.trace = b.trace
LIMIT 100

Consulta dos vistas de registros con una instrucción de unión

Para combinar los resultados de dos o más instrucciones SELECT y descartar las filas duplicadas, usa el operador UNION. Para conservar las filas duplicadas, usa el operador UNION ALL:

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
-- Create a union of two log views
FROM(
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1`
  UNION ALL
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2`
)
-- Sort the union by timestamp.
ORDER BY timestamp ASC
LIMIT 100

Cómo unir datos de registros y de seguimiento con el ID de seguimiento

La siguiente consulta une los datos de registro y de seguimiento con los IDs de intervalo y de seguimiento:

SELECT
  T.trace_id,
  T.span_id,
  T.name,
  T.start_time,
  T.duration_nano,
  L.log_name,
  L.severity,
  L.json_payload
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans` AS T
JOIN
  `PROJECT_ID.LOCATION._Default._AllLogs` AS L
ON
  -- Join log and trace data by both the span ID and trace ID.
  -- Don't join only on span ID, this field isn't globally unique.
  T.span_id = L.span_id
  -- A regular expression is required because the storage format of the trace ID
  -- differs between a log view and a trace view.
  AND T.trace_id = REGEXP_EXTRACT(L.trace, r'/([^/]+)$')
WHERE T.duration_nano > 1000000
LIMIT 10

La respuesta de la consulta enumera el ID de seguimiento y el ID de intervalo, lo que te permite consultarlos de forma individual para recopilar más información. Además, los resultados indican la gravedad de la entrada de registro y la carga útil de JSON.

Cómo quitar entradas de registro duplicadas

El Análisis de registros no quita las entradas de registro duplicadas antes de que se ejecute una consulta. Este comportamiento es diferente al que se produce cuando consultas entradas de registro con el Explorador de registros, que quita las entradas duplicadas comparando los nombres de los registros, las marcas de tiempo y los campos de ID de inserción.

Puedes usar la validación a nivel de la fila para quitar las entradas de registro duplicadas.

Para obtener más información, consulta Solución de problemas: Hay entradas de registro duplicadas en mis resultados de Log Analytics.

¿Qué sigue?

Para obtener documentación de referencia de SQL o más ejemplos, consulta los siguientes documentos: