Procesa registros a gran escala con Cloud Dataflow

Last reviewed 2015-11-19 UTC

Google Cloud proporciona la infraestructura escalable que necesitas para manejar operaciones de análisis de registros grandes y diversas. En este instructivo, se muestra cómo usar Google Cloud para compilar canalizaciones de análisis que procesen entradas de registro de varias fuentes. Combinas los datos de registro de manera que te ayuden a extraer información significativa y mantener las estadísticas derivadas de los datos, que se pueden usar para análisis, informes y revisión.

Descripción general

A medida que tu aplicación se vuelve más compleja, es cada vez más difícil obtener estadísticas a partir de los datos capturados en tus registros. Los registros provienen de una mayor cantidad de fuentes, por lo que pueden ser difíciles de recopilar y consultar para obtener información útil. La compilación, la operación y el mantenimiento de tu propia infraestructura para analizar los datos de registro a gran escala pueden requerir una amplia experiencia en la ejecución de sistemas y almacenamiento distribuidos. Este tipo de infraestructura dedicada a menudo representa un gasto de capital único, lo que da como resultado una capacidad fija. Esto dificulta su escala más allá de la inversión inicial. Estas limitaciones pueden afectar tu empresa porque conducen a demoras en la generación de información significativa y estadísticas prácticas a partir de tus datos.

En esta solución, se muestra cómo superar estas limitaciones mediante el uso de productos de Google Cloud, como se ilustra en el siguiente diagrama.

En la solución, se usan varios componentes de Google Cloud

En esta solución, se ejecuta un conjunto de microservicios de muestra en Google Kubernetes Engine (GKE) para implementar un sitio web. Cloud Logging recopila registros de estos servicios y los guarda en depósitos de Cloud Storage. Dataflow luego procesa los registros mediante la extracción de metadatos y el cálculo de agregaciones básicas. La canalización de Dataflow está diseñada con el fin de procesar los elementos de registro a diario y así generar métricas agregadas para los tiempos de respuesta del servidor, según los registros de cada día. Por último, el resultado de Dataflow se carga en las tablas de BigQuery, en las que se puede analizar para proporcionar inteligencia empresarial. En esta solución, también se explica cómo puedes cambiar la canalización a fin de que se ejecute en modo de transmisión, para el procesamiento de registros asíncronos de latencia baja.

En este instructivo, se proporciona una canalización de Dataflow de muestra, una aplicación web de muestra, información de configuración y pasos para ejecutar la muestra.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

  • GKE para implementar microservicios
  • Cloud Logging para recibir y exportar registros
  • Cloud Storage para almacenar registros exportados en modo por lotes
  • Pub/Sub para trasmitir los registros exportados en modo de transmisión
  • Dataflow para procesar los datos de registro
  • BigQuery para almacenar el resultado del procesamiento y admitir consultas enriquecidas en ese resultado

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Antes de comenzar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the BigQuery, Cloud Storage, Pub/Sub, Dataflow, GKE and Logging APIs.

    Enable the APIs

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

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the BigQuery, Cloud Storage, Pub/Sub, Dataflow, GKE and Logging APIs.

    Enable the APIs

Configura tu entorno

En este instructivo usarás Cloud Shell para ingresar comandos. Cloud Shell te brinda acceso a la línea de comandos en la consola de Google Cloud y, además, incluye Google Cloud CLI y otras herramientas que necesitas para el desarrollo en Google Cloud. Cloud Shell aparece como una ventana en la parte inferior de la consola de Google Cloud. Es posible que la inicialización tome unos minutos, pero la ventana aparecerá de inmediato.

Para configurar tu entorno y clonar el repositorio de Git que se usa en este instructivo mediante Cloud Shell, sigue estos pasos:

  1. En Google Cloud Console, abre Cloud Shell.

    Abra Cloud Shell

  2. Asegúrate de que estés trabajando en el proyecto que acabas de crear. Reemplaza [YOUR_PROJECT_ID] por tu proyecto de Google Cloud recién creado.

    gcloud config set project [YOUR_PROJECT_ID]
    
  3. Configura la zona de procesamiento predeterminada. Para los fines de este instructivo, es us-east1. Si realizas la implementación en un entorno de producción, elige la región en la que deseas hacerlo.

    export REGION=us-east1
    gcloud config set compute/region $REGION
    

Clona el repositorio de muestra

  • Clona el repositorio que contiene las secuencias de comandos y la lógica de la aplicación que usas en este instructivo.

    git clone https://github.com/GoogleCloudPlatform/processing-logs-using-dataflow.git
    cd processing-logs-using-dataflow/services
    

Configure las variables de entorno

# name your bucket
export PROJECT_ID=[YOUR_PROJECT_ID]
# name your GKE cluster
export CLUSTER_NAME=cluster-processing-logs-using-dataflow

# name the bucket for this tutorial
export BUCKET_NAME=${PROJECT_ID}-processing-logs-using-dataflow

# name the logging sink for this tutorial
export SINK_NAME=sink-processing-logs-using-dataflow

# name the logging sink for this tutorial
export DATASET_NAME=processing_logs_using_dataflow

Implementa la aplicación de muestra en un clúster de Google Kubernetes Engine nuevo

# create the cluster and deploy sample services
./cluster.sh $PROJECT_ID $CLUSTER_NAME up

Acerca de la implementación de la aplicación de muestra

En la implementación de muestra, se hace el modelo de una aplicación de compras. En esta muestra, los usuarios pueden visitar la página principal de un sitio de venta minorista, buscar productos individuales y, luego, tratar de ubicar los productos en tiendas físicas cercanas. La app consta de tres microservicios: HomeService, BrowseService y LocateService. Cada servicio está disponible en un extremo de API en un espacio de nombres compartidos. Los usuarios acceden a los servicios agregando /home, /browse y /locate a la URL base.

La aplicación está configurada para registrar las solicitudes HTTP entrantes en stdout.

Usa Google Kubernetes Engine con Cloud Logging

En este ejemplo, los microservicios se ejecutan en un clúster de Kubernetes Engine, que es un grupo de instancias de Compute Engine o nodos, que ejecutan Kubernetes. De forma predeterminada, GKE configura cada nodo para que ofrezca una variedad de servicios, incluidos la supervisión, la verificación de estado y el registro centralizado. En esta solución, se usa esta compatibilidad integrada con Logging para enviar los registros de cada microservicio a Cloud Storage. Como alternativa para las aplicaciones que registran información en archivos, las cuales no se incluyen en esta solución, puedes configurar el registro a nivel de clúster con Kubernetes.

Cada microservicio se ejecuta en un pod individual en el clúster. Cada pod se ejecuta en un nodo y se expone como un extremo HTTP único mediante el uso de los servicios de GKE.

Los microservicios se ejecutan en nodos individuales.

Los nodos del clúster ejecutan un agente de Cloud Logging que captura los mensajes de registro. Cuando los registros ya están disponibles en Logging, una secuencia de comandos exporta los registros automáticamente a un bucket de Cloud Storage mediante la asistencia de Logging disponible en la CLI de gcloud.

También puedes configurar los registros que se exportarán a Cloud Storage mediante el Explorador de registros. Esta solución usa la CLI de gcloud porque es obligatorio al momento de exportar varios registros.

Con el uso de Cloud Storage como un destino de las exportaciones de registros, las entradas de registro de tipo LogEntry se guardan en lotes por hora en archivos JSON individuales. Estas entradas estructuradas de Logging incluyen metadatos adicionales que especifican cuándo se creó cada mensaje de registro, qué recurso o instancia lo generó, cuál es su nivel de gravedad, etcétera. En el siguiente ejemplo de una entrada de Logging, en el elemento structPayload.log puedes ver el mensaje de registro original que el microservicio generó:

 {
    "insertId": "ugjuig3j77zdi",
    "labels": {
        "compute.googleapis.com/resource_name": "fluentd-gcp-v3.2.0-9q4tr",
        "container.googleapis.com/namespace_name": "default",
        "container.googleapis.com/pod_name": "browse-service-rm7v9",
        "container.googleapis.com/stream": "stdout"
    },
    "logName": "projects/processing-logs-at-scale/logs/browse-service",
    "receiveTimestamp": "2019-03-09T00:33:30.489218596Z",
    "resource": {
        "labels": {
            "cluster_name": "cluster-processing-logs-using-dataflow",
            "container_name": "browse-service",
            "instance_id": "640697565266753757",
            "namespace_id": "default",
            "pod_id": "browse-service-rm7v9",
            "project_id": "processing-logs-at-scale",
            "zone": "us-east1-d"
        },
        "type": "container"
    },
    "severity": "INFO",
    "textPayload": "[GIN] 2019/03/09 - 00:33:23 | 200 |     190.726µs |      10.142.0.6 | GET      /browse/product/1\n",
    "timestamp": "2019-03-09T00:33:23.743466177Z"
 }

Configura los registros

Una vez que el clúster está en ejecución y se implementan los servicios, puedes configurar el registro de la aplicación.

Primero, obtén las credenciales para el clúster, ya que kubectl se usa con el fin de obtener nombres de servicios y así configurar los receptores de exportación de Cloud Logging.

gcloud container clusters get-credentials  $CLUSTER_NAME --region $REGION

En el repositorio de código, services/logging.sh configura los componentes necesarios para el modo por lotes o de transmisión. La secuencia de comandos acepta estos parámetros:

logging.sh [YOUR_PROJECT_ID] [BUCKET_NAME] [streaming|batch] [up|down]

Para los fines de este instructivo, comienza el registro por lotes:

./logging.sh $PROJECT_ID $BUCKET_NAME batch up

En los siguientes pasos, se muestran los comandos que se ejecutan para el modo por lotes:

  1. Crea un bucket de Cloud Storage

    gsutil -q mb gs://[BUCKET_NAME]

  2. Permite el acceso de Cloud Logging al bucket:

    gsutil -q acl ch -g cloud-logs@google.com:O gs://[BUCKET_NAME]

  3. Para cada microservicio, configura las exportaciones de Cloud Logging mediante un receptor:

    gcloud logging sinks create [SINK_NAME] \ storage.googleapis.com/[BUCKET_NAME] \ --log-filter="kubernetes.home_service..." --project=[YOUR_PROJECT_ID]

Actualiza los permisos de destino

Los permisos del destino, en este caso, tu bucket de Cloud Storage, no se modifican cuando creas un receptor. Debes cambiar la configuración de permiso de tu bucket de Cloud Storage para otorgar permiso de escritura a tu receptor.

Para actualizar los permisos del bucket de Cloud Storage, sigue estos pasos:

  1. Identifica la identidad del escritor de tu receptor:

    1. Ve a la página Enrutador de registros:

      Ir a la página Enrutador de registros

      La página Enrutador de registros contiene un resumen de tus receptores, incluida la identidad de escritor del receptor.

    2. IMPORTANTE: Por cada uno de los tres (3) receptores, hay un correo electrónico individual de la cuenta de servicio que debe tener permisos en el bucket de Cloud Storage.

  2. Desde la consola de Google Cloud, haz clic en Almacenamiento > Navegador:

    Ir al navegador

  3. Para abrir la vista detallada, haz clic en el nombre de tu bucket.

  4. Selecciona Permisos y, a continuación, haz clic en Agregar principales.

  5. Establece la Función como Storage Object Creator, a continuación, ingresa la identidad del escritor del receptor.

Consulta Permisos de destino para obtener más información.

Es posible verificar las rutas de los objetos de registro con el comando siguiente:

gsutil ls gs://$BUCKET_NAME | grep service

Cuando el resultado contiene las tres entradas, puedes continuar con los pasos para ejecutar la canalización de datos:

 gs://$BUCKET_NAME/browse-service/
 gs://$BUCKET_NAME/home-service/
 gs://$BUCKET_NAME/locate-service/

Crea el conjunto de datos de BigQuery

bq mk $DATASET_NAME

Genera un poco de carga en los servicios de la aplicación

Instala las utilidades del servidor HTTP de Apache

Usa la herramienta de comparativas del servidor HTTP de Apache (ab) para generar la carga en los servicios.

sudo apt-get update

sudo apt-get install -y apache2-utils

La secuencia de comandos de shell load.sh genera carga en los microservicios mediante la solicitud de respuestas de HomeService, BrowseService y LocateService.

Un solo conjunto de carga consta de una solicitud para el servicio de la página principal y veinte (20) solicitudes cada una para los servicios del navegador y de ubicación.

La siguiente opción genera mil (1,000) conjuntos de carga (con simultaneidad establecida en 3 solicitudes simultáneas).

cd ../services
./load.sh 1000 3

Deja que esto se ejecute durante varios minutos para crear una cantidad suficiente de registros.

Inicia la canalización de Dataflow

Después de que una cantidad de tráfico suficiente llegue los servicios, puedes iniciar la canalización de Dataflow.

Para los fines de este instructivo, la canalización de Dataflow se ejecuta en modo por lotes. La secuencia de comandos de shell pipeline.sh inicia la canalización de forma manual.

cd ../dataflow
./pipeline.sh $PROJECT_ID $DATASET_NAME $BUCKET_NAME run

Comprende la canalización de Dataflow

Dataflow se puede usar para muchos tipos de tareas de procesamiento de datos. El SDK de Dataflow ofrece un modelo de datos unificado que puede representar un conjunto de datos de cualquier tamaño, incluido un conjunto de datos ilimitado o infinito de una fuente de datos que se actualiza de manera continua; es ideal para trabajar con los datos de registro en esta solución. El servicio administrado de Dataflow puede ejecutar trabajos por lotes y de transmisión. Esto significa que puedes usar una base de código única para el procesamiento de datos síncrono o asíncrono basado en eventos y en tiempo real.

El SDK de Dataflow ofrece representaciones simples de datos por medio de una clase de colecciones especializada llamada PCollection. El SDK proporciona transformaciones de datos integradas y personalizadas mediante la clase PTransform. En Dataflow, las transformaciones representan la lógica de procesamiento de una canalización. Las transformaciones se pueden usar para una variedad de operaciones de procesamiento, como unir datos, calcular valores de forma matemática, filtrar la salida de datos o convertir datos de un formato a otro. Para obtener más información sobre las canalizaciones, las PCollections, las transformaciones, las fuentes de E/S y los receptores, consulta el Modelo de programación de Dataflow.

El siguiente diagrama muestra las operaciones de canalización para los datos de registro almacenados en Cloud Storage:

Pasos de las operaciones para la canalización.

Aunque el diagrama puede parecer complejo, Dataflow facilita la compilación y el uso de la canalización. Las siguientes secciones describen las operaciones específicas en cada etapa de la canalización.

Cómo recibir los datos

La canalización comienza con el consumo de entrada de los depósitos de Cloud Storage que contienen los registros de los tres microservicios. Cada colección de registros se convierte en una PCollection de elementos String, en la que cada elemento corresponde a un solo objeto LogEntry. En el siguiente fragmento, homeLogs, browseLogs y locateLogs son del tipo PCollection<String>:

homeLogs = p.apply("homeLogsTextRead", TextIO.read().from(options.getHomeLogSource()));
browseLogs = p.apply("browseLogsTextRead", TextIO.read().from(options.getBrowseLogSource()));
locateLogs = p.apply("locateLogsTextRead", TextIO.read().from(options.getLocateLogSource()));

Para enfrentar los desafíos de un conjunto de datos que se actualiza de manera continua, el SDK de Dataflow utiliza una técnica llamada sistema de ventanas. Este sistema funciona mediante la subdivisión de manera lógica de los datos en una PCollection, según las marcas de tiempo de sus elementos individuales. Debido a que en este caso el tipo de fuente es TextIO, todos los objetos se leen al inicio en una ventana global única, lo que resulta el comportamiento predeterminado.

Recopila los datos en objetos

En el paso siguiente, se combinan las PCollections de microservicios individuales en una sola PCollection mediante la operación Flatten.

PCollection<String> allLogs = PCollectionList
  .of(homeLogs)
  .and(browseLogs)
  .and(locateLogs)
  .apply(Flatten.<String>pCollections());

Esta operación es útil porque cada PCollection fuente contiene el mismo tipo de datos y usa la misma estrategia global del sistema de ventanas. Aunque las fuentes y la estructura de cada registro son las mismas en esta solución, podrías extender esta práctica a un caso en el que la fuente y la estructura sean diferentes.

Con una sola PCollection creada, puedes entonces procesar los elementos String individuales mediante una transformación personalizada que realiza varios pasos en la entrada de registro. Los pasos se ilustran en el diagrama siguiente:

Una transformación procesa mensajes de string para crear mensajes de registro.

  • Deserializa la string JSON en un objeto de Java LogEntry de Cloud Logging.
  • Extrae la marca de tiempo de los metadatos LogEntry.
  • Extrae los siguientes campos individuales del mensaje de registro mediante el uso de expresiones regulares: timestamp, responseTime, httpStatusCode, httpMethod, dirección IP source y extremo destination. Usa estos campos para crear un objeto personalizado con la marca de tiempo LogMessage.
  • Envía los objetos LogMessage a una PCollection nueva.

El siguiente código realiza los pasos:

PCollection<LogMessage> allLogMessages = allLogs
  .apply("allLogsToLogMessage", ParDo.of(new EmitLogMessageFn(outputWithTimestamp, options.getLogRegexPattern())));

Cómo agregar los datos por días

Recuerda que el objetivo es procesar los elementos todos los días para generar métricas agregadas basadas en los registros de cada día. Para lograr esta agregación, se requiere una función analítica que subdivida los datos por día, lo que es posible porque cada LogMessage en PCollection tiene una marca de tiempo. Después de que Dataflow particiona PCollection junto con los límites diarios, las operaciones que admiten las PCollections con ventanas respetarán el esquema del sistema de ventanas.

PCollection<LogMessage> allLogMessagesDaily = allLogMessages
  .apply("allLogMessageToDaily", Window.<LogMessage>into(FixedWindows.of(Duration.standardDays(1))));

Con una PCollection con ventanas única, ahora puedes calcular métricas agregadas diarias en las tres fuentes del archivo de registro de varios días, mediante la ejecución de un solo trabajo de Dataflow.

PCollection<KV<String,Double>> destMaxRespTime = destResponseTimeCollection
  .apply(Max.<String>doublesPerKey());
 // .apply(Combine.<String,Double,Double>perKey(new Max.doublesPerKey()));

PCollection<KV<String,Double>> destMeanRespTime = destResponseTimeCollection
  .apply(Mean.<String,Double>perKey());

Primero, una transformación toma objetos LogMessage como entrada y da como resultado una PCollection de pares clave-valor que asignan los extremos de destino como claves a valores de tiempo de respuesta, como se ilustra en el diagrama siguiente.

Cálculo de las métricas agregadas diarias.

Mediante el uso de esa PCollection, puedes calcular dos métricas agregadas: el tiempo de respuesta máximo por destino y el tiempo de respuesta promedio por destino. Debido a que la PCollection aún se divide por día, el resultado de cada cálculo representa los datos de registro de un solo día. Esto significa que tienes dos PCollections: una que contiene el tiempo de respuesta máximo por destino y otra que contiene el tiempo de respuesta diario promedio por destino.

Carga los datos en BigQuery

El último paso de la canalización produce las PCollections resultantes para BigQuery a fin de realizar el análisis posterior y el almacenamiento de datos.

Primero, la canalización transforma la PCollection que contiene los objetos LogMessage para todas las fuentes del archivo de registro en una PCollection de objetos TableRow de BigQuery. Este paso es necesario para de aprovechar la compatibilidad integrada en Dataflow a fin usar BigQuery como receptor de una canalización.

PCollection<TableRow> logsAsTableRows = allLogMessagesDaily
  .apply("logMessageToTableRow", ParDo.of(new LogMessageTableRowFn()));

Las tablas de BigQuery requieren esquemas definidos. Para esta solución, los esquemas se definen en LogAnalyticsPipelineOptions.java mediante el uso de una anotación de valor predeterminado. Por ejemplo, el esquema para la tabla del tiempo de respuesta máximo se define de la siguiente manera:

@Default.String("destination:STRING,aggResponseTime:FLOAT")

Una operación en las PCollections que contienen los valores de tiempo de respuesta agregados las convierte en PCollections de objetos TableRow, mediante la aplicación de esquemas adecuados y la creación de tablas, si faltan.

logsAsTableRows.apply("allLogsToBigQuery", BigQueryIO.writeTableRows()
  .to(options.getAllLogsTableName())
  .withSchema(allLogsTableSchema)
  .withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_APPEND)
  .withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED));

Esta solución siempre agrega datos nuevos a los datos existentes. Esta es una opción adecuada, ya que la canalización se ejecuta periódicamente para analizar nuevos datos de registro. No obstante, es posible truncar los datos de la tabla existente o solo escribir en la tabla si está vacía, si una de estas opciones tiene más sentido en una situación diferente.

Consulta los datos desde BigQuery

La consola de BigQuery te permite ejecutar consultas en los datos de salida y conectarte a herramientas de inteligencia empresarial de terceros, como Tableau y QlikView para un análisis adicional.

  1. En la consola de Google Cloud, abre BigQuery.

    Abra BigQuery

  2. Haz clic en el proyecto processing-logs-at-scale y, luego, haz clic en el conjunto de datos processing_logs_using_dataflow.

  3. Selecciona all_logs_table, luego en el panel de datos, selecciona Vista previa, para ver una muestra de los datos en la tabla todos los registros.

  4. En el Editor de consultas, ingresa la consulta siguiente:

    SELECT *
    FROM `processing_logs_using_dataflow.max_response_time_table`
    ORDER BY aggResponseTime DESC
    LIMIT 100;
    
  5. Para ejecutar la consulta, haz clic en Ejecutar.

    La consola de BigQuery ejecuta una consulta en los datos de registro.

Usa una canalización de transmisión

La muestra incluye compatibilidad para ejecutar la canalización en el lote o el modo de transmisión. Solo se requieren unos pocos pasos para cambiar la canalización por lote a la de transmisión. En primer lugar, la configuración de Cloud Logging exporta información de registros a Pub/Sub en lugar de a Cloud Storage. El siguiente paso es cambiar las fuentes de entrada en la canalización de Dataflow desde Cloud Storage a suscripciones de temas de Pub/Sub. Necesitas una suscripción por cada fuente de entrada.

La canalización de Pub/Sub usa suscripciones.

Puedes ver los comandos del SDK en uso en logging.sh.

Las PCollections creadas a partir de los datos de entradas de Pub/Sub usan una ventana global ilimitada. Sin embargo, las entradas individuales ya incluyen marcas de tiempo. Esto significa que no es necesario extraer datos de marcas de tiempo del objeto LogEntry de Cloud Logging. En su lugar, extrae las marcas de tiempo del registro para crear los objetos LogMessage personalizados.

Cuando usas la canalización de Pub/Sub, puedes extraer las marcas de tiempo de los registros.

El resto de la canalización se mantiene como está, incluidas las operaciones posteriores de transformación flatten, agregación y salida.

Supervisa la canalización

Cuando ejecutas el trabajo de Dataflow, puedes usar la consola de Google Cloud para supervisar el progreso y ver información sobre cada etapa de la canalización.

En la siguiente imagen, se muestra la consola de Google Cloud mientras se ejecuta una canalización de ejemplo:

La consola de Google Cloud muestra un trabajo de Dataflow en ejecución.

Realice una limpieza

Borra el proyecto

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Borra todos los componentes

Asegúrate de que las variables de entorno sigan configuradas con los valores que usaste durante la configuración

  1. Borra el conjunto de datos de BigQuery:

    bq rm $DATASET_NAME
    
  2. Desactiva las exportaciones ((logging_name)). En este paso, se borran las exportaciones y el bucket de Cloud Storage especificado:

    cd ../services
    ./logging.sh $PROJECT_ID $BUCKET_NAME batch down
    
  3. Borra el clúster de Compute Engine que se usa para ejecutar las aplicaciones web de muestra:

    /cluster.sh $PROJECT_ID $CLUSTER_NAME down
    

Extiende la solución

La canalización y el conjunto de operaciones descritos en esta solución se pueden extender de diversas maneras. La extensión más evidente sería realizar agregaciones adicionales a través de los datos de LogMessage. Por ejemplo, si la sesión o la información del usuario anonimizada se incluyeran en el resultado del registro, podrías crear agregaciones sobre la actividad del usuario. También podrías usar la transformación ApproximateQuantiles para generar una distribución de los tiempos de respuesta.

¿Qué sigue?