{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "43d9cdb9-1ab6-4e4d-b619-f59680254e3c", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Copyright 2023 Google LLC\n", "#\n", "# Licensed under the Apache License, Version 2.0 (the \"License\");\n", "# you may not use this file except in compliance with the License.\n", "# You may obtain a copy of the License at\n", "#\n", "# https://www.apache.org/licenses/LICENSE-2.0\n", "#\n", "# Unless required by applicable law or agreed to in writing, software\n", "# distributed under the License is distributed on an \"AS IS\" BASIS,\n", "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", "# See the License for the specific language governing permissions and\n", "# limitations under the License." ] }, { "cell_type": "markdown", "id": "1b553a81-d772-4f73-8ef9-d50f6e4ff4b3", "metadata": { "tags": [] }, "source": [ "

\n", " \"drawing\" \n", " Dataproc usage analysis\n", "

" ] }, { "cell_type": "markdown", "id": "801e091a-10ac-499d-9237-fd336b509574", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Table of contents\n", "* Overview\n", "* Reference architecture\n", "* Setup\n", "* Imports\n", "* Parameters\n", "* Client and functions\n", "* Run data extraction and preparation\n", "* Explore data\n", "* Visualize in Looker Studio" ] }, { "cell_type": "markdown", "id": "371ed8d6-9d2d-47af-87a0-6f8558175624", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Overview " ] }, { "cell_type": "markdown", "id": "fa475167-86b3-45b4-abdc-1629de214578", "metadata": {}, "source": [ "This notebooks show how to analyse Dataproc usage and billing. It uses the [Dataproc JobController](https://cloud.google.com/python/docs/reference/dataproc/latest/google.cloud.dataproc_v1.services.job_controller.JobControllerClient#google_cloud_dataproc_v1_services_job_controller_JobControllerClient_list_operations) python client to retrieve the service operations of type [dataproc.v1.ClusterOperationMetadata](https://cloud.google.com/python/docs/reference/dataproc/5.16.0/google.cloud.dataproc_v1.types.ClusterOperationMetadata). This operation logs cluster creation and deletion events. It also uses [BigQuery magics](https://cloud.google.com/python/docs/reference/bigquery/latest/magics) and [Bigframes API](https://cloud.google.com/python/docs/reference/bigframes/latest/summary_overview) to query, explore, and plot the data easily.\n", "\n", "In addition, [Cloud Billing data](https://cloud.google.com/billing/docs/how-to/export-data-bigquery) exported in BigQuery is used to provide further insights about the usage cost." ] }, { "cell_type": "markdown", "id": "519a7ddf-8372-4c4b-ae48-b046374d79e5", "metadata": { "tags": [] }, "source": [ "## Reference architecture" ] }, { "cell_type": "markdown", "id": "9e7c8879-e547-4eef-950d-18a722f54e17", "metadata": { "tags": [] }, "source": [ "![dataproc-jobs-architecture.png](../../docs/images/dataproc_cluster_insights_bigquery/dataproc-jobs-architecture.png)" ] }, { "cell_type": "markdown", "id": "bb3f69cd-7fae-49d7-b50d-1808b51619e7", "metadata": { "tags": [] }, "source": [ "## Setup " ] }, { "cell_type": "markdown", "id": "178071c6-aae2-44de-8217-137582515b37", "metadata": {}, "source": [ "Pre-requisites:\n", "* [Setup Cloud Billing export to BigQuery](https://cloud.google.com/billing/docs/how-to/export-data-bigquery)\n", "* [Create a BigQuery dataset named **dataproc_analysis**](https://cloud.google.com/bigquery/docs/datasets#console)\n", "\n", "Make sure the service account running this notebook has:\n", "* [BigQueryDataViewer role](https://cloud.google.com/bigquery/docs/access-control#dataset_level) on the dataset used for Cloud Billing export\n", "* [BigQueryDataEditor role](https://cloud.google.com/bigquery/docs/access-control#dataset_level) on the **dataproc_analysis** dataset\n", "* Dataproc IAM permisions on [operations.list](https://cloud.google.com/dataproc/docs/concepts/iam/iam#operations_methods_required_permissions) and [workflowTemplates.list](https://cloud.google.com/dataproc/docs/concepts/iam/iam#workflow_templates_methods_required_permissions)\n", "\n", "Considerations:\n", "* This code will not retrieve nor ingest data incrementally, but historically. Then it will filter from the specified date.\n", "* Tables will be re-created at each run.\n", "* Code provided as a sample, not ready to production. Review with your organization.\n", "* To protect large customer environments, there is a filter provided to limit the Dataproc client pager to only retrieve 5 pages of data. Remove it carefully after considering the volume of your organization." ] }, { "cell_type": "markdown", "id": "9f4ba4c1-4c4d-4052-b16a-9c11d3776515", "metadata": { "tags": [] }, "source": [ "**Install upgrade dependencies**" ] }, { "cell_type": "code", "execution_count": null, "id": "363aa697-4b9f-49a1-83e3-fc6022b867e3", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "pip install --upgrade google-api-core google-cloud-dataproc bigframes -q" ] }, { "cell_type": "markdown", "id": "c80e7282-68a3-44a8-bada-43bb900d8bf9", "metadata": { "scrolled": true, "tags": [] }, "source": [ "**Make sure to restart Kernel**" ] }, { "cell_type": "markdown", "id": "36f7f7d5-8bf3-4aae-8106-03ae67f60f22", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 4, "id": "2fccea23-bb1d-494a-beff-fa93f9c928de", "metadata": { "tags": [] }, "outputs": [], "source": [ "from google.cloud import dataproc_v1 as dataproc\n", "from google.api_core import client_options\n", "from google.longrunning.operations_pb2 import ListOperationsRequest\n", "from typing import Sequence, Tuple, Union\n", "from google.protobuf.json_format import MessageToJson \n", "import json\n", "import pandas as pd\n", "from google.cloud import bigquery\n", "import time\n", "import bigframes.pandas as bpd" ] }, { "cell_type": "markdown", "id": "0a59f01f-d0ae-49d9-b344-a1703c842f93", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Parameters " ] }, { "cell_type": "markdown", "id": "0f33cb72-7d81-4020-af0c-b60a09e7cce1", "metadata": {}, "source": [ "- Provide your Google Cloud Project ID, region, and information for the Cloud Billing export in BigQuery (Dataset and table name).\n", "\n", "- You can configure the start date from where the data will be presented.\n", "\n", "- DATAPROC_PAGER_LIMIT allows you to limit how many request to the Dataproc API are made to retrieve past Operations. " ] }, { "cell_type": "code", "execution_count": 5, "id": "7fb0e9a8-4db8-4ab0-a6f8-9edf11c44dcc", "metadata": { "tags": [] }, "outputs": [], "source": [ "# Provide your GCP project ID\n", "PROJECT_ID = \"\" \n", "# Provide your GCP region\n", "GCP_REGION = \"us-central1\" \n", "# Provide your Cloud Billing export dataset\n", "BQ_BILLING_DATASET_NAME = \"gcp_billing\" \n", "# Provide your Cloud Billing export table name\n", "BQ_BILLING_TABLE_NAME = \"gcp_billing_export_resource_v1_019CAE_7D7330_15385C\" \n", "\n", "# Set reporting start date \n", "START_DATE = \"2024-03-01\"\n", "\n", "# Limit Dataproc operation list pager\n", "DATAPROC_PAGER_LIMIT = 5" ] }, { "cell_type": "code", "execution_count": 6, "id": "4f477fc4-28a3-4f70-aac2-6100e9175315", "metadata": {}, "outputs": [], "source": [ "# Do not change, unless necesary\n", "BQ_DATASET_NAME = \"dataproc_analysis\"\n", "BQ_TABLE_NAME_RAW = \"operations_raw\"\n", "BQ_TABLE_NAME_CLEAN = \"operations_clean\"\n", "BQ_TABLE_NAME_MODEL = \"operations_model\"\n", "BQ_BILLING_TABLE_VIEW = \"billing_model\"" ] }, { "cell_type": "markdown", "id": "d6a99a1c-7f43-4fe6-9820-16cc0a635c50", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Clients and functions " ] }, { "cell_type": "code", "execution_count": 7, "id": "04544a15-5381-4ac9-a49e-4fbbb2290718", "metadata": { "tags": [] }, "outputs": [], "source": [ "client_options = client_options.ClientOptions(\n", " api_endpoint=f\"{GCP_REGION}-dataproc.googleapis.com:443\"\n", ")\n", "workflow_template_client = dataproc.WorkflowTemplateServiceClient(client_options=client_options)\n", "bq_client = bigquery.Client()" ] }, { "cell_type": "code", "execution_count": 8, "id": "af04229f-b1f1-428d-a1ba-b86dacfc3cbe", "metadata": { "tags": [] }, "outputs": [], "source": [ "def save_to_bq(table_id, df, schema = None):\n", " job_config = bigquery.LoadJobConfig(\n", " write_disposition=\"WRITE_APPEND\",\n", " schema = schema\n", " )\n", "\n", " job = bq_client.load_table_from_dataframe(df, table_id, job_config=job_config) \n", " return job.result()" ] }, { "cell_type": "markdown", "id": "95193af9-e284-497e-9dd2-9a0f027daad2", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Run data extraction and preparation " ] }, { "cell_type": "markdown", "id": "b37e7ad9-8179-4dd7-be8d-d6f51ebaab24", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "#### 1. Prepare BigQuery tables" ] }, { "cell_type": "code", "execution_count": 9, "id": "ce2c19be-5ef0-4d04-be49-76cfea9d6c24", "metadata": { "tags": [] }, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", " CREATE OR REPLACE TABLE {BQ_DATASET_NAME}.{BQ_TABLE_NAME_RAW}\n", " (\n", " clusterUuid STRING,\n", " clusterName STRING,\n", " operationType STRING,\n", " status STRING,\n", " master_instances STRING,\n", " master_machine_type STRING,\n", " worker_instances STRING,\n", " worker_machine_type STRING\n", " );\n", " CREATE OR REPLACE TABLE {BQ_DATASET_NAME}.{BQ_TABLE_NAME_CLEAN}\n", " (\n", " clusterUuid STRING, \n", " clusterName STRING,\n", " operationType STRING,\n", " stateStartTime STRING,\n", " master_instances STRING,\n", " master_machine_type STRING,\n", " worker_instances STRING,\n", " worker_machine_type STRING\n", " );\n", " CREATE OR REPLACE TABLE {BQ_DATASET_NAME}.{BQ_TABLE_NAME_MODEL}\n", " (\n", " clusterUuid STRING, \n", " clusterName STRING,\n", " created TIMESTAMP,\n", " deleted TIMESTAMP,\n", " date DATE,\n", " hour INTEGER,\n", " master_instances STRING,\n", " master_machine_type STRING,\n", " worker_instances STRING,\n", " worker_machine_type STRING,\n", " seconds_elapsed INTEGER,\n", " );\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 10, "id": "4cbf243f-b47f-45a2-a2f5-753b1ee7659c", "metadata": { "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f30e63c48dca4174af46142b74aa04de", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "markdown", "id": "b071e7a2-d779-4274-aed6-2176455ec681", "metadata": { "tags": [] }, "source": [ "#### 2. List workflow templates" ] }, { "cell_type": "code", "execution_count": 11, "id": "8dd84b94-de9d-49bf-aafa-20c4a9cd7507", "metadata": { "tags": [] }, "outputs": [], "source": [ "parent = f\"projects/{PROJECT_ID}/regions/{GCP_REGION}\"\n", "request = dataproc.ListWorkflowTemplatesRequest(parent=parent)" ] }, { "cell_type": "code", "execution_count": 12, "id": "2f0067ef-416f-4dad-96f7-83463783a1ae", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "page_result = workflow_template_client.list_workflow_templates(request=request)" ] }, { "cell_type": "code", "execution_count": 13, "id": "86548456-13b3-41e0-81b3-9fc7a55c148a", "metadata": {}, "outputs": [], "source": [ "workflow_templates = []\n", "\n", "for response in page_result:\n", " workflow_templates.append({\n", " \"name\": response.name,\n", " \"id\": response.id\n", " })" ] }, { "cell_type": "markdown", "id": "aae2a7ee-043d-493c-8542-b6952f8abebf", "metadata": { "tags": [] }, "source": [ "#### 3. Get cluster operations and save them into BigQuery" ] }, { "cell_type": "code", "execution_count": 14, "id": "bfa59c96-60c7-49a1-9ca3-0fc946fd1cb0", "metadata": { "tags": [] }, "outputs": [], "source": [ "def format_ops_data(ops):\n", " cluster_metadata = json.loads(MessageToJson(ops.metadata))\n", " ops = json.loads(MessageToJson(ops))\n", " \n", " response = ops.get(\"response\", None)\n", " config = response.get(\"config\", None) if response is not None else None\n", "\n", " # Master\n", " master_config = config.get(\"masterConfig\", {\"masterConfig\": None}) if config is not None else None\n", " master_num_instances = master_config.get(\"numInstances\", \"\") if master_config is not None else \"\"\n", " master_machineType = master_config.get(\"machineTypeUri\", \"\") if master_config is not None else \"\"\n", " master_mathineType = master_machineType[master_machineType.rindex('/')+1:] if master_machineType != \"\" else \"\"\n", "\n", " # Worker\n", " worker_config = config.get(\"workerConfig\", {\"workerConfig\": None}) if config is not None else None\n", " worker_num_instances = worker_config.get(\"numInstances\", \"\") if worker_config is not None else \"\"\n", " worker_machineType = master_config.get(\"machineTypeUri\", \"\") if worker_config is not None else \"\"\n", " worker_machineType = worker_machineType[worker_machineType.rindex('/')+1:] if worker_machineType != \"\" else \"\"\n", " \n", " return {\n", " \"clusterName\": cluster_metadata[\"clusterName\"], \n", " \"clusterUuid\": cluster_metadata[\"clusterUuid\"], \n", " \"operationType\": cluster_metadata[\"operationType\"], \n", " \"status\": cluster_metadata[\"status\"],\n", " \"master_instances\": str(master_num_instances),\n", " \"master_machine_type\": master_mathineType,\n", " \"worker_instances\": str(worker_num_instances),\n", " \"worker_machine_type\": worker_machineType,\n", " }" ] }, { "cell_type": "code", "execution_count": 15, "id": "032215df-a9f3-4b23-ab5f-a2c97f599833", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "def run_extract(filter_string):\n", " parent = f\"projects/{PROJECT_ID}/regions/{GCP_REGION}/operations\"\n", " operations_count = 0\n", " page_token = \"\"\n", " run_count = 0\n", " while True:\n", " run_count += 1\n", " time.sleep(0.5)\n", " \n", " if run_count > DATAPROC_PAGER_LIMIT:\n", " return operations_count\n", "\n", " operations = []\n", " request = ListOperationsRequest(\n", " name = parent,\n", " page_token = page_token,\n", " filter = filter_string\n", " )\n", " execution_request = workflow_template_client.list_operations(request=request)\n", " for ops in execution_request.operations:\n", " if ops.metadata.type_url == \"type.googleapis.com/google.cloud.dataproc.v1.ClusterOperationMetadata\":\n", " operations_count += 1\n", " cluster_metadata = format_ops_data(ops)\n", " operations.append(cluster_metadata)\n", "\n", " df = pd.DataFrame(operations)\n", " df[\"status\"] = df[\"status\"].apply(json.dumps)\n", " save_to_bq(\n", " table_id = f\"{BQ_DATASET_NAME}.{BQ_TABLE_NAME_RAW}\",\n", " df = df\n", " )\n", "\n", " page_token = execution_request.next_page_token\n", " if page_token == '':\n", " return operations_count" ] }, { "cell_type": "code", "execution_count": 16, "id": "c259c696-a1a1-465b-924e-d42f13c6f8c2", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "operations_count = 0\n", "filter_string = \"operationType=CREATE\"\n", "operations_count += run_extract(filter_string)\n", "\n", "filter_string = \"operationType=DELETE\"\n", "operations_count += run_extract(filter_string)" ] }, { "cell_type": "code", "execution_count": 17, "id": "ea2ad878-7198-4bbf-80a5-fbc55787d88e", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "'86 operations found'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f\"{operations_count} operations found\"" ] }, { "cell_type": "markdown", "id": "9861b3b0-d79d-42cc-980f-87395592a417", "metadata": { "tags": [] }, "source": [ "#### 4. Clean operations" ] }, { "cell_type": "code", "execution_count": 18, "id": "7af22abb-4ded-4e69-8214-b2fd44f2d4a7", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", " INSERT INTO {BQ_DATASET_NAME}.{BQ_TABLE_NAME_CLEAN}\n", " WITH operations_clean AS (\n", " SELECT \n", " clusterUuid\n", " , clusterName\n", " , operationType\n", " , JSON_VALUE(PARSE_JSON(status), '$.stateStartTime') stateStartTime\n", " , master_instances\n", " , master_machine_type\n", " , worker_instances\n", " , worker_machine_type\n", " FROM {BQ_DATASET_NAME}.{BQ_TABLE_NAME_RAW}\n", " WHERE \n", " --JSON_VALUE(PARSE_JSON(status), '$.innerState') = 'DONE'\n", " JSON_VALUE(PARSE_JSON(status), '$.state') = 'DONE'\n", " )\n", " , created AS (\n", " SELECT\n", " *\n", " , RANK() OVER ( PARTITION BY clusterUuid ORDER BY stateStartTime ASC) cluster_group\n", " FROM operations_clean \n", " WHERE \n", " operationType = 'CREATE'\n", " AND DATE(stateStartTime) >= DATE('{START_DATE}')\n", " GROUP BY ALL\n", " ORDER BY stateStartTime\n", " )\n", " , deleted AS (\n", " SELECT\n", " *\n", " , RANK() OVER ( PARTITION BY clusterUuid ORDER BY stateStartTime DESC ) cluster_group\n", " FROM operations_clean \n", " WHERE operationType = 'DELETE' AND clusterUuid IN (SELECT clusterUuid FROM created GROUP BY 1)\n", " GROUP BY ALL\n", " ORDER BY stateStartTime\n", " )\n", " SELECT \n", " * EXCEPT (cluster_group)\n", " FROM created\n", " WHERE cluster_group = 1\n", " UNION ALL\n", " SELECT \n", " * EXCEPT (cluster_group)\n", " FROM deleted\n", " WHERE cluster_group = 1\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 19, "id": "8cfda3cf-3d46-4768-93cd-40816e8c388c", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0a583f4120a54dc982675e3b25149177", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "markdown", "id": "47dad238-ae05-4154-aa96-4a803ae6a1fe", "metadata": { "tags": [] }, "source": [ "#### 5. Model cluster usage" ] }, { "cell_type": "code", "execution_count": 20, "id": "db029f7d-6576-484a-98c2-d03633d9c931", "metadata": {}, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", " INSERT INTO {BQ_DATASET_NAME}.{BQ_TABLE_NAME_MODEL}\n", " WITH cluster_create AS (\n", " SELECT \n", " clusterUuid, clusterName, TIMESTAMP(stateStartTime) stateStartTime,\n", " master_instances, master_machine_type, worker_instances, worker_machine_type\n", " FROM {BQ_DATASET_NAME}.{BQ_TABLE_NAME_CLEAN}\n", " WHERE operationType = 'CREATE'\n", " )\n", " , cluster_delete AS (\n", " SELECT clusterUuid, TIMESTAMP(stateStartTime) stateStartTime\n", " FROM {BQ_DATASET_NAME}.{BQ_TABLE_NAME_CLEAN}\n", " WHERE operationType = 'DELETE'\n", " )\n", " SELECT \n", " cluster_create.clusterUuid\n", " , cluster_create.clusterName\n", " , cluster_create.stateStartTime AS created\n", " , cluster_delete.stateStartTime AS deleted\n", " , extract(DATE from cluster_create.stateStartTime) date\n", " , extract(HOUR from cluster_create.stateStartTime) hour\n", " , master_instances\n", " , master_machine_type\n", " , worker_instances\n", " , worker_machine_type\n", " , TIMESTAMP_DIFF(cluster_delete.stateStartTime, cluster_create.stateStartTime, SECOND) AS seconds_elapsed\n", " FROM cluster_create\n", " LEFT JOIN cluster_delete\n", " USING (clusterUuid)\n", " GROUP BY 1,2,3,4,5,6,7,8,9,10\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 21, "id": "1587a323-d20b-45ee-8e74-66065e767666", "metadata": { "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "be37461944f24afdac7358d33b1b087d", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: []\n", "Index: []" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "markdown", "id": "36bfec24-3e78-4e97-93fe-9c26041bc21c", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "## Explore data " ] }, { "cell_type": "markdown", "id": "08479090-ad5e-413d-8cf3-3b4bb6c478b6", "metadata": {}, "source": [ "#### Total seconds by time" ] }, { "cell_type": "code", "execution_count": 22, "id": "a36d990f-6e2e-4c38-b9d0-e188273433fa", "metadata": { "tags": [] }, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", " SELECT \n", " date\n", " , hour\n", " , concat(date, ' ', hour, ':00') date_hour\n", " , sum(seconds_elapsed) / 60 minutes\n", " FROM {BQ_DATASET_NAME}.{BQ_TABLE_NAME_MODEL}\n", " GROUP BY 1,2,3\n", " ORDER BY 3\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 23, "id": "eb480990-7650-4d1e-aac5-24cd64da20e0", "metadata": { "scrolled": true, "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "30fa65b12cf849ff8fcf0360576246d0", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e3205a4658cd4a0bbf094e852cddf642", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Downloading: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datehourdate_hourminutes
02024-03-2102024-03-21 0:0032.550000
12024-03-21212024-03-21 21:0030.366667
22024-04-22152024-04-22 15:0010.366667
32024-05-29202024-05-29 20:0030.066667
42024-06-04132024-06-04 13:0029.833333
52024-06-18122024-06-18 12:0030.016667
62024-09-03212024-09-03 21:002.433333
72024-11-27142024-11-27 14:0031.216667
82025-02-12172025-02-12 17:004.333333
92025-02-12182025-02-12 18:004.933333
102025-02-24222025-02-24 22:0011.650000
112025-02-24232025-02-24 23:002.983333
122025-02-25122025-02-25 12:002.833333
132025-02-2562025-02-25 6:002.900000
\n", "
" ], "text/plain": [ " date hour date_hour minutes\n", "0 2024-03-21 0 2024-03-21 0:00 32.550000\n", "1 2024-03-21 21 2024-03-21 21:00 30.366667\n", "2 2024-04-22 15 2024-04-22 15:00 10.366667\n", "3 2024-05-29 20 2024-05-29 20:00 30.066667\n", "4 2024-06-04 13 2024-06-04 13:00 29.833333\n", "5 2024-06-18 12 2024-06-18 12:00 30.016667\n", "6 2024-09-03 21 2024-09-03 21:00 2.433333\n", "7 2024-11-27 14 2024-11-27 14:00 31.216667\n", "8 2025-02-12 17 2025-02-12 17:00 4.333333\n", "9 2025-02-12 18 2025-02-12 18:00 4.933333\n", "10 2025-02-24 22 2025-02-24 22:00 11.650000\n", "11 2025-02-24 23 2025-02-24 23:00 2.983333\n", "12 2025-02-25 12 2025-02-25 12:00 2.833333\n", "13 2025-02-25 6 2025-02-25 6:00 2.900000" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "code", "execution_count": 24, "id": "f68e7b20-9e27-44cd-83b6-75a2af621c94", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "Query job fdb5cc9f-ccde-4f03-83c0-bd2eaf594052 is DONE. 0 Bytes processed. Open Job" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "Query job 282c56b2-31b9-48e4-91d2-e57ec3c647be is DONE. 504 Bytes processed. Open Job" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "Query job 8632188a-c966-4731-a02c-e85ba3c3bd98 is DONE. 586 Bytes processed. Open Job" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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SCkWH0RERKQUiw8iIiJSisUHERERKcXig4iIiJS65+Jj69at6NSpE4KDg2EwGPD9999btffr1w8Gg8Hq0b59+6LKS0RERE7unouPzMxM1K5dG3PmzLH5mvbt2+PcuXOWx/Lly+8rJBERET04XO/1L8TExCAmJuaurzGZTAgMDPzHoYiIiOjBZZdzPjZv3oyAgABUqVIFgwcPxqVLl2y+NicnBxkZGVYPIiIienAVefHRvn17LF68GBs3bsTUqVOxZcsWxMTEIC8vr9DXT548Gb6+vpZHSEhIUUciIiIijdzzzy5/pUePHpY/16xZE7Vq1UKlSpWwefNmtG7dusDrx40bh5EjR1qeZ2RksAAhIiJ6gNn9UtuKFSuiVKlSOH78eKHtJpMJPj4+Vg8iIiJ6cNm9+Pj9999x6dIlBAUF2fujiIiIyAnc888u165dszqKkZKSgoSEBPj7+8Pf3x9vvvkmunXrhsDAQCQnJ2PMmDEIDw9Hu3btijQ4EREROad7Lj727t2Lli1bWp7nn6/Rt29fzJs3D/v378cXX3yBK1euIDg4GG3btsVbb70Fk8lUdKmJiIjIad1z8dGiRQuIiM322NjY+wpEREREDzbe24WIiIiUYvFBRERESrH4ICIiIqVYfBAREZFSLD6IiIhIKRYfREREpBSLDyIiIlKKxQcREREpxeKDiIiIlGLxQUREREqx+CAiIiKlWHwQERGRUiw+iIiISCkWH0RERKQUiw8iIiJSisUHERERKcXig4iIiJRi8UFERERKsfggIiIipVh8EBERkVIsPoiIiEgpFh9ERESkFIsPIiIiUorFBxERESnF4oOIiIiUYvFBRERESrH4ICIiIqVYfBAREZFSLD6IiIhIKVdHB6CiV37smiJ5n9QpHYrkfYiIiG7HIx9ERESkFIsPIiIiUorFBxERESnF4oOIiIiUYvFBRERESrH4ICIiIqVYfBAREZFSLD6IiIhIKRYfREREpBSLDyIiIlKKxQcREREpxeKDiIiIlGLxQURERErd811tt27dimnTpiE+Ph7nzp3Dd999hy5duljaRQQTJkzA/PnzceXKFTRp0gTz5s1D5cqVizI3ERGRtnh38bu75yMfmZmZqF27NubMmVNo+3vvvYdZs2bh448/xu7du1GsWDG0a9cO2dnZ9x2WiIiInN89H/mIiYlBTExMoW0ighkzZuD1119H586dAQCLFy9GmTJl8P3336NHjx73l5aIiIicXpGe85GSkoK0tDRER0dblvn6+qJRo0bYuXNnoX8nJycHGRkZVg8iIiJ6cBVp8ZGWlgYAKFOmjNXyMmXKWNruNHnyZPj6+loeISEhRRmJiIiINOPwq13GjRuH9PR0y+P06dOOjkRERER2VKTFR2BgIADg/PnzVsvPnz9vabuTyWSCj4+P1YOIiIgeXEVafFSoUAGBgYHYuHGjZVlGRgZ2796NyMjIovwoIiIiclL3fLXLtWvXcPz4ccvzlJQUJCQkwN/fH6GhoRg+fDjefvttVK5cGRUqVMAbb7yB4OBgq7lAiIiI6OF1z8XH3r170bJlS8vzkSNHAgD69u2Lzz//HGPGjEFmZiYGDhyIK1euoGnTpli3bh08PDyKLjURERE5rXsuPlq0aAERsdluMBgwadIkTJo06b6CERER0YPJ4Ve7EBER0cOFxQcREREpxeKDiIiIlGLxQUREREqx+CAiIiKlWHwQERGRUiw+iIiISCkWH0RERKQUiw8iIiJSisUHERERKcXig4iIiJRi8UFERERKsfggIiIipVh8EBERkVIsPoiIiEgpFh9ERESkFIsPIiIiUorFBxERESnF4oOIiIiUYvFBRERESrH4ICIiIqVYfBAREZFSLD6IiIhIKRYfREREpBSLDyIiIlKKxQcREREpxeKDiIiIlGLxQUREREqx+CAiIiKlWHwQERGRUiw+iIiISCkWH0RERKQUiw8iIiJSisUHERERKcXig4iIiJRi8UFERERKsfggIiIipVh8EBERkVIsPoiIiEgpFh9ERESkFIsPIiIiUorFBxERESnF4oOIiIiUKvLiY+LEiTAYDFaPqlWrFvXHEBERkZNytcebVq9eHT/99NP/fYirXT6GiIiInJBdqgJXV1cEBgba462JiIjIydnlnI9jx44hODgYFStWxNNPP41Tp07ZfG1OTg4yMjKsHkRERPTgKvLio1GjRvj888+xbt06zJs3DykpKXjsscdw9erVQl8/efJk+Pr6Wh4hISFFHYmIiIg0UuQ/u8TExFj+XKtWLTRq1AhhYWH45ptvMGDAgAKvHzduHEaOHGl5npGRwQKEHgrlx64pkvdJndKhSN6HiEgVu58J6ufnh0ceeQTHjx8vtN1kMsFkMtk7BhEREWnC7vN8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E2+99RYSExPx/fffIzU11VJghISE4NtvvwUAHDlyBOfOncPMmTMB3JoxdvHixfj4449x8OBBjBgxAr1798aWLVv+drbXXnsNH3zwAfbu3QtXV1c8++yzlrbvvvsO//nPf/Dyyy/jwIEDeOGFF9C/f3/ExcXdcx+MHTsWU6ZMwaFDh1CrVq17/vtEVATsPoE7EWnh6tWr4u7uLt98841l2aVLl8TT01P+85//FPp3fvnlFwEgV69eFRGRuLg4ASB//vmn5TXZ2dni5eUlO3bssPq7AwYMkJ49e/5lrvz3/OmnnyzL1qxZIwDk+vXrIiISFRUlzz//vNXf+/e//y2PP/64iIikpKQIAPn1118t7X/++acAkLi4OKvP+f777/8yExHZF498ED0kkpOTcePGDTRq1MiyzN/fH1WqVLE8j4+PR6dOnRAaGgpvb280b94cAHDq1Cmb73v8+HFkZWWhTZs2KF68uOWxePFiJCcn/+18tx+FCAoKAgDLTz6HDh1CkyZNrF7fpEkTHDp06G+/f7769evf898hoqLl+tcvIaKHQWZmJtq1a4d27dph6dKlKF26NE6dOoV27drhxo0bNv/etWvXAABr1qxB2bJlrdpMJtPf/nw3NzfLnw0GAwD87Rv7GY23/h8lt92q6ubNm4W+tlixYn87ExHZB498ED0kKlWqBDc3N+zevduy7M8//8TRo0cBAIcPH8alS5cwZcoUPPbYY6hatarlyEM+d3d3AEBeXp5lWbVq1WAymXDq1CmEh4dbPUJCQooke0REBLZv3261bPv27ahWrRoAoHTp0gCAc+fOWdpvP/mUiPTCIx9ED4nixYtjwIABGD16NEqWLImAgAC89tprlqMGoaGhcHd3x0cffYRBgwbhwIEDeOutt6zeIywsDAaDAatXr8bjjz8OT09PeHt7Y9SoURgxYgTMZjOaNm2K9PR0bN++HT4+Pujbt+99Zx89ejS6d++ORx99FNHR0Vi1ahVWrlyJn376CQDg6emJxo0bY8qUKahQoQIuXLiA119//b4/l4jsxNEnnRCROlevXpXevXuLl5eXlClTRt577z1p3ry55YTTZcuWSfny5cVkMklkZKT8+OOPBU7knDRpkgQGBorBYJC+ffuKiIjZbJYZM2ZIlSpVxM3NTUqXLi3t2rWTLVu2/GWmwk5i/fXXXwWApKSkWJbNnTtXKlasKG5ubvLII4/I4sWLrd4nKSlJIiMjxdPTU+rUqSPr168v9ITT2z+HiBzDIHLbj6REREREdsZzPoiIiEgpFh9EZFeDBg2yugT39segQYMcHY+IHIA/uxCRXV24cAEZGRmFtvn4+CAgIEBxIiJyNBYfREREpBR/diEiIiKlWHwQERGRUiw+iIiISCkWH0RERKQUiw8iIiJSisUHERERKcXig4iIiJRi8UFERERK/T/IR6mVoSHw6AAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df = bpd.read_gbq(SQL_QUERY)\n", "df[[\"date_hour\", \"minutes\"]].plot.bar(x=\"date_hour\", y=\"minutes\")" ] }, { "cell_type": "markdown", "id": "205039f3-6b1b-4557-b1c6-c6866d050534", "metadata": {}, "source": [ "#### Cluster details" ] }, { "cell_type": "code", "execution_count": 25, "id": "406d1a6e-03ca-42a0-9875-c0a2f3f0a7b2", "metadata": { "tags": [] }, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", "SELECT \n", " date\n", " , hour\n", " , clusterUuid\n", " , clusterName\n", " , seconds_elapsed / 60 minutes\n", "FROM {BQ_DATASET_NAME}.{BQ_TABLE_NAME_MODEL}\n", "ORDER BY 1,2,3\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 26, "id": "431174f9-1278-49ed-b7e3-14b65507e529", "metadata": { "scrolled": true, "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "39168d8de1b3467f820309f647955ea0", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d55e98de90444ddc8eb74adeca1adf99", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Downloading: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datehourclusterUuidclusterNameminutes
02024-03-2107c7f0f34-76e5-422b-9b10-27c319dea982srvls-session-7ae4c720-8e54-477e-b33b-a9cecc62...2.383333
12024-03-210f177a280-8efc-42fe-885d-edc8ff76f64csrvls-session-0b40ab36-883c-4ec1-93f5-43efb647...30.166667
22024-03-2121199a2ebc-e287-40a8-a7e6-701042cd6663srvls-session-8f4207ee-921a-4593-86b5-ead3d406...30.366667
32024-04-221508273726-b69e-488a-a813-c0e287b9bf0bsrvls-session-d6c9fdd2-b4d5-49ad-9853-fd283347...10.366667
42024-05-2920fc36f463-6de5-4f4d-972a-7e7a0cccdaa0srvls-session-d9f26ba6-6140-47f6-9f6d-c3c17da5...30.066667
52024-06-0413ecd1fe28-354f-4eea-863e-745b02462c85srvls-session-ccc4f4ef-de25-4aaf-aa07-1442776b...29.833333
62024-06-1812fbaac46a-e25c-454b-8617-261ec75a4c07srvls-session-ad7438cc-23a6-41c0-9dc1-b116f8a8...30.016667
72024-09-0321b7dc43ed-9556-462f-b1f4-540c080a678csrvls-session-5153a351-3d2f-4f8f-861f-339a24f1...2.433333
82024-11-271444ae9df0-467d-4cc8-9b37-ef8a5dabbfa0srvls-session-58fe92c0-55f3-4bea-91aa-a05852a4...31.216667
92025-02-121768aac871-dac9-4534-9dba-b3b94adb4925cluster-f6ef-ktklml7lgv4wa2.783333
102025-02-121789d41015-4d24-4df6-b107-93dc80789a43cluster-f6ef-ze7qchjeqbgpi1.550000
112025-02-121805804ce3-9436-4ad5-b06e-03ec40136fc7cluster-f6ef-ftpjdixscxjea2.766667
122025-02-1218e78bddb9-ca43-4c1b-96cf-b9427c35f1b8cluster-f6ef-r4alnh7zqdhtm2.166667
132025-02-242221bf1220-045c-49a9-a4ce-d60964469993cluster-f6ef-lsde6ofzsmtu62.816667
142025-02-24225054321f-c443-4772-8d22-9dee9316a14fcluster-1605-zl3r44m2mf7qy2.800000
152025-02-24227ddf6d6c-11a0-4415-8743-f6784b0e7b30cluster-f6ef-kus5iy4fdbtji1.533333
162025-02-2422d2493f89-43a1-446c-9f1e-e25900048718cluster-b015-47cnzyiaswp2w2.883333
172025-02-2422eab86372-1fbe-4bb9-9328-3e346aa987dfcluster-f6ef-litog7w7m245o1.616667
182025-02-24233360ed2a-888b-42c4-9965-f61f993c6106cluster-0f90-4unxcy2ydejwg2.983333
192025-02-2567e21b393-61c3-4b89-a5ef-168e7c555528cluster-26fc-jzicbl3sson3k2.900000
202025-02-251234658e4a-bcec-472f-bd56-5aaabba58895cluster-26fc-2hphnbrwz37s62.833333
\n", "
" ], "text/plain": [ " date hour clusterUuid \\\n", "0 2024-03-21 0 7c7f0f34-76e5-422b-9b10-27c319dea982 \n", "1 2024-03-21 0 f177a280-8efc-42fe-885d-edc8ff76f64c \n", "2 2024-03-21 21 199a2ebc-e287-40a8-a7e6-701042cd6663 \n", "3 2024-04-22 15 08273726-b69e-488a-a813-c0e287b9bf0b \n", "4 2024-05-29 20 fc36f463-6de5-4f4d-972a-7e7a0cccdaa0 \n", "5 2024-06-04 13 ecd1fe28-354f-4eea-863e-745b02462c85 \n", "6 2024-06-18 12 fbaac46a-e25c-454b-8617-261ec75a4c07 \n", "7 2024-09-03 21 b7dc43ed-9556-462f-b1f4-540c080a678c \n", "8 2024-11-27 14 44ae9df0-467d-4cc8-9b37-ef8a5dabbfa0 \n", "9 2025-02-12 17 68aac871-dac9-4534-9dba-b3b94adb4925 \n", "10 2025-02-12 17 89d41015-4d24-4df6-b107-93dc80789a43 \n", "11 2025-02-12 18 05804ce3-9436-4ad5-b06e-03ec40136fc7 \n", "12 2025-02-12 18 e78bddb9-ca43-4c1b-96cf-b9427c35f1b8 \n", "13 2025-02-24 22 21bf1220-045c-49a9-a4ce-d60964469993 \n", "14 2025-02-24 22 5054321f-c443-4772-8d22-9dee9316a14f \n", "15 2025-02-24 22 7ddf6d6c-11a0-4415-8743-f6784b0e7b30 \n", "16 2025-02-24 22 d2493f89-43a1-446c-9f1e-e25900048718 \n", "17 2025-02-24 22 eab86372-1fbe-4bb9-9328-3e346aa987df \n", "18 2025-02-24 23 3360ed2a-888b-42c4-9965-f61f993c6106 \n", "19 2025-02-25 6 7e21b393-61c3-4b89-a5ef-168e7c555528 \n", "20 2025-02-25 12 34658e4a-bcec-472f-bd56-5aaabba58895 \n", "\n", " clusterName minutes \n", "0 srvls-session-7ae4c720-8e54-477e-b33b-a9cecc62... 2.383333 \n", "1 srvls-session-0b40ab36-883c-4ec1-93f5-43efb647... 30.166667 \n", "2 srvls-session-8f4207ee-921a-4593-86b5-ead3d406... 30.366667 \n", "3 srvls-session-d6c9fdd2-b4d5-49ad-9853-fd283347... 10.366667 \n", "4 srvls-session-d9f26ba6-6140-47f6-9f6d-c3c17da5... 30.066667 \n", "5 srvls-session-ccc4f4ef-de25-4aaf-aa07-1442776b... 29.833333 \n", "6 srvls-session-ad7438cc-23a6-41c0-9dc1-b116f8a8... 30.016667 \n", "7 srvls-session-5153a351-3d2f-4f8f-861f-339a24f1... 2.433333 \n", "8 srvls-session-58fe92c0-55f3-4bea-91aa-a05852a4... 31.216667 \n", "9 cluster-f6ef-ktklml7lgv4wa 2.783333 \n", "10 cluster-f6ef-ze7qchjeqbgpi 1.550000 \n", "11 cluster-f6ef-ftpjdixscxjea 2.766667 \n", "12 cluster-f6ef-r4alnh7zqdhtm 2.166667 \n", "13 cluster-f6ef-lsde6ofzsmtu6 2.816667 \n", "14 cluster-1605-zl3r44m2mf7qy 2.800000 \n", "15 cluster-f6ef-kus5iy4fdbtji 1.533333 \n", "16 cluster-b015-47cnzyiaswp2w 2.883333 \n", "17 cluster-f6ef-litog7w7m245o 1.616667 \n", "18 cluster-0f90-4unxcy2ydejwg 2.983333 \n", "19 cluster-26fc-jzicbl3sson3k 2.900000 \n", "20 cluster-26fc-2hphnbrwz37s6 2.833333 " ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "markdown", "id": "9da1381a-a5f7-442d-9afd-6795c8b9188f", "metadata": { "tags": [] }, "source": [ "#### Total price by the hour" ] }, { "cell_type": "code", "execution_count": 27, "id": "c0a93faa-3751-448b-9ba4-2b5aa9d96ff0", "metadata": { "tags": [] }, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", " SELECT \n", " CONCAT(\n", " EXTRACT (DATE FROM usage_start_time),\n", " ' ',\n", " EXTRACT (HOUR FROM usage_start_time),\n", " ' :00'\n", " ) date_hour,\n", " sku.id sku_id, \n", " price.effective_price / price.pricing_unit_quantity effective_price,\n", " SUM(usage.amount_in_pricing_units) amount_in_pricing_units, \n", " SUM(usage.amount_in_pricing_units * price.effective_price / price.pricing_unit_quantity) total_price\n", " FROM {BQ_BILLING_DATASET_NAME}.{BQ_BILLING_TABLE_NAME}\n", " WHERE \n", " service.description = 'Dataproc' \n", " AND sku.description LIKE 'Data Compute Unit (milli) Hours%'\n", " AND DATE(usage_start_time) >= DATE('{START_DATE}')\n", " GROUP BY 1,2,3\n", " ORDER BY 1\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 28, "id": "7ab1f56c-f73f-4356-9a65-93bed4a024c1", "metadata": { "scrolled": true, "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7d4f53b6b8a9470d97f10264495946be", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d3f7e2e46fa846d7aa63eb0d1cc8c4ff", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Downloading: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
date_hoursku_ideffective_priceamount_in_pricing_unitstotal_price
02024-03-21 0 :00A486-6040-07FE0.00008900011721.5733331.043220
12024-03-21 21 :00A486-6040-07FE0.00008900022043.2986111.961854
22024-03-23 0 :00A065-18C2-08FA0.00010023210963.9386111.098937
32024-03-23 1 :00A065-18C2-08FA0.00010023211849.9991671.187749
42024-03-23 10 :00A065-18C2-08FA0.00010023211850.0000001.187749
52024-03-23 11 :00A065-18C2-08FA0.00010023211850.0000001.187749
62024-03-23 12 :00A065-18C2-08FA0.00010023211850.0000001.187749
72024-03-23 13 :00A065-18C2-08FA0.00010023211850.0000001.187749
82024-03-23 14 :00A065-18C2-08FA0.00010023211850.0000001.187749
92024-03-23 15 :00A065-18C2-08FA0.00010023211850.0000001.187749
102024-03-23 16 :00A065-18C2-08FA0.00010023211850.0000001.187749
112024-03-23 17 :00A065-18C2-08FA0.00010023211850.0000001.187749
122024-03-23 18 :00A065-18C2-08FA0.00010023211850.0000001.187749
132024-03-23 19 :00A065-18C2-08FA0.00010023211850.0000001.187749
142024-03-23 2 :00A065-18C2-08FA0.00010023211850.0000001.187749
152024-03-23 20 :00A065-18C2-08FA0.00010023211850.0000001.187749
162024-03-23 21 :00A065-18C2-08FA0.00010023211850.0000001.187749
172024-03-23 22 :00A065-18C2-08FA0.00010023211850.0000001.187749
182024-03-23 23 :00A065-18C2-08FA0.00010023211850.0000001.187749
192024-03-23 3 :00A065-18C2-08FA0.00010023211850.0000001.187749
202024-03-23 4 :00A065-18C2-08FA0.00010023211850.0000001.187749
212024-03-23 5 :00A065-18C2-08FA0.00010023211850.0000001.187749
222024-03-23 6 :00A065-18C2-08FA0.00010023211850.0000001.187749
232024-03-23 7 :00A065-18C2-08FA0.00010023211850.0000001.187749
242024-03-23 8 :00A065-18C2-08FA0.00010023211850.0000001.187749
252024-03-23 9 :00A065-18C2-08FA0.00010023211850.0000001.187749
262024-03-24 0 :00A065-18C2-08FA0.0001002322229.2688890.223444
272024-04-22 15 :00A065-18C2-08FA0.0001002322910.3102780.291706
282024-04-22 15 :00A486-6040-07FE0.0000890003556.2347220.316505
292024-04-22 16 :00A065-18C2-08FA0.0001002322979.9602780.298687
302024-04-22 16 :00A486-6040-07FE0.0000890001058.4238890.094200
312024-05-29 20 :00A486-6040-07FE0.00008900021327.5338891.898151
322024-06-04 13 :00A486-6040-07FE0.0000890001936.0508330.172309
332024-06-04 14 :00A486-6040-07FE0.0000890006321.6805560.562630
342024-06-18 12 :00A486-6040-07FE0.00008900013069.6994441.163203
352024-11-27 14 :00A486-6040-07FE0.00008900021816.6319441.941680
362025-02-12 17 :00EC7A-EF05-537E0.000060000607.3669440.036442
372025-02-12 18 :00EC7A-EF05-537E0.000060000594.9352780.035696
\n", "
" ], "text/plain": [ " date_hour sku_id effective_price \\\n", "0 2024-03-21 0 :00 A486-6040-07FE 0.000089000 \n", "1 2024-03-21 21 :00 A486-6040-07FE 0.000089000 \n", "2 2024-03-23 0 :00 A065-18C2-08FA 0.000100232 \n", "3 2024-03-23 1 :00 A065-18C2-08FA 0.000100232 \n", "4 2024-03-23 10 :00 A065-18C2-08FA 0.000100232 \n", "5 2024-03-23 11 :00 A065-18C2-08FA 0.000100232 \n", "6 2024-03-23 12 :00 A065-18C2-08FA 0.000100232 \n", "7 2024-03-23 13 :00 A065-18C2-08FA 0.000100232 \n", "8 2024-03-23 14 :00 A065-18C2-08FA 0.000100232 \n", "9 2024-03-23 15 :00 A065-18C2-08FA 0.000100232 \n", "10 2024-03-23 16 :00 A065-18C2-08FA 0.000100232 \n", "11 2024-03-23 17 :00 A065-18C2-08FA 0.000100232 \n", "12 2024-03-23 18 :00 A065-18C2-08FA 0.000100232 \n", "13 2024-03-23 19 :00 A065-18C2-08FA 0.000100232 \n", "14 2024-03-23 2 :00 A065-18C2-08FA 0.000100232 \n", "15 2024-03-23 20 :00 A065-18C2-08FA 0.000100232 \n", "16 2024-03-23 21 :00 A065-18C2-08FA 0.000100232 \n", "17 2024-03-23 22 :00 A065-18C2-08FA 0.000100232 \n", "18 2024-03-23 23 :00 A065-18C2-08FA 0.000100232 \n", "19 2024-03-23 3 :00 A065-18C2-08FA 0.000100232 \n", "20 2024-03-23 4 :00 A065-18C2-08FA 0.000100232 \n", "21 2024-03-23 5 :00 A065-18C2-08FA 0.000100232 \n", "22 2024-03-23 6 :00 A065-18C2-08FA 0.000100232 \n", "23 2024-03-23 7 :00 A065-18C2-08FA 0.000100232 \n", "24 2024-03-23 8 :00 A065-18C2-08FA 0.000100232 \n", "25 2024-03-23 9 :00 A065-18C2-08FA 0.000100232 \n", "26 2024-03-24 0 :00 A065-18C2-08FA 0.000100232 \n", "27 2024-04-22 15 :00 A065-18C2-08FA 0.000100232 \n", "28 2024-04-22 15 :00 A486-6040-07FE 0.000089000 \n", "29 2024-04-22 16 :00 A065-18C2-08FA 0.000100232 \n", "30 2024-04-22 16 :00 A486-6040-07FE 0.000089000 \n", "31 2024-05-29 20 :00 A486-6040-07FE 0.000089000 \n", "32 2024-06-04 13 :00 A486-6040-07FE 0.000089000 \n", "33 2024-06-04 14 :00 A486-6040-07FE 0.000089000 \n", "34 2024-06-18 12 :00 A486-6040-07FE 0.000089000 \n", "35 2024-11-27 14 :00 A486-6040-07FE 0.000089000 \n", "36 2025-02-12 17 :00 EC7A-EF05-537E 0.000060000 \n", "37 2025-02-12 18 :00 EC7A-EF05-537E 0.000060000 \n", "\n", " amount_in_pricing_units total_price \n", "0 11721.573333 1.043220 \n", "1 22043.298611 1.961854 \n", "2 10963.938611 1.098937 \n", "3 11849.999167 1.187749 \n", "4 11850.000000 1.187749 \n", "5 11850.000000 1.187749 \n", "6 11850.000000 1.187749 \n", "7 11850.000000 1.187749 \n", "8 11850.000000 1.187749 \n", "9 11850.000000 1.187749 \n", "10 11850.000000 1.187749 \n", "11 11850.000000 1.187749 \n", "12 11850.000000 1.187749 \n", "13 11850.000000 1.187749 \n", "14 11850.000000 1.187749 \n", "15 11850.000000 1.187749 \n", "16 11850.000000 1.187749 \n", "17 11850.000000 1.187749 \n", "18 11850.000000 1.187749 \n", "19 11850.000000 1.187749 \n", "20 11850.000000 1.187749 \n", "21 11850.000000 1.187749 \n", "22 11850.000000 1.187749 \n", "23 11850.000000 1.187749 \n", "24 11850.000000 1.187749 \n", "25 11850.000000 1.187749 \n", "26 2229.268889 0.223444 \n", "27 2910.310278 0.291706 \n", "28 3556.234722 0.316505 \n", "29 2979.960278 0.298687 \n", "30 1058.423889 0.094200 \n", "31 21327.533889 1.898151 \n", "32 1936.050833 0.172309 \n", "33 6321.680556 0.562630 \n", "34 13069.699444 1.163203 \n", "35 21816.631944 1.941680 \n", "36 607.366944 0.036442 \n", "37 594.935278 0.035696 " ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "code", "execution_count": 29, "id": "5a774c45-d631-4d4c-8a95-612001861af7", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "Query job c8816107-06b2-4d99-bbcb-0abfe3f7db9f is DONE. 2.4 kB processed. Open Job" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "Query job 66ca8e85-faf1-4ee7-8943-2f72812f0460 is DONE. 2.5 kB processed. Open Job" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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GDNmDFJTUxEREYH4+HirD+ISERHR/ckkIlLaQRRVRkYGfHx8kJ6eDm9v79IO574TOnJlnvtOTupoYCREpANeE/SX13Nk9PNjz99v/pYQERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERaY8FCxEREWmPBQsRERFpjwULERERac/ugmXDhg3o1KkTgoKCYDKZsHz58nyPX7ZsGR577DFUrlwZ3t7eiIqKwpo1ayyOGTduHEwmk8Wtdu3a9oZGREREDsrugiUzMxMNGzbEjBkzCnX8hg0b8Nhjj2HVqlXYuXMn2rZti06dOmH37t0Wxz344INISUkx3zZu3GhvaEREROSgXOxt0KFDB3To0KHQx0+bNs3i/oQJE7BixQr8+OOPaNSo0f8F4uKCgIAAe8MhIiKi+4Dhn2HJycnBlStX4Ovra7H96NGjCAoKQrVq1fDss88iOTk5z8e4ceMGMjIyLG5ERETkuAwvWD788ENcvXoV3bp1M2+LjIzEggULEB8fj1mzZiEpKQktW7bElStXbD7GxIkT4ePjY74FBwcbFT4RERGVAkMLlsWLF+Ptt9/Gt99+Cz8/P/P2Dh06oGvXrmjQoAFiY2OxatUqXL58Gd9++63Nxxk1ahTS09PNt9OnTxs1BCIiIioFdn+GRdWSJUvQr18/fPfdd4iJicn32PLly6NmzZo4duyYzf3u7u5wd3cviTCJiIhIQ4a8wvLNN9+gT58++Oabb9CxY8cCj7969SqOHz+OwMBAA6IjIiIi3dn9CsvVq1ctXvlISkrCnj174Ovri6pVq2LUqFE4c+YMFi5cCOD220C9evXC9OnTERkZidTUVACAp6cnfHx8AADDhg1Dp06dEBISgrNnz2Ls2LFwdnZGz549i2OMREREdI+z+xWWHTt2oFGjRuavJA8dOhSNGjXCmDFjAAApKSkW3/D5/PPPcevWLQwePBiBgYHm28svv2w+5s8//0TPnj1Rq1YtdOvWDRUrVsTWrVtRuXLloo6PiIiIHIDdr7C0adMGIpLn/gULFljcT0xMLPAxlyxZYm8YREREdB/hbwkRERGR9liwEBERkfZYsBAREZH2WLAQERGR9gxbOO5eEDpypc3tJyflvXaMzm1U5NVPcfdlVD8qVGLTuU1+7XRoo4L9FG8/JdGXvXQ+h3TOm5FK+5rAV1iIiIhIeyxYiIiISHssWIiIiEh7/AwLERHliZ/fIF3wFRYiIiLSHgsWIiIi0h4LFiIiItIeCxYiIiLSHgsWIiIi0h4LFiIiItIeCxYiIiLSHgsWIiIi0h4LFiIiItIeCxYiIiLSHgsWIiIi0h5/S8iB8TdAiIjIUfAVFiIiItIeCxYiIiLSHgsWIiIi0h4LFiIiItIeCxYiIiLSHgsWIiIi0h4LFiIiItIeCxYiIiLSHgsWIiIi0h5XuiWHxtV+iYgcA19hISIiIu2xYCEiIiLtsWAhIiIi7dldsGzYsAGdOnVCUFAQTCYTli9fXmCbxMREPPTQQ3B3d0d4eDgWLFhgdcyMGTMQGhoKDw8PREZGYvv27faGRkRERA7K7oIlMzMTDRs2xIwZMwp1fFJSEjp27Ii2bdtiz549eOWVV9CvXz+sWbPGfMzSpUsxdOhQjB07Frt27ULDhg0RGxuLv/76y97wiIiIyAHZ/S2hDh06oEOHDoU+fvbs2QgLC8NHH30EAKhTpw42btyIqVOnIjY2FgAwZcoU9O/fH3369DG3WblyJebNm4eRI0faGyIRERE5mBL/DMuWLVsQExNjsS02NhZbtmwBAGRlZWHnzp0Wxzg5OSEmJsZ8zN1u3LiBjIwMixsRERE5rhIvWFJTU+Hv72+xzd/fHxkZGbh27RrOnz+P7Oxsm8ekpqbafMyJEyfCx8fHfAsODi6x+ImIiKj03ZPfEho1ahTS09PNt9OnT5d2SERERFSCSnyl24CAAKSlpVlsS0tLg7e3Nzw9PeHs7AxnZ2ebxwQEBNh8THd3d7i7u5dYzERERKSXEn+FJSoqCgkJCRbbfvnlF0RFRQEA3Nzc0LhxY4tjcnJykJCQYD6GiIiI7m92FyxXr17Fnj17sGfPHgC3v7a8Z88eJCcnA7j9dk1cXJz5+IEDB+LEiRMYMWIEDh8+jJkzZ+Lbb7/Fq6++aj5m6NChmDNnDr788kscOnQIgwYNQmZmpvlbQ0RERHR/s/stoR07dqBt27bm+0OHDgUA9OrVCwsWLEBKSoq5eAGAsLAwrFy5Eq+++iqmT5+OKlWq4IsvvjB/pRkAunfvjnPnzmHMmDFITU1FREQE4uPjrT6IS0RERPcnuwuWNm3aQETy3G9rFds2bdpg9+7d+T7ukCFDMGTIEHvDISIiovvAPfktISIiIrq/sGAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtsWAhIiIi7bFgISIiIu2xYCEiIiLtKRUsM2bMQGhoKDw8PBAZGYnt27fneWybNm1gMpmsbh07djQf07t3b6v97du3VwmNiIiIHJCLvQ2WLl2KoUOHYvbs2YiMjMS0adMQGxuLI0eOwM/Pz+r4ZcuWISsry3z/woULaNiwIbp27WpxXPv27TF//nzzfXd3d3tDIyIiIgdld8EyZcoU9O/fH3369AEAzJ49GytXrsS8efMwcuRIq+N9fX0t7i9ZsgReXl5WBYu7uzsCAgIKFcONGzdw48YN8/2MjAx7h0FERET3ELveEsrKysLOnTsRExPzfw/g5ISYmBhs2bKlUI8xd+5c9OjRA2XKlLHYnpiYCD8/P9SqVQuDBg3ChQsX8nyMiRMnwsfHx3wLDg62ZxhERER0j7GrYDl//jyys7Ph7+9vsd3f3x+pqakFtt++fTt+//139OvXz2J7+/btsXDhQiQkJGDy5MlYv349OnTogOzsbJuPM2rUKKSnp5tvp0+ftmcYREREdI+x+y2hopg7dy7q16+PZs2aWWzv0aOH+f/r16+PBg0aoHr16khMTMSjjz5q9Tju7u78jAsREdF9xK5XWCpVqgRnZ2ekpaVZbE9LSyvw8yeZmZlYsmQJ+vbtW2A/1apVQ6VKlXDs2DF7wiMiIiIHZVfB4ubmhsaNGyMhIcG8LScnBwkJCYiKisq37XfffYcbN27gueeeK7CfP//8ExcuXEBgYKA94REREZGDsnsdlqFDh2LOnDn48ssvcejQIQwaNAiZmZnmbw3FxcVh1KhRVu3mzp2LLl26oGLFihbbr169iuHDh2Pr1q04efIkEhIS0LlzZ4SHhyM2NlZxWERERORI7P4MS/fu3XHu3DmMGTMGqampiIiIQHx8vPmDuMnJyXBysqyDjhw5go0bN+Lnn3+2ejxnZ2fs27cPX375JS5fvoygoCC0a9cO48eP5+dUiIiICIDih26HDBmCIUOG2NyXmJhota1WrVoQEZvHe3p6Ys2aNSphEBER0X2CvyVERERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpjwUJERETaY8FCRERE2mPBQkRERNpzKe0AiIiICAgduTLPfScndTQwEj3xFRYiIiLSHgsWIiIi0h4LFiIiItIeCxYiIiLSHgsWIiIi0h4LFiIiItKeUsEyY8YMhIaGwsPDA5GRkdi+fXuexy5YsAAmk8ni5uHhYXGMiGDMmDEIDAyEp6cnYmJicPToUZXQiIiIyAHZXbAsXboUQ4cOxdixY7Fr1y40bNgQsbGx+Ouvv/Js4+3tjZSUFPPt1KlTFvvff/99fPzxx5g9eza2bduGMmXKIDY2FtevX7d/RERERORw7C5YpkyZgv79+6NPnz6oW7cuZs+eDS8vL8ybNy/PNiaTCQEBAeabv7+/eZ+IYNq0aXjrrbfQuXNnNGjQAAsXLsTZs2exfPlypUERERGRY7GrYMnKysLOnTsRExPzfw/g5ISYmBhs2bIlz3ZXr15FSEgIgoOD0blzZxw4cMC8LykpCampqRaP6ePjg8jIyDwf88aNG8jIyLC4ERERkeOyq2A5f/48srOzLV4hAQB/f3+kpqbabFOrVi3MmzcPK1aswFdffYWcnBxER0fjzz//BABzO3sec+LEifDx8THfgoOD7RkGERER3WNK/FtCUVFRiIuLQ0REBFq3bo1ly5ahcuXK+Oyzz5Qfc9SoUUhPTzffTp8+XYwRExERkW7sKlgqVaoEZ2dnpKWlWWxPS0tDQEBAoR7D1dUVjRo1wrFjxwDA3M6ex3R3d4e3t7fFjYiIiByXXQWLm5sbGjdujISEBPO2nJwcJCQkICoqqlCPkZ2djf379yMwMBAAEBYWhoCAAIvHzMjIwLZt2wr9mEREROTYXOxtMHToUPTq1QtNmjRBs2bNMG3aNGRmZqJPnz4AgLi4ODzwwAOYOHEiAOCdd97Bww8/jPDwcFy+fBkffPABTp06hX79+gG4/Q2iV155Be+++y5q1KiBsLAwjB49GkFBQejSpUvxjZSIiIjuWXYXLN27d8e5c+cwZswYpKamIiIiAvHx8eYPzSYnJ8PJ6f9euLl06RL69++P1NRUVKhQAY0bN8bmzZtRt25d8zEjRoxAZmYmBgwYgMuXL6NFixaIj4+3WmCOiIiI7k92FywAMGTIEAwZMsTmvsTERIv7U6dOxdSpU/N9PJPJhHfeeQfvvPOOSjhERETk4PhbQkRERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPRYsREREpD0WLERERKQ9FixERESkPZfSDoCIiIjUhY5caXP7yUkdDY6kZPEVFiIiItIeCxYiIiLSHt8SIiIqRvfLy/NERuMrLERERKQ9vsJCRKWKr0gQUWHwFRYiIiLSHgsWIiIi0p5SwTJjxgyEhobCw8MDkZGR2L59e57HzpkzBy1btkSFChVQoUIFxMTEWB3fu3dvmEwmi1v79u1VQiMiIiIHZHfBsnTpUgwdOhRjx47Frl270LBhQ8TGxuKvv/6yeXxiYiJ69uyJdevWYcuWLQgODka7du1w5swZi+Pat2+PlJQU8+2bb75RGxERERE5HLsLlilTpqB///7o06cP6tati9mzZ8PLywvz5s2zefzXX3+NF198EREREahduza++OIL5OTkICEhweI4d3d3BAQEmG8VKlRQGxERERE5HLsKlqysLOzcuRMxMTH/9wBOToiJicGWLVsK9Rh/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88svv2Ds2LFYu3YtgNuLX3Xo0AGPPPII5s+fb3V8fHw89u/fD+D215rHjx+PBx54AO7u7qhSpQomTZqEu79YqZrrQ4cOYf78+eZz+fDhwxg0aBBeeOEFc7x3Uzm/U1JS8NVXX2HVqlXIysqy2JeZmWnz/F61ahX69euHESNGWF1rLl26ZPO6eP78ebz//vt46qmnEBUVhaioKDz11FP44IMPcO7cOZux2fv8FMbp06fxwgsvWGxLSUlBs2bNEBISgvLlyyMuLg5Xr14177948SLatm1r0aZTp05YtGgRrl27Vui+VdrkpVatWjh69GihjlU5h+5mK2+qsanMhUJRWr1FQw0aNJBffvlFRETmzJkjnp6e8tJLL8msWbPklVdekbJly8rcuXPtesw9e/ZYLXDz6quv2rw5OTlJXFyc+f6dcn80qkaNGjJp0iRJSUkpsG9PT0/566+/RETkwIED4uPjI+Hh4dK1a1epXbu2eHl5yd69ey3arFq1Stzc3OThhx+WsWPHysyZM2XmzJkyduxYiY6OFnd3d4mPjy9yDho1amTzlrtIUO79Ox05ckRCQkLMuWjVqpWcPXvWvD81NdVmroOCguS1116TOnXqyIsvvihVq1aVr776ShYvXizh4eHy73//2yrmBQsWiIuLi/To0UPmz58vq1atklWrVsn8+fOlZ8+e4urqKgsXLrRoExMTI507d7b4ddFc6enp0rlzZ2nXrp3F9vj4ePH09JSnn35annvuOfHy8pIhQ4bI66+/LuHh4VK9enWr5/q3334THx8fady4sbRo0UKcnZ3l+eefl+7du0v58uUlOjpaMjIyipwHlfNh/PjxUq5cOXn66aclICBAJk2aJBUrVpR3331XJkyYIJUrV5YxY8ZY5a1fv36SkZEhH3zwgVSpUkX69etn3t+nTx/p0qWLRZs6derIhQsXREQkOTlZQkNDxcfHR5o2bSq+vr7i5+cnJ06cKHKbRYsWiYuLizz00ENStmxZmT9/vpQvX1769esnL7zwgri5ucl3331n0aZWrVqyYcMGERGZMGGCVKxYUaZMmSKrV6+WadOmib+/v0yaNKnIuV69erW4ubmJr6+veHh4yOrVq6Vy5coSExMjjzzyiDg7O0tCQoJFG5Xze/v27VK+fHnx9vYWT09PCQ8Pl99//92839Z59/XXX4uzs7N07NhR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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "df = bpd.read_gbq(SQL_QUERY)\n", "df[[\"date_hour\", \"total_price\"]].plot.bar(x=\"date_hour\", y=\"total_price\")" ] }, { "cell_type": "markdown", "id": "68b62d46-88e0-45bd-ae90-3228553077ee", "metadata": {}, "source": [ "#### Billing details by SKU and hour" ] }, { "cell_type": "code", "execution_count": 30, "id": "efac01dc-89f7-40de-b2fe-22884fef78cd", "metadata": { "tags": [] }, "outputs": [], "source": [ "SQL_QUERY = f\"\"\"\n", " CREATE OR REPLACE MATERIALIZED VIEW {BQ_DATASET_NAME}.{BQ_BILLING_TABLE_VIEW} AS\n", " SELECT \n", " EXTRACT (DATE FROM usage_start_time) date,\n", " EXTRACT (HOUR FROM usage_start_time) hour,\n", " sku.id sku_id, \n", " sku.description sku_description, \n", " price.effective_price / price.pricing_unit_quantity effective_price,\n", " SUM(usage.amount_in_pricing_units) amount_in_pricing_units, \n", " SUM(usage.amount_in_pricing_units * price.effective_price / price.pricing_unit_quantity) total_price\n", " FROM {BQ_BILLING_DATASET_NAME}.{BQ_BILLING_TABLE_NAME}\n", " WHERE \n", " service.description = 'Dataproc' \n", " AND sku.description LIKE 'Data Compute Unit (milli) Hours%'\n", " AND DATE(usage_start_time) >= DATE('{START_DATE}')\n", " GROUP BY 1,2,3,4,5;\n", " \n", " SELECT * FROM {BQ_DATASET_NAME}.{BQ_BILLING_TABLE_VIEW} ORDER BY 1,2;\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 31, "id": "953cbf74-ff08-4c0e-abd3-0f44503b15f2", "metadata": { "scrolled": true, "tags": [] }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7dcbeb52e86d4729a478c4f23ce7c93b", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Query is running: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7d1c9dae1e374369b8188fa509bd6776", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Downloading: 0%| |" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datehoursku_idsku_descriptioneffective_priceamount_in_pricing_unitstotal_price
02024-03-210A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.00008900011721.5733331.043220
12024-03-2121A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.00008900022043.2986111.961854
22024-03-230A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023210963.9386111.098937
32024-03-231A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211849.9991671.187749
42024-03-232A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
52024-03-233A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
62024-03-234A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
72024-03-235A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
82024-03-236A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
92024-03-237A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
102024-03-238A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
112024-03-239A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
122024-03-2310A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
132024-03-2311A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
142024-03-2312A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
152024-03-2313A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
162024-03-2314A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
172024-03-2315A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
182024-03-2316A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
192024-03-2317A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
202024-03-2318A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
212024-03-2319A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
222024-03-2320A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
232024-03-2321A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
242024-03-2322A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
252024-03-2323A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.00010023211850.0000001.187749
262024-03-240A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.0001002322229.2688890.223444
272024-04-2215A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.0000890003556.2347220.316505
282024-04-2215A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.0001002322910.3102780.291706
292024-04-2216A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.0000890001058.4238890.094200
302024-04-2216A065-18C2-08FAData Compute Unit (milli) Hours - Dataproc Ser...0.0001002322979.9602780.298687
312024-05-2920A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.00008900021327.5338891.898151
322024-06-0413A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.0000890001936.0508330.172309
332024-06-0414A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.0000890006321.6805560.562630
342024-06-1812A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.00008900013069.6994441.163203
352024-11-2714A486-6040-07FEData Compute Unit (milli) Hours - Dataproc Ser...0.00008900021816.6319441.941680
362025-02-1217EC7A-EF05-537EData Compute Unit (milli) Hours - Dataproc Ser...0.000060000607.3669440.036442
372025-02-1218EC7A-EF05-537EData Compute Unit (milli) Hours - Dataproc Ser...0.000060000594.9352780.035696
\n", "
" ], "text/plain": [ " date hour sku_id \\\n", "0 2024-03-21 0 A486-6040-07FE \n", "1 2024-03-21 21 A486-6040-07FE \n", "2 2024-03-23 0 A065-18C2-08FA \n", "3 2024-03-23 1 A065-18C2-08FA \n", "4 2024-03-23 2 A065-18C2-08FA \n", "5 2024-03-23 3 A065-18C2-08FA \n", "6 2024-03-23 4 A065-18C2-08FA \n", "7 2024-03-23 5 A065-18C2-08FA \n", "8 2024-03-23 6 A065-18C2-08FA \n", "9 2024-03-23 7 A065-18C2-08FA \n", "10 2024-03-23 8 A065-18C2-08FA \n", "11 2024-03-23 9 A065-18C2-08FA \n", "12 2024-03-23 10 A065-18C2-08FA \n", "13 2024-03-23 11 A065-18C2-08FA \n", "14 2024-03-23 12 A065-18C2-08FA \n", "15 2024-03-23 13 A065-18C2-08FA \n", "16 2024-03-23 14 A065-18C2-08FA \n", "17 2024-03-23 15 A065-18C2-08FA \n", "18 2024-03-23 16 A065-18C2-08FA \n", "19 2024-03-23 17 A065-18C2-08FA \n", "20 2024-03-23 18 A065-18C2-08FA \n", "21 2024-03-23 19 A065-18C2-08FA \n", "22 2024-03-23 20 A065-18C2-08FA \n", "23 2024-03-23 21 A065-18C2-08FA \n", "24 2024-03-23 22 A065-18C2-08FA \n", "25 2024-03-23 23 A065-18C2-08FA \n", "26 2024-03-24 0 A065-18C2-08FA \n", "27 2024-04-22 15 A486-6040-07FE \n", "28 2024-04-22 15 A065-18C2-08FA \n", "29 2024-04-22 16 A486-6040-07FE \n", "30 2024-04-22 16 A065-18C2-08FA \n", "31 2024-05-29 20 A486-6040-07FE \n", "32 2024-06-04 13 A486-6040-07FE \n", "33 2024-06-04 14 A486-6040-07FE \n", "34 2024-06-18 12 A486-6040-07FE \n", "35 2024-11-27 14 A486-6040-07FE \n", "36 2025-02-12 17 EC7A-EF05-537E \n", "37 2025-02-12 18 EC7A-EF05-537E \n", "\n", " sku_description effective_price \\\n", "0 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "1 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "2 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "3 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "4 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "5 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "6 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "7 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "8 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "9 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "10 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "11 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "12 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "13 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "14 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "15 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "16 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "17 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "18 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "19 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "20 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "21 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "22 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "23 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "24 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "25 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "26 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "27 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "28 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "29 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "30 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000100232 \n", "31 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "32 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "33 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "34 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "35 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000089000 \n", "36 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000060000 \n", "37 Data Compute Unit (milli) Hours - Dataproc Ser... 0.000060000 \n", "\n", " amount_in_pricing_units total_price \n", "0 11721.573333 1.043220 \n", "1 22043.298611 1.961854 \n", "2 10963.938611 1.098937 \n", "3 11849.999167 1.187749 \n", "4 11850.000000 1.187749 \n", "5 11850.000000 1.187749 \n", "6 11850.000000 1.187749 \n", "7 11850.000000 1.187749 \n", "8 11850.000000 1.187749 \n", "9 11850.000000 1.187749 \n", "10 11850.000000 1.187749 \n", "11 11850.000000 1.187749 \n", "12 11850.000000 1.187749 \n", "13 11850.000000 1.187749 \n", "14 11850.000000 1.187749 \n", "15 11850.000000 1.187749 \n", "16 11850.000000 1.187749 \n", "17 11850.000000 1.187749 \n", "18 11850.000000 1.187749 \n", "19 11850.000000 1.187749 \n", "20 11850.000000 1.187749 \n", "21 11850.000000 1.187749 \n", "22 11850.000000 1.187749 \n", "23 11850.000000 1.187749 \n", "24 11850.000000 1.187749 \n", "25 11850.000000 1.187749 \n", "26 2229.268889 0.223444 \n", "27 3556.234722 0.316505 \n", "28 2910.310278 0.291706 \n", "29 1058.423889 0.094200 \n", "30 2979.960278 0.298687 \n", "31 21327.533889 1.898151 \n", "32 1936.050833 0.172309 \n", "33 6321.680556 0.562630 \n", "34 13069.699444 1.163203 \n", "35 21816.631944 1.941680 \n", "36 607.366944 0.036442 \n", "37 594.935278 0.035696 " ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%bigquery\n", "$SQL_QUERY" ] }, { "cell_type": "markdown", "id": "45429e85-6532-4d97-b8d7-eb205ff98787", "metadata": { "tags": [] }, "source": [ "## Visualize in Looker Studio " ] }, { "cell_type": "markdown", "id": "a3bc00d4-65d6-4f9f-a1b0-159ef7882972", "metadata": {}, "source": [ "With the refined tables **operations_model** and **billing_model** in your dataset **dataproc_analysis**, you can now generate the following dashboard in Looker Studio. This can provide business and FinOps users a simple pane of glass to understad Dataproc cluster usage and billing." ] }, { "cell_type": "markdown", "id": "90b7f661-0a47-4bec-a5fe-69217176cdbc", "metadata": {}, "source": [ "![dataproc-jobs.png](../../docs/images/dataproc_cluster_insights_bigquery/dataproc-jobs.png)" ] }, { "cell_type": "code", "execution_count": null, "id": "4e518fb2-36da-43d7-90f4-beb78042903a", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "environment": { "kernel": "conda-base-py", "name": "workbench-notebooks.m121", "type": "gcloud", "uri": "us-docker.pkg.dev/deeplearning-platform-release/gcr.io/workbench-notebooks:m121" }, "kernelspec": { "display_name": "Python 3 (ipykernel) (Local)", "language": "python", "name": "conda-base-py" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.14" } }, "nbformat": 4, "nbformat_minor": 5 }