From a93165420bd9c96d52e0e26aff7d9130d74a4e7d Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Mon, 13 Mar 2023 20:30:40 +0100 Subject: [PATCH 1/7] added schema --- build_analytics/migrations/1.sql | 4 +- build_analytics/migrations/3.sql | 78 ++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 build_analytics/migrations/3.sql diff --git a/build_analytics/migrations/1.sql b/build_analytics/migrations/1.sql index cf17985..274e7e5 100644 --- a/build_analytics/migrations/1.sql +++ b/build_analytics/migrations/1.sql @@ -16,7 +16,7 @@ CREATE INDEX IF NOT EXISTS builds_finished_at ON builds(finished_at); --- build_taks_enum +-- build_tasks_enum CREATE TABLE IF NOT EXISTS build_task_status_enum( id INTEGER PRIMARY KEY, value VARCHAR(15) @@ -53,7 +53,7 @@ CREATE TABLE web_node_stats_enum ( ); INSERT INTO web_node_stats_enum (id, value) -VALUEs +VALUES (0, 'build_done'), (1, 'logs_processing'), (2, 'packages_processing'); diff --git a/build_analytics/migrations/3.sql b/build_analytics/migrations/3.sql new file mode 100644 index 0000000..a0e1fc5 --- /dev/null +++ b/build_analytics/migrations/3.sql @@ -0,0 +1,78 @@ +BEGIN; + +-- test_task_status_enum +CREATE TABLE test_task_status_enum( + id INTEGER PRIMARY KEY, + value VARCHAR(15) +); + + + + +INSERT INTO test_task_status_enum (id, value) +VALUES + (0, 'created'), + (1, 'started'), + (2, 'completed'), + (3, 'failed'); + + +-- test_task +CREATE TABLE test_task ( + id INTEGER PRIMARY KEY, + build_task_id INTEGER REFERENCES build_tasks(id) ON DELETE CASCADE, + revision INTEGER, + status_id INTEGER REFERENCES test_task_status_enum(id) ON DELETE SET NULL, + package_fullname VARCHAR(100) +); + +CREATE INDEX test_task_build_task_id +ON test_task(build_task_id); + +CREATE INDEX test_task_build_status_id +ON test_task(status_id); + +CREATE INDEX test_task_package_fullname +ON test_task(package_fullname); + + +-- test_step_enum +CREATE TABLE test_step_enum ( + id INTEGER PRIMARY KEY, + value VARCHAR(50) +); + +INSERT INTO test_step_enum (id, value) +VALUES + (1, 'install_package'), + (2, 'stop_environment'), + (3, 'initial_provision'), + (4, 'start_environment'), + (5, 'uninstall_package'), + (6, 'initialize_terraform'), + (7, 'package_integrity_tests'); + + + +-- test_step +CREATE TABLE test_step_stats( + test_task_id INTEGER, + stat_name_id INTEGER REFERENCES test_step_enum(id) ON DELETE SET NULL, + start_ts DOUBLE PRECISION, + end_ts DOUBLE PRECISION +); + +ALTER TABLE test_step_stats +ADD CONSTRAINT test_step_stats_unique UNIQUE (test_task_id, stat_name_id); + +CREATE INDEX test_step_stats_start_ts +ON test_step_stats(start_ts); + +CREATE INDEX test_step_stats_end_ts +ON test_step_stats(end_ts); + + +UPDATE schema_version +SET version = 3; + +COMMIT; \ No newline at end of file From 08ec138942dbd39ee232a754497683251e7c3d5b Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Wed, 15 Mar 2023 11:28:12 +0100 Subject: [PATCH 2/7] added api and db functions --- build_analytics/build_analytics/api_client.py | 57 ++++++++++++- build_analytics/build_analytics/const.py | 19 ++++- build_analytics/build_analytics/db.py | 24 ++++++ .../build_analytics/extractor/extractor.py | 18 +++-- .../build_analytics/models/test_step_stat.py | 10 +++ .../models/test_step_stat_db.py | 10 +++ .../models/test_steps_stats.py | 37 +++++++++ .../build_analytics/models/test_task.py | 31 ++++++++ .../build_analytics/models/test_task_db.py | 17 ++++ .../grafana-dashbords}/Build analytics.json | 0 .../grafana-dashbords}/Build details.json | 0 .../Build task details.json | 0 build_analytics/migrations/3.sql | 79 +++++++++---------- 13 files changed, 251 insertions(+), 51 deletions(-) create mode 100644 build_analytics/build_analytics/models/test_step_stat.py create mode 100644 build_analytics/build_analytics/models/test_step_stat_db.py create mode 100644 build_analytics/build_analytics/models/test_steps_stats.py create mode 100644 build_analytics/build_analytics/models/test_task.py create mode 100644 build_analytics/build_analytics/models/test_task_db.py rename {grafana-dashbords => build_analytics/grafana-dashbords}/Build analytics.json (100%) rename {grafana-dashbords => build_analytics/grafana-dashbords}/Build details.json (100%) rename {grafana-dashbords => build_analytics/grafana-dashbords}/Build task details.json (100%) diff --git a/build_analytics/build_analytics/api_client.py b/build_analytics/build_analytics/api_client.py index 56a293b..2b112e0 100644 --- a/build_analytics/build_analytics/api_client.py +++ b/build_analytics/build_analytics/api_client.py @@ -1,16 +1,19 @@ from datetime import datetime import logging from urllib.parse import urljoin -from typing import Dict, List +from typing import Dict, List, Any import requests + from .models.build import Build from .models.build_task import BuildTask from .models.build_node_stats import BuildNodeStats from .models.build_stat import BuildStat from .models.web_node_stats import WebNodeStats - +from .models.test_task import TestTask +from .models.test_steps_stats import TestStepsStats +from .models.test_step_stat import TestStepStat TZ_OFFSET = '+00:00' @@ -138,3 +141,53 @@ class APIclient(): 'build_tasks': build_tasks} return Build(**params) + + def get_test_tasks(self, build_task_id: int) -> List[TestTask]: + ep = f'/api/v1/tests/{build_task_id}/latest' + url = urljoin(self.api_root, ep) + headers = {'accept': 'application/json'} + + response = requests.get( + url, headers=headers, timeout=self.timeout) + response.raise_for_status() + return self.__parse_test_tasks() + + def __parse_test_tasks(self, raw_tasks: List[Dict[str, Any]], + build_task_id: int, + started_at: str = None) -> List[TestTask]: + result: List[TestTask] = [] + for task in raw_tasks: + if task['alts_response']: + started_raw = task['alts_response']['stats']['started_at'] + started_at = datetime.fromisoformat(started_raw+TZ_OFFSET) + stats_raw = task['alts_response']['stats'] + results_raw = task['results']['tests'] + step_stats = self.__parse_test_steps_stats( + stats_raw, results_raw) + else: + started_at = None + step_stats = None + params = { + 'id': task['id'], + 'build_task_id': build_task_id, + 'revision': task['revision'], + 'status': task['status'], + 'package_fullname': '_'.join([raw_tasks['package_name'], + raw_tasks['package_version'], + raw_tasks['package_release']]), + 'started_at': started_at, + 'step_stats': step_stats + } + result.append(TestTask(**params)) + return result + + def __parse_test_steps_stats(self, stats_raw: Dict[str, Any], results_raw: Dict[str, Any]) -> TestStepsStats: + teast_steps_params = {} + for field_name in TestStepsStats.__fields__.keys(): + try: + p = stats_raw[field_name] + except KeyError: + continue + p['success'] = results_raw[field_name]['success'] + teast_steps_params[field_name] = TestStepStat(**p) + return TestStepsStats(**teast_steps_params) diff --git a/build_analytics/build_analytics/const.py b/build_analytics/build_analytics/const.py index d00a342..d77ff24 100644 --- a/build_analytics/build_analytics/const.py +++ b/build_analytics/build_analytics/const.py @@ -3,7 +3,7 @@ from enum import IntEnum # supported schema version -DB_SCHEMA_VER = 2 +DB_SCHEMA_VER = 3 # ENUMS @@ -41,3 +41,20 @@ class BuildNodeStatsEnum(IntEnum): build_node_task = 6 cas_notarize_artifacts = 7 cas_source_authenticate = 8 + + +class TestTaskStatusEnum(IntEnum): + created = 1 + started = 2 + completed = 3 + failed = 4 + + +class TestStepEnum(IntEnum): + install_package = 0 + stop_enviroment = 1 + initial_provision = 2 + start_enviroment = 3 + uninstall_package = 4 + initialize_terraform = 5 + package_integrity_tests = 6 diff --git a/build_analytics/build_analytics/db.py b/build_analytics/build_analytics/db.py index b266249..0b60d0d 100644 --- a/build_analytics/build_analytics/db.py +++ b/build_analytics/build_analytics/db.py @@ -9,6 +9,7 @@ from .models.build_task_db import BuildTaskDB from .models.build_node_stat_db import BuildNodeStatDB from .models.db_config import DbConfig from .models.web_node_stat_db import WebNodeStatDB +from .models.test_task_db import TestTaskDB class DB(): @@ -229,3 +230,26 @@ class DB(): cur.execute(sql, (build_task_id, stat_name_id)) val = int(cur.fetchone()[0]) return val == 1 + + def insert_test_task(self, task: TestTaskDB): + # inserting test task itself + sql = ''' + INSERT INTO test_tasks(id, build_task_id, revision, status_id, package_fullname, started_at) + VALUES (%s, %s, %s, %s, %s, %s); + ''' + + cur = self.__conn.cursor() + cur.execute(sql, (task.id, task.build_task_id, task.status_id, + task.package_fullname, task.started_at)) + # inserting test steps stats + for ss in task.steps_stats: + sql = ''' + INSERT INTO test_steps_stats (test_task_id, stat_name_id, start_ts, end_ts, success) + VALUES + (%s, %s, %s, %s, %s); + ''' + cur.execute(sql, (ss.test_task_id, ss.stat_name_id, + ss.start_ts, ss.end_ts, ss.success)) + + # commiting changes + self.__conn.commit() diff --git a/build_analytics/build_analytics/extractor/extractor.py b/build_analytics/build_analytics/extractor/extractor.py index 3a3a953..4702810 100644 --- a/build_analytics/build_analytics/extractor/extractor.py +++ b/build_analytics/build_analytics/extractor/extractor.py @@ -1,13 +1,13 @@ # pylint: disable=relative-beyond-top-level import logging -from typing import List, Dict +from typing import Dict, List -from ..models.extractor_config import ExtractorConfig -from ..const import BuildTaskEnum -from ..models.build import BuildTask -from ..db import DB from ..api_client import APIclient +from ..const import BuildTaskEnum +from ..db import DB +from ..models.build import BuildTask +from ..models.extractor_config import ExtractorConfig class Extractor: @@ -36,7 +36,7 @@ class Extractor: break # inserting build build tasks and build tasks statistics - logging.info("inserting %s", build.id) + logging.info('inserting %s', build.id) try: self.db.insert_build(build.as_db_model()) except Exception as error: # pylint: disable=broad-except @@ -45,6 +45,8 @@ class Extractor: continue for build_task in build.build_tasks: + logging.info('build %s: inserting build task %s', + build.id, build_task.id) try: self.db.insert_buildtask(build_task.as_db_model(), build_task.web_node_stats.as_db_model( @@ -52,8 +54,8 @@ class Extractor: build_task.build_node_stats.as_db_model( build_task.id)) except Exception as error: # pylint: disable=broad-except - logging.error('failed to insert build task %d: %s', - build_task.id, error, exc_info=True) + logging.error('build %s: failed to insert build task %d: %s', + build.id, build_task.id, error, exc_info=True) build_count += 1 page_num += 1 return build_count diff --git a/build_analytics/build_analytics/models/test_step_stat.py b/build_analytics/build_analytics/models/test_step_stat.py new file mode 100644 index 0000000..2632646 --- /dev/null +++ b/build_analytics/build_analytics/models/test_step_stat.py @@ -0,0 +1,10 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel # pylint: disable=no-name-in-module + + +class TestStepStat(BaseModel): + start_ts: Optional[datetime] = None + end_ts: Optional[datetime] = None + success: bool diff --git a/build_analytics/build_analytics/models/test_step_stat_db.py b/build_analytics/build_analytics/models/test_step_stat_db.py new file mode 100644 index 0000000..ddae876 --- /dev/null +++ b/build_analytics/build_analytics/models/test_step_stat_db.py @@ -0,0 +1,10 @@ +from pydantic import BaseModel # pylint: disable=no-name-in-module +from typing import Optional + + +class TestStepStatDB(BaseModel): + test_task_id: int + stat_name_id: int + start_ts: Optional[float] = None + end_ts: Optional[float] = None + success: bool diff --git a/build_analytics/build_analytics/models/test_steps_stats.py b/build_analytics/build_analytics/models/test_steps_stats.py new file mode 100644 index 0000000..5518982 --- /dev/null +++ b/build_analytics/build_analytics/models/test_steps_stats.py @@ -0,0 +1,37 @@ +from typing import List, Optional + +from pydantic import BaseModel # pylint: disable=no-name-in-module + +from ..const import TestStepEnum +from .test_step_stat import TestStepStat +from .test_step_stat_db import TestStepStatDB + + +class TestStepsStats(BaseModel): + install_package: Optional[TestStepStat] = None + stop_environment: Optional[TestStepStat] = None + initial_provision: Optional[TestStepStat] = None + start_environment: Optional[TestStepStat] = None + uninstall_package: Optional[TestStepStat] = None + initialize_terraform: Optional[TestStepStat] = None + package_integrity_tests: Optional[TestStepStat] = None + + def as_db(self, test_task_id: int) -> List[TestStepStatDB]: + result = [] + for field_name in self.__fields__.keys(): + stats: TestStepStat = getattr(self, field_name) + if not stats: + continue + start_ts = stats.start_ts.timestamp() \ + if stats.start_ts else None + end_ts = stats.end_ts.timestamp() \ + if stats.end_ts else None + stat_name_id = TestStepEnum[field_name].value + + test_step_stat_db = TestStepStatDB(test_task_id=test_task_id, + stat_name_id=stat_name_id, + start_ts=start_ts, + end_ts=end_ts, + success=stats.success) + result.append(test_step_stat_db) + return result diff --git a/build_analytics/build_analytics/models/test_task.py b/build_analytics/build_analytics/models/test_task.py new file mode 100644 index 0000000..1b87fea --- /dev/null +++ b/build_analytics/build_analytics/models/test_task.py @@ -0,0 +1,31 @@ +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel # pylint: disable=no-name-in-module + +from .test_task_db import TestTaskDB +from .test_steps_stats import TestStepsStats + + +class TestTask(BaseModel): + id: int + build_task_id: int + revision: int + status: int + package_fullname: str + started_at: Optional[datetime] = None + steps_stats: TestStepsStats + + def as_db_model(self) -> TestTaskDB: + started_at = self.started_at.timestamp() \ + if self.started_at else None + params = { + 'id': self.id, + 'build_task_id': self.build_task_id, + 'revision': self.revision, + 'status': self.status, + 'package_fullname': self.package_fullname, + 'started_at': started_at, + 'steps_stats': self.step_stats.as_db(self.id) + } + return TestTaskDB(**params) diff --git a/build_analytics/build_analytics/models/test_task_db.py b/build_analytics/build_analytics/models/test_task_db.py new file mode 100644 index 0000000..736d054 --- /dev/null +++ b/build_analytics/build_analytics/models/test_task_db.py @@ -0,0 +1,17 @@ +from typing import List, Optional +from pydantic import BaseModel # pylint: disable=no-name-in-module + +from .test_step_stat_db import TestStepStatDB + + +class TestTaskDB(BaseModel): + """ + Test task as it received from/sent to database + """ + id: int + build_task_id: int + revision: int + status_id: int + package_fullname: str + started_at: float + steps_stats: List[TestStepStatDB] = None diff --git a/grafana-dashbords/Build analytics.json b/build_analytics/grafana-dashbords/Build analytics.json similarity index 100% rename from grafana-dashbords/Build analytics.json rename to build_analytics/grafana-dashbords/Build analytics.json diff --git a/grafana-dashbords/Build details.json b/build_analytics/grafana-dashbords/Build details.json similarity index 100% rename from grafana-dashbords/Build details.json rename to build_analytics/grafana-dashbords/Build details.json diff --git a/grafana-dashbords/Build task details.json b/build_analytics/grafana-dashbords/Build task details.json similarity index 100% rename from grafana-dashbords/Build task details.json rename to build_analytics/grafana-dashbords/Build task details.json diff --git a/build_analytics/migrations/3.sql b/build_analytics/migrations/3.sql index a0e1fc5..cc2b688 100644 --- a/build_analytics/migrations/3.sql +++ b/build_analytics/migrations/3.sql @@ -1,75 +1,74 @@ BEGIN; --- test_task_status_enum -CREATE TABLE test_task_status_enum( +-- test_tasks_status_enum +CREATE TABLE test_tasks_status_enum( id INTEGER PRIMARY KEY, value VARCHAR(15) ); - - - -INSERT INTO test_task_status_enum (id, value) +INSERT INTO test_tasks_status_enum (id, value) VALUES - (0, 'created'), - (1, 'started'), - (2, 'completed'), - (3, 'failed'); + (1, 'created'), + (2, 'started'), + (3, 'completed'), + (4, 'failed'); --- test_task -CREATE TABLE test_task ( +-- test_tasks +CREATE TABLE test_tasks ( id INTEGER PRIMARY KEY, build_task_id INTEGER REFERENCES build_tasks(id) ON DELETE CASCADE, revision INTEGER, - status_id INTEGER REFERENCES test_task_status_enum(id) ON DELETE SET NULL, - package_fullname VARCHAR(100) + status_id INTEGER REFERENCES test_tasks_status_enum(id) ON DELETE SET NULL, + package_fullname VARCHAR(100), + started_at DOUBLE PRECISION ); -CREATE INDEX test_task_build_task_id -ON test_task(build_task_id); +CREATE INDEX test_tasks_build_task_id +ON test_tasks(build_task_id); -CREATE INDEX test_task_build_status_id -ON test_task(status_id); +CREATE INDEX test_tasks_build_status_id +ON test_tasks(status_id); -CREATE INDEX test_task_package_fullname -ON test_task(package_fullname); +CREATE INDEX test_tasks_package_fullname +ON test_tasks(package_fullname); --- test_step_enum -CREATE TABLE test_step_enum ( +-- test_steps_enum +CREATE TABLE test_steps_enum ( id INTEGER PRIMARY KEY, value VARCHAR(50) ); -INSERT INTO test_step_enum (id, value) +INSERT INTO test_steps_enum (id, value) VALUES - (1, 'install_package'), - (2, 'stop_environment'), - (3, 'initial_provision'), - (4, 'start_environment'), - (5, 'uninstall_package'), - (6, 'initialize_terraform'), - (7, 'package_integrity_tests'); + (0, 'install_package'), + (1, 'stop_environment'), + (2, 'initial_provision'), + (3, 'start_environment'), + (4, 'uninstall_package'), + (5, 'initialize_terraform'), + (6, 'package_integrity_tests'); --- test_step -CREATE TABLE test_step_stats( +-- test_steps +CREATE TABLE test_steps_stats( test_task_id INTEGER, - stat_name_id INTEGER REFERENCES test_step_enum(id) ON DELETE SET NULL, + stat_name_id INTEGER REFERENCES (id) ON DELETE SET NULL, start_ts DOUBLE PRECISION, - end_ts DOUBLE PRECISION + end_ts DOUBLE PRECISION, + success BOOLEAN ); -ALTER TABLE test_step_stats -ADD CONSTRAINT test_step_stats_unique UNIQUE (test_task_id, stat_name_id); +ALTER TABLE test_steps_stats +ADD CONSTRAINT test_steps_stats_unique UNIQUE (test_task_id, stat_name_id); -CREATE INDEX test_step_stats_start_ts -ON test_step_stats(start_ts); +CREATE INDEX test_steps_stats_start_ts +ON test_steps_stats(start_ts); -CREATE INDEX test_step_stats_end_ts -ON test_step_stats(end_ts); +CREATE INDEX test_steps_stats_end_ts +ON test_steps_stats(end_ts); UPDATE schema_version From 45a68500564761c439125d808d442894528ac3fa Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Thu, 16 Mar 2023 09:31:09 +0100 Subject: [PATCH 3/7] debugging --- build_analytics/build_analytics/api_client.py | 19 ++++++------- build_analytics/build_analytics/const.py | 3 +- build_analytics/build_analytics/db.py | 28 ++++++++++--------- .../build_analytics/extractor/extractor.py | 9 ++++++ .../build_analytics/models/sign_task_db.py | 2 +- .../build_analytics/models/test_step_stat.py | 3 +- .../models/test_step_stat_db.py | 3 +- .../models/test_steps_stats.py | 7 ++--- .../build_analytics/models/test_task.py | 6 ++-- .../build_analytics/models/test_task_db.py | 4 +-- build_analytics/migrations/3.sql | 10 +++---- build_analytics/releases.txt | 5 +++- 12 files changed, 54 insertions(+), 45 deletions(-) diff --git a/build_analytics/build_analytics/api_client.py b/build_analytics/build_analytics/api_client.py index 2b112e0..e16c7d5 100644 --- a/build_analytics/build_analytics/api_client.py +++ b/build_analytics/build_analytics/api_client.py @@ -150,7 +150,7 @@ class APIclient(): response = requests.get( url, headers=headers, timeout=self.timeout) response.raise_for_status() - return self.__parse_test_tasks() + return self.__parse_test_tasks(response.json(), build_task_id) def __parse_test_tasks(self, raw_tasks: List[Dict[str, Any]], build_task_id: int, @@ -161,33 +161,30 @@ class APIclient(): started_raw = task['alts_response']['stats']['started_at'] started_at = datetime.fromisoformat(started_raw+TZ_OFFSET) stats_raw = task['alts_response']['stats'] - results_raw = task['results']['tests'] - step_stats = self.__parse_test_steps_stats( - stats_raw, results_raw) + steps_stats = self.__parse_test_steps_stats(stats_raw) else: started_at = None - step_stats = None + steps_stats = None params = { 'id': task['id'], 'build_task_id': build_task_id, 'revision': task['revision'], 'status': task['status'], - 'package_fullname': '_'.join([raw_tasks['package_name'], - raw_tasks['package_version'], - raw_tasks['package_release']]), + 'package_fullname': '_'.join([task['package_name'], + task['package_version'], + task['package_release']]), 'started_at': started_at, - 'step_stats': step_stats + 'steps_stats': steps_stats } result.append(TestTask(**params)) return result - def __parse_test_steps_stats(self, stats_raw: Dict[str, Any], results_raw: Dict[str, Any]) -> TestStepsStats: + def __parse_test_steps_stats(self, stats_raw: Dict[str, Any]) -> TestStepsStats: teast_steps_params = {} for field_name in TestStepsStats.__fields__.keys(): try: p = stats_raw[field_name] except KeyError: continue - p['success'] = results_raw[field_name]['success'] teast_steps_params[field_name] = TestStepStat(**p) return TestStepsStats(**teast_steps_params) diff --git a/build_analytics/build_analytics/const.py b/build_analytics/build_analytics/const.py index d77ff24..37367ab 100644 --- a/build_analytics/build_analytics/const.py +++ b/build_analytics/build_analytics/const.py @@ -54,7 +54,8 @@ class TestStepEnum(IntEnum): install_package = 0 stop_enviroment = 1 initial_provision = 2 - start_enviroment = 3 + start_environment = 3 uninstall_package = 4 initialize_terraform = 5 package_integrity_tests = 6 + stop_environment = 7 diff --git a/build_analytics/build_analytics/db.py b/build_analytics/build_analytics/db.py index 0b60d0d..1a4ab0f 100644 --- a/build_analytics/build_analytics/db.py +++ b/build_analytics/build_analytics/db.py @@ -232,24 +232,26 @@ class DB(): return val == 1 def insert_test_task(self, task: TestTaskDB): + cur = self.__conn.cursor() # inserting test task itself sql = ''' INSERT INTO test_tasks(id, build_task_id, revision, status_id, package_fullname, started_at) - VALUES (%s, %s, %s, %s, %s, %s); + VALUES + (%s, %s, %s, %s, %s, %s); ''' - - cur = self.__conn.cursor() - cur.execute(sql, (task.id, task.build_task_id, task.status_id, + cur.execute(sql, (task.id, task.build_task_id, task.revision, task.status_id, task.package_fullname, task.started_at)) - # inserting test steps stats - for ss in task.steps_stats: - sql = ''' - INSERT INTO test_steps_stats (test_task_id, stat_name_id, start_ts, end_ts, success) - VALUES - (%s, %s, %s, %s, %s); - ''' - cur.execute(sql, (ss.test_task_id, ss.stat_name_id, - ss.start_ts, ss.end_ts, ss.success)) + + if task.steps_stats: + # inserting test steps stats + for ss in task.steps_stats: + sql = ''' + INSERT INTO test_steps_stats (test_task_id, stat_name_id, start_ts, finish_ts) + VALUES + (%s, %s, %s, %s); + ''' + cur.execute(sql, (ss.test_task_id, ss.stat_name_id, + ss.start_ts, ss.finish_ts)) # commiting changes self.__conn.commit() diff --git a/build_analytics/build_analytics/extractor/extractor.py b/build_analytics/build_analytics/extractor/extractor.py index 4702810..7603a44 100644 --- a/build_analytics/build_analytics/extractor/extractor.py +++ b/build_analytics/build_analytics/extractor/extractor.py @@ -56,6 +56,15 @@ class Extractor: except Exception as error: # pylint: disable=broad-except logging.error('build %s: failed to insert build task %d: %s', build.id, build_task.id, error, exc_info=True) + + logging.info( + 'getting test tasks for build task %s', build_task.id) + test_tasks = self.api.get_test_tasks(build_task.id) + logging.info('received %d tests tasks', len(test_tasks)) + for t in test_tasks: + logging.info( + 'build task %s: inserting test task %s', build_task.id, t.id) + self.db.insert_test_task(t.as_db_model()) build_count += 1 page_num += 1 return build_count diff --git a/build_analytics/build_analytics/models/sign_task_db.py b/build_analytics/build_analytics/models/sign_task_db.py index 60281f2..e6d47af 100644 --- a/build_analytics/build_analytics/models/sign_task_db.py +++ b/build_analytics/build_analytics/models/sign_task_db.py @@ -1,4 +1,4 @@ -from pydantic import BaseModel +from pydantic import BaseModel # pylint: disable=no-name-in-module class SignTaskDB(BaseModel): diff --git a/build_analytics/build_analytics/models/test_step_stat.py b/build_analytics/build_analytics/models/test_step_stat.py index 2632646..9dcc598 100644 --- a/build_analytics/build_analytics/models/test_step_stat.py +++ b/build_analytics/build_analytics/models/test_step_stat.py @@ -6,5 +6,4 @@ from pydantic import BaseModel # pylint: disable=no-name-in-module class TestStepStat(BaseModel): start_ts: Optional[datetime] = None - end_ts: Optional[datetime] = None - success: bool + finish_ts: Optional[datetime] = None diff --git a/build_analytics/build_analytics/models/test_step_stat_db.py b/build_analytics/build_analytics/models/test_step_stat_db.py index ddae876..52cc090 100644 --- a/build_analytics/build_analytics/models/test_step_stat_db.py +++ b/build_analytics/build_analytics/models/test_step_stat_db.py @@ -6,5 +6,4 @@ class TestStepStatDB(BaseModel): test_task_id: int stat_name_id: int start_ts: Optional[float] = None - end_ts: Optional[float] = None - success: bool + finish_ts: Optional[float] = None diff --git a/build_analytics/build_analytics/models/test_steps_stats.py b/build_analytics/build_analytics/models/test_steps_stats.py index 5518982..a783b91 100644 --- a/build_analytics/build_analytics/models/test_steps_stats.py +++ b/build_analytics/build_analytics/models/test_steps_stats.py @@ -24,14 +24,13 @@ class TestStepsStats(BaseModel): continue start_ts = stats.start_ts.timestamp() \ if stats.start_ts else None - end_ts = stats.end_ts.timestamp() \ - if stats.end_ts else None + finish_ts = stats.finish_ts.timestamp() \ + if stats.finish_ts else None stat_name_id = TestStepEnum[field_name].value test_step_stat_db = TestStepStatDB(test_task_id=test_task_id, stat_name_id=stat_name_id, start_ts=start_ts, - end_ts=end_ts, - success=stats.success) + finish_ts=finish_ts) result.append(test_step_stat_db) return result diff --git a/build_analytics/build_analytics/models/test_task.py b/build_analytics/build_analytics/models/test_task.py index 1b87fea..e7abe3b 100644 --- a/build_analytics/build_analytics/models/test_task.py +++ b/build_analytics/build_analytics/models/test_task.py @@ -14,7 +14,7 @@ class TestTask(BaseModel): status: int package_fullname: str started_at: Optional[datetime] = None - steps_stats: TestStepsStats + steps_stats: Optional[TestStepsStats] = None def as_db_model(self) -> TestTaskDB: started_at = self.started_at.timestamp() \ @@ -23,9 +23,9 @@ class TestTask(BaseModel): 'id': self.id, 'build_task_id': self.build_task_id, 'revision': self.revision, - 'status': self.status, + 'status_id': self.status, 'package_fullname': self.package_fullname, 'started_at': started_at, - 'steps_stats': self.step_stats.as_db(self.id) + 'steps_stats': self.steps_stats.as_db(self.id) if self.steps_stats else None } return TestTaskDB(**params) diff --git a/build_analytics/build_analytics/models/test_task_db.py b/build_analytics/build_analytics/models/test_task_db.py index 736d054..c1e281a 100644 --- a/build_analytics/build_analytics/models/test_task_db.py +++ b/build_analytics/build_analytics/models/test_task_db.py @@ -13,5 +13,5 @@ class TestTaskDB(BaseModel): revision: int status_id: int package_fullname: str - started_at: float - steps_stats: List[TestStepStatDB] = None + started_at: Optional[float] = None + steps_stats: Optional[List[TestStepStatDB]] = None diff --git a/build_analytics/migrations/3.sql b/build_analytics/migrations/3.sql index cc2b688..8ebb3a5 100644 --- a/build_analytics/migrations/3.sql +++ b/build_analytics/migrations/3.sql @@ -48,17 +48,17 @@ VALUES (3, 'start_environment'), (4, 'uninstall_package'), (5, 'initialize_terraform'), - (6, 'package_integrity_tests'); + (6, 'package_integrity_tests'), + (7, 'stop_environment'); -- test_steps CREATE TABLE test_steps_stats( - test_task_id INTEGER, - stat_name_id INTEGER REFERENCES (id) ON DELETE SET NULL, + test_task_id INTEGER REFERENCES test_tasks(id) ON DELETE CASCADE, + stat_name_id INTEGER REFERENCES test_steps_enum(id) ON DELETE SET NULL, start_ts DOUBLE PRECISION, - end_ts DOUBLE PRECISION, - success BOOLEAN + finish_ts DOUBLE PRECISION ); ALTER TABLE test_steps_stats diff --git a/build_analytics/releases.txt b/build_analytics/releases.txt index 236fc65..0d8799a 100644 --- a/build_analytics/releases.txt +++ b/build_analytics/releases.txt @@ -7,4 +7,7 @@ First version - Added metrics for build steps 0.2.1 (2023-03-15) - - Added canceled Build task status \ No newline at end of file + - Added canceled Build task status + +0.3.0 (IN PROGRESS) + - Added test tasks stats \ No newline at end of file From 679328093a628bb2de15f78e954b902dcf528698 Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Thu, 16 Mar 2023 18:57:31 +0100 Subject: [PATCH 4/7] added test tasks updating logic --- build_analytics/build_analytics/db.py | 66 +++++++++++++++++-- .../build_analytics/extractor/extractor.py | 27 ++++++-- .../build_analytics/extractor/start.py | 48 +++++++------- .../models/extractor_config.py | 6 +- build_analytics/config_default.yml | 8 +++ build_analytics/migrations/3.sql | 2 +- build_analytics/releases.txt | 3 +- 7 files changed, 122 insertions(+), 38 deletions(-) diff --git a/build_analytics/build_analytics/db.py b/build_analytics/build_analytics/db.py index 1a4ab0f..35200f4 100644 --- a/build_analytics/build_analytics/db.py +++ b/build_analytics/build_analytics/db.py @@ -10,6 +10,7 @@ from .models.build_node_stat_db import BuildNodeStatDB from .models.db_config import DbConfig from .models.web_node_stat_db import WebNodeStatDB from .models.test_task_db import TestTaskDB +from .models.test_step_stat_db import TestStepStatDB class DB(): @@ -100,7 +101,7 @@ class DB(): self.__conn.commit() return cur.rowcount - def get_unfinished_builds(self) -> Dict[int, Dict[int, int]]: + def get_unfinished_builds(self, not_before: datetime) -> Dict[int, Dict[int, int]]: """ Getting list of unfinished builds and build_tasks Dict[build_id, Dict[build_task_id, task_status_id]] @@ -108,8 +109,8 @@ class DB(): res: Dict[int, Dict[int, int]] = {} # getting unfinished builds - sql = 'SELECT id FROM builds where finished_at is NULL;' - cur = self.__conn.cursor() + sql = 'SELECT id FROM builds where finished_at is NULL AND created_at > %s ;' + cur = self.__conn.cursor(not_before.timestamp()) cur.execute(sql) for row in cur.fetchall(): res[row[0]] = {} @@ -160,7 +161,7 @@ class DB(): for stat in web_node_stats: logging.debug( 'updating web_node_stats %s build_task %s', stat.stat_name_id, build_task.id) - if self.stat_exists(build_task_id=stat.build_task_id, + if self.stat_exists(task_id=stat.build_task_id, stat_name_id=stat.stat_name_id, table_name='web_node_stats'): sql = ''' @@ -184,7 +185,7 @@ class DB(): for stat in build_node_stats: logging.debug( 'updating build_node_stats %s build_task %s', stat.stat_name_id, build_task.id) - if self.stat_exists(build_task_id=stat.build_task_id, + if self.stat_exists(task_id=stat.build_task_id, stat_name_id=stat.stat_name_id, table_name='build_node_stats'): sql = ''' @@ -220,14 +221,14 @@ class DB(): return None return int(val[0]) - def stat_exists(self, build_task_id: int, stat_name_id: int, table_name: str) -> bool: + def stat_exists(self, task_id: int, stat_name_id: int, table_name: str) -> bool: sql = f''' SELECT COUNT(build_task_id) FROM {table_name} WHERE build_task_id = %s AND stat_name_id = %s; ''' cur = self.__conn.cursor() - cur.execute(sql, (build_task_id, stat_name_id)) + cur.execute(sql, (task_id, stat_name_id)) val = int(cur.fetchone()[0]) return val == 1 @@ -255,3 +256,54 @@ class DB(): # commiting changes self.__conn.commit() + + def get_build_tasks_for_unfinished_tests(self, not_before: datetime) -> List[int]: + ''' + getting build tasks id of unfinished test tasks + ''' + cur = self.__conn.cursor() + sql = ''' + SELECT bt.id + FROM build_tasks as bt + INNER JOIN test_tasks AS tt + ON bt.id = tt.build_task_id + WHERE tt.status_id < 3 AND tt.started_at > %s; + ''' + cur.execute(sql, (not_before,)) + result = [int(row[0]) for row in cur.fetchall()] + return result + + def update_test_tasks(self, test_tasks: List[TestTaskDB]): + cur = self.__conn.cursor() + # test tasks + for task in test_tasks: + sql = ''' + UPDATE test_tasks + SET revision = %s, + status_id = %s, + started_at = %s + WHERE id = %s; + ''' + cur.execute(sql, (task.revision, task.status_id, + task.started_at, task.id)) + + # test step + if not task.steps_stats: + continue + for s in task.steps_stats: + if self.stat_exists(s.test_task_id, s.stat_name_id, 'test_steps_stats'): + sql = ''' + UPDATE test_steps_stats + SET start_ts = %s, + SET finish_ts = %s; + ''' + cur.execute(sql, s.start_ts, s.finish_ts) + else: + sql = ''' + INSERT INTO test_steps_stats (test_task_id, stat_name_id, start_ts, finish_ts) + VALUES (%s, %s, %s, %s); + ''' + cur.execute(sql, (s.test_task_id, s.stat_name_id, + s.start_ts, s.finish_ts)) + # commiting changes + self.__conn.commit() diff --git a/build_analytics/build_analytics/extractor/extractor.py b/build_analytics/build_analytics/extractor/extractor.py index 7603a44..df83acc 100644 --- a/build_analytics/build_analytics/extractor/extractor.py +++ b/build_analytics/build_analytics/extractor/extractor.py @@ -12,8 +12,7 @@ from ..models.extractor_config import ExtractorConfig class Extractor: def __init__(self, config: ExtractorConfig, api: APIclient, db: DB): - self.start_from = config.start_from - self.oldest_build_age = config.oldest_build_age + self.config = config self.api = api self.db = db @@ -22,7 +21,7 @@ class Extractor: page_num = 1 last_build_id = self.db.get_latest_build_id() if not last_build_id: - last_build_id = self.start_from - 1 + last_build_id = self.config.start_from - 1 logging.info("last_build_id: %s", last_build_id) stop = False @@ -31,7 +30,7 @@ class Extractor: for build in self.api.get_builds(page_num): # check if we shoud stop processing build if build.id <= last_build_id or \ - build.created_at <= self.oldest_build_age: + build.created_at <= self.config.oldest_build_age: stop = True break @@ -71,8 +70,8 @@ class Extractor: def build_cleanup(self): logging.info('Removing all buidls older then %s', - self.oldest_build_age.strftime("%m/%d/%Y, %H:%M:%S")) - removed_count = self.db.cleanup_builds(self.oldest_build_age) + self.config.oldest_build_age.strftime("%m/%d/%Y, %H:%M:%S")) + removed_count = self.db.cleanup_builds(self.config.oldest_build_age) logging.info('removed %d entries', removed_count) def __update_build_tasks(self, build_tasks: List[BuildTask], @@ -125,3 +124,19 @@ class Extractor: except Exception as err: # pylint: disable=broad-except logging.error("Cant process build %d: %s", build_id, err, exc_info=True) + + def updating_test_tasks(self): + logging.info('getting build task ids of unfinished tests') + build_task_ids = self.db.get_build_tasks_for_unfinished_tests( + self.config.oldest_to_update) + for build_task_id in build_task_ids: + try: + logging.info('getting tests for build task %s', build_task_id) + tasks_api = self.api.get_test_tasks(build_task_id) + logging.info('updating test tasks') + tasks_db = [t.as_db_model() for t in tasks_api] + self.db.update_test_tasks(tasks_db) + except Exception as err: + logging.error( + 'failed to update tests for %d build task: %s', + build_task_id, err, exc_info=True) diff --git a/build_analytics/build_analytics/extractor/start.py b/build_analytics/build_analytics/extractor/start.py index d7f86e3..e14598a 100644 --- a/build_analytics/build_analytics/extractor/start.py +++ b/build_analytics/build_analytics/extractor/start.py @@ -15,20 +15,6 @@ from ..models.extractor_config import ExtractorConfig from ..models.db_config import DbConfig -def __get_oldest_build_age(config: dict) -> datetime: - oldest_build_age = datetime.now().astimezone() \ - - timedelta(days=config['data_store_days']) - return oldest_build_age - - -def __get_db_config(config: dict) -> DbConfig: - return DbConfig(name=config['db_name'], - port=int(config['db_port']), - host=config['db_host'], - username=config['db_username'], - password=config['db_password']) - - def __get_config(yml_path: str) -> ExtractorConfig: """ get_config loads yml file and generates instance @@ -37,8 +23,18 @@ def __get_config(yml_path: str) -> ExtractorConfig: raw = yaml.safe_load(flr) # adding new attrs - raw['oldest_build_age'] = __get_oldest_build_age(raw) - raw['db_config'] = __get_db_config(raw) + raw['oldest_build_age'] = datetime.now().astimezone() \ + - timedelta(days=raw['data_store_days']) + + raw['db_config'] = DbConfig(name=raw['db_name'], + port=int(raw['db_port']), + host=raw['db_host'], + username=raw['db_username'], + password=raw['db_password']) + + if 'oldest_to_update_days' in raw: + raw['oldest_to_update_days'] = datetime.now().astimezone() \ + - timedelta(days=raw['oldest_to_update_days']) return ExtractorConfig(**raw) @@ -83,21 +79,29 @@ def start(yml_path: str): logging.info( 'Build extaction was finished. %d builds were inserted', inserted_count) - logging.info('Starting old builds removal') + logging.info('starting old builds removal') try: extractor.build_cleanup() except Exception as err: # pylint: disable=broad-except - logging.critical("Unhandled exception %s", err, exc_info=True) + logging.critical("unhandled exception %s", err, exc_info=True) else: - logging.info('Cleanup finished') + logging.info('cleanup finished') - logging.info('Updating statuses of unfinished build tasks') + logging.info('updating statuses of unfinished build tasks') try: extractor.update_builds() except Exception as err: # pylint: disable=broad-except - logging.critical("Unhandled exception %s", err, exc_info=True) + logging.critical("unhandled exception %s", err, exc_info=True) else: - logging.info('Update finished') + logging.info('update finished') + + logging.info('updating statuses of unfinished test tasks') + try: + extractor.updating_test_tasks() + except Exception as err: # pylint: disable=broad-except + logging.critical("unhandled exception %s", err, exc_info=True) + else: + logging.info('test tasks were updated') extractor.db.close_conn() logging.info("Extraction was finished") diff --git a/build_analytics/build_analytics/models/extractor_config.py b/build_analytics/build_analytics/models/extractor_config.py index a49c3dd..15efa3b 100644 --- a/build_analytics/build_analytics/models/extractor_config.py +++ b/build_analytics/build_analytics/models/extractor_config.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timedelta from pathlib import Path from pydantic import HttpUrl, Field, BaseModel # pylint: disable=no-name-in-module @@ -11,6 +11,7 @@ LOG_FILE_DEFAULT = '/tmp/extractor.log' API_DEFAULT = 30 SCRAPE_INTERVAL_DEFAULT = 3600 START_FROM_DEFAULT = 5808 +OLDEST_TO_UPDATE_DEFAULT = datetime.now().astimezone() - timedelta(days=3) class ExtractorConfig(BaseModel): @@ -32,3 +33,6 @@ class ExtractorConfig(BaseModel): default=SCRAPE_INTERVAL_DEFAULT) start_from: int = Field(description='build id to start populating empty db with', default=START_FROM_DEFAULT) + oldest_to_update: datetime = \ + Field(description='oldest unfinished object (build/task/step...) that we will try to update', + default=OLDEST_TO_UPDATE_DEFAULT) diff --git a/build_analytics/config_default.yml b/build_analytics/config_default.yml index 8e68a61..7d16c97 100644 --- a/build_analytics/config_default.yml +++ b/build_analytics/config_default.yml @@ -61,3 +61,11 @@ scrape_interval: 3600 # required: false # default: 5808 (first build with correct metrics) start_from: + + +# oldest_to_update +# oldest (in days) unfinished object (build/task/step...) that we will try to update +# required: false +# default: 3 +oldest_to_update_days: 3 + diff --git a/build_analytics/migrations/3.sql b/build_analytics/migrations/3.sql index 8ebb3a5..9169351 100644 --- a/build_analytics/migrations/3.sql +++ b/build_analytics/migrations/3.sql @@ -53,7 +53,7 @@ VALUES --- test_steps +-- test_steps_stats CREATE TABLE test_steps_stats( test_task_id INTEGER REFERENCES test_tasks(id) ON DELETE CASCADE, stat_name_id INTEGER REFERENCES test_steps_enum(id) ON DELETE SET NULL, diff --git a/build_analytics/releases.txt b/build_analytics/releases.txt index 0d8799a..9b03a2e 100644 --- a/build_analytics/releases.txt +++ b/build_analytics/releases.txt @@ -10,4 +10,5 @@ First version - Added canceled Build task status 0.3.0 (IN PROGRESS) - - Added test tasks stats \ No newline at end of file + - Added test tasks stats + - New config parameter: oldest_to_update_days \ No newline at end of file From 313d4a4d2a691549e3c0762782038020dbd7d359 Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Thu, 16 Mar 2023 22:48:35 +0100 Subject: [PATCH 5/7] db: debug of update feature --- build_analytics/build_analytics/db.py | 42 ++++++++++++------- .../build_analytics/extractor/extractor.py | 5 ++- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/build_analytics/build_analytics/db.py b/build_analytics/build_analytics/db.py index 35200f4..edbfe4c 100644 --- a/build_analytics/build_analytics/db.py +++ b/build_analytics/build_analytics/db.py @@ -10,7 +10,6 @@ from .models.build_node_stat_db import BuildNodeStatDB from .models.db_config import DbConfig from .models.web_node_stat_db import WebNodeStatDB from .models.test_task_db import TestTaskDB -from .models.test_step_stat_db import TestStepStatDB class DB(): @@ -109,9 +108,10 @@ class DB(): res: Dict[int, Dict[int, int]] = {} # getting unfinished builds - sql = 'SELECT id FROM builds where finished_at is NULL AND created_at > %s ;' - cur = self.__conn.cursor(not_before.timestamp()) - cur.execute(sql) + sql = 'SELECT id FROM builds where finished_at is NULL AND created_at > %s;' + cur = self.__conn.cursor() + cur.execute(sql, (not_before.timestamp(),)) + logging.debug('raw SQL query: %s', cur.query) for row in cur.fetchall(): res[row[0]] = {} @@ -163,7 +163,8 @@ class DB(): 'updating web_node_stats %s build_task %s', stat.stat_name_id, build_task.id) if self.stat_exists(task_id=stat.build_task_id, stat_name_id=stat.stat_name_id, - table_name='web_node_stats'): + table_name='web_node_stats', + column_name='build_task_id'): sql = ''' UPDATE web_node_stats SET start_ts = %(start_ts)s, end_ts = %(end_ts)s @@ -187,7 +188,8 @@ class DB(): 'updating build_node_stats %s build_task %s', stat.stat_name_id, build_task.id) if self.stat_exists(task_id=stat.build_task_id, stat_name_id=stat.stat_name_id, - table_name='build_node_stats'): + table_name='build_node_stats', + column_name='build_task_id'): sql = ''' UPDATE build_node_stats SET start_ts = %(start_ts)s, end_ts = %(end_ts)s @@ -221,11 +223,11 @@ class DB(): return None return int(val[0]) - def stat_exists(self, task_id: int, stat_name_id: int, table_name: str) -> bool: + def stat_exists(self, task_id: int, stat_name_id: int, table_name: str, column_name: str) -> bool: sql = f''' - SELECT COUNT(build_task_id) + SELECT COUNT({column_name}) FROM {table_name} - WHERE build_task_id = %s AND stat_name_id = %s; + WHERE {column_name} = %s AND stat_name_id = %s; ''' cur = self.__conn.cursor() cur.execute(sql, (task_id, stat_name_id)) @@ -263,13 +265,14 @@ class DB(): ''' cur = self.__conn.cursor() sql = ''' - SELECT bt.id + SELECT DISTINCT bt.id FROM build_tasks as bt INNER JOIN test_tasks AS tt ON bt.id = tt.build_task_id - WHERE tt.status_id < 3 AND tt.started_at > %s; + WHERE tt.status_id < 3 AND bt.started_at > %s; ''' - cur.execute(sql, (not_before,)) + cur.execute(sql, (not_before.timestamp(),)) + logging.info('raw SQL query: %s', cur.query) result = [int(row[0]) for row in cur.fetchall()] return result @@ -286,18 +289,27 @@ class DB(): ''' cur.execute(sql, (task.revision, task.status_id, task.started_at, task.id)) + assert cur.rowcount == 1 # test step if not task.steps_stats: continue for s in task.steps_stats: - if self.stat_exists(s.test_task_id, s.stat_name_id, 'test_steps_stats'): + logging.info('test_task_id %s, stat_name_id %s', + s.test_task_id, s.stat_name_id) + if self.stat_exists(s.test_task_id, + s.stat_name_id, + 'test_steps_stats', + 'test_task_id'): sql = ''' UPDATE test_steps_stats SET start_ts = %s, - SET finish_ts = %s; + finish_ts = %s + WHERE test_task_id = %s AND stat_name_id = %s; ''' - cur.execute(sql, s.start_ts, s.finish_ts) + cur.execute(sql, (s.start_ts, s.finish_ts, + s.test_task_id, s.stat_name_id)) + assert cur.rowcount == 1 else: sql = ''' INSERT INTO test_steps_stats (test_task_id, stat_name_id, start_ts, finish_ts) diff --git a/build_analytics/build_analytics/extractor/extractor.py b/build_analytics/build_analytics/extractor/extractor.py index df83acc..45770bc 100644 --- a/build_analytics/build_analytics/extractor/extractor.py +++ b/build_analytics/build_analytics/extractor/extractor.py @@ -102,7 +102,8 @@ class Extractor: def update_builds(self): logging.info('Getting list of tasks from DB') - unfinished_tasks = self.db.get_unfinished_builds() + unfinished_tasks = self.db.get_unfinished_builds( + self.config.oldest_to_update) for build_id, build_tasks_db in unfinished_tasks.items(): try: logging.info('Getting status of build %d', build_id) @@ -136,7 +137,7 @@ class Extractor: logging.info('updating test tasks') tasks_db = [t.as_db_model() for t in tasks_api] self.db.update_test_tasks(tasks_db) - except Exception as err: + except Exception as err: # pylint: disable=broad-except logging.error( 'failed to update tests for %d build task: %s', build_task_id, err, exc_info=True) From 4d5ffcc74fc4b89c75a49fa24b5a0da42b6d8e77 Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Mon, 20 Mar 2023 19:29:45 +0100 Subject: [PATCH 6/7] - Added new try/catch segments - Added tz info to test step stats timestamps - Increased oldest_to_update_days parameter --- build_analytics/build_analytics/api_client.py | 21 +- build_analytics/build_analytics/db.py | 2 +- .../models/extractor_config.py | 2 +- build_analytics/config_default.yml | 4 +- .../grafana-dashbords/Build analytics.json | 928 +++++++++--------- .../grafana-dashbords/Build details.json | 811 +++++++-------- 6 files changed, 918 insertions(+), 850 deletions(-) diff --git a/build_analytics/build_analytics/api_client.py b/build_analytics/build_analytics/api_client.py index e16c7d5..0497acb 100644 --- a/build_analytics/build_analytics/api_client.py +++ b/build_analytics/build_analytics/api_client.py @@ -158,10 +158,18 @@ class APIclient(): result: List[TestTask] = [] for task in raw_tasks: if task['alts_response']: - started_raw = task['alts_response']['stats']['started_at'] - started_at = datetime.fromisoformat(started_raw+TZ_OFFSET) - stats_raw = task['alts_response']['stats'] - steps_stats = self.__parse_test_steps_stats(stats_raw) + try: + started_raw = task['alts_response']['stats']['started_at'] + except KeyError: + started_at = None + else: + started_at = datetime.fromisoformat(started_raw+TZ_OFFSET) + try: + stats_raw = task['alts_response']['stats'] + except KeyError: + steps_stats = None + else: + steps_stats = self.__parse_test_steps_stats(stats_raw) else: started_at = None steps_stats = None @@ -176,6 +184,7 @@ class APIclient(): 'started_at': started_at, 'steps_stats': steps_stats } + result.append(TestTask(**params)) return result @@ -186,5 +195,9 @@ class APIclient(): p = stats_raw[field_name] except KeyError: continue + # there are must be a better way + for k in ['start_ts', 'finish_ts']: + if k in p: + p[k] = datetime.fromisoformat(p[k]+TZ_OFFSET) teast_steps_params[field_name] = TestStepStat(**p) return TestStepsStats(**teast_steps_params) diff --git a/build_analytics/build_analytics/db.py b/build_analytics/build_analytics/db.py index edbfe4c..a204192 100644 --- a/build_analytics/build_analytics/db.py +++ b/build_analytics/build_analytics/db.py @@ -272,7 +272,7 @@ class DB(): WHERE tt.status_id < 3 AND bt.started_at > %s; ''' cur.execute(sql, (not_before.timestamp(),)) - logging.info('raw SQL query: %s', cur.query) + logging.debug('raw SQL query: %s', cur.query) result = [int(row[0]) for row in cur.fetchall()] return result diff --git a/build_analytics/build_analytics/models/extractor_config.py b/build_analytics/build_analytics/models/extractor_config.py index 15efa3b..852855b 100644 --- a/build_analytics/build_analytics/models/extractor_config.py +++ b/build_analytics/build_analytics/models/extractor_config.py @@ -11,7 +11,7 @@ LOG_FILE_DEFAULT = '/tmp/extractor.log' API_DEFAULT = 30 SCRAPE_INTERVAL_DEFAULT = 3600 START_FROM_DEFAULT = 5808 -OLDEST_TO_UPDATE_DEFAULT = datetime.now().astimezone() - timedelta(days=3) +OLDEST_TO_UPDATE_DEFAULT = datetime.now().astimezone() - timedelta(days=7) class ExtractorConfig(BaseModel): diff --git a/build_analytics/config_default.yml b/build_analytics/config_default.yml index 7d16c97..febe104 100644 --- a/build_analytics/config_default.yml +++ b/build_analytics/config_default.yml @@ -66,6 +66,6 @@ start_from: # oldest_to_update # oldest (in days) unfinished object (build/task/step...) that we will try to update # required: false -# default: 3 -oldest_to_update_days: 3 +# default: 7 +oldest_to_update_days: 7 diff --git a/build_analytics/grafana-dashbords/Build analytics.json b/build_analytics/grafana-dashbords/Build analytics.json index 374b650..91f303a 100644 --- a/build_analytics/grafana-dashbords/Build analytics.json +++ b/build_analytics/grafana-dashbords/Build analytics.json @@ -3304,7 +3304,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -3459,7 +3460,7 @@ "type": "row" }, { - "collapsed": true, + "collapsed": false, "gridPos": { "h": 1, "w": 24, @@ -3467,462 +3468,515 @@ "y": 15 }, "id": 39, - "panels": [ + "panels": [], + "title": "Build tasks", + "type": "row" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "task_duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + }, + { + "id": "custom.width", + "value": 124 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + } + ] + }, + { + "id": "custom.width", + "value": 81 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 274 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": ".*duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build id" + }, + "properties": [ + { + "id": "custom.width", + "value": 89 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "arch" + }, + "properties": [ + { + "id": "custom.width", + "value": 104 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "finished" + }, + "properties": [ + { + "id": "custom.width", + "value": 220 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "started" + }, + "properties": [ + { + "id": "custom.width", + "value": 197 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 152 + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 37, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "task_duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ { + "cacheDurationSeconds": 300, "datasource": { "type": "postgres", "uid": "${DS_POSTGRESQL}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "displayMode": "auto", - "filterable": true, - "inspect": true - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - }, - { - "id": "custom.width", - "value": 103 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build_id" - }, - "properties": [ - { - "id": "custom.width", - "value": 88 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "custom.width", - "value": 108 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build id" - }, - "properties": [ - { - "id": "custom.width", - "value": 89 - }, - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n" - } - ] - } - ] - } - ] - }, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 16 - }, - "id": 37, - "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "task_duration" - } - ] - }, - "pluginVersion": "9.3.2", - "targets": [ + "editorMode": "code", + "fields": [ { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "hide": false, - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": " SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS task_duration\n FROM build_tasks AS bt\n JOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\n JOIN arch_enum on bt.arch_id = arch_enum.id \n WHERE $__unixEpochFilter(started_at)", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": true, - "rawQuery": true, - "rawSql": "SELECT\n bt.id, \n bt.build_id,\n SUM(bt.finished_at - bt.started_at) AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\nFROM build_tasks AS bt\nWHERE $__unixEpochFilter(started_at) \nGROUP BY bt.id;", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } + "jsonPath": "" } ], - "title": "All build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" - }, - { - "destinationType": "time", - "targetField": "finished" - } - ], - "fields": {} + "format": "table", + "hide": false, + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": " SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS task_duration\n FROM build_tasks AS bt\n JOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\n JOIN arch_enum on bt.arch_id = arch_enum.id \n WHERE $__unixEpochFilter(started_at)", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" } - }, - { - "id": "joinByField", - "options": { - "byField": "id", - "mode": "outer" + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" } - } - ], - "type": "table" + ], + "limit": 50 + }, + "urlPath": "" }, { "datasource": { "type": "postgres", "uid": "${DS_POSTGRESQL}" }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "displayMode": "auto", - "filterable": true, - "inspect": true - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] + "editorMode": "code", + "format": "table", + "hide": true, + "rawQuery": true, + "rawSql": "SELECT\n bt.id, \n bt.build_id,\n SUM(bt.finished_at - bt.started_at) AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\nFROM build_tasks AS bt\nWHERE $__unixEpochFilter(started_at) \nGROUP BY bt.id;", + "refId": "B", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" } - }, - "overrides": [ + ], + "groupBy": [ { - "matcher": { - "id": "byRegexp", - "options": "(.*duration)|(wait time)" + "property": { + "type": "string" }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.width", - "value": 70 - }, - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "arch" - }, - "properties": [ - { - "id": "custom.width", - "value": 111 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" - } - ] - }, - { - "id": "custom.width", - "value": 102 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "custom.width", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "task duration" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - } - ] + "type": "groupBy" } - ] - }, - "gridPos": { - "h": 10, - "w": 24, - "x": 0, - "y": 25 - }, - "id": 43, - "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "task duration" - } - ] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE $__unixEpochFilter(started_at) AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE $__unixEpochFilter(started_at) AND status_id = 2", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "Completed build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" - }, - { - "destinationType": "time", - "targetField": "finished" - } - ], - "fields": {} - } - } - ], - "type": "table" + ], + "limit": 50 + } } ], - "title": "Build tasks", - "type": "row" + "title": "All build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + }, + { + "id": "joinByField", + "options": { + "byField": "id", + "mode": "outer" + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "(.*duration)|(wait time)" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 70 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "arch" + }, + "properties": [ + { + "id": "custom.width", + "value": 111 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" + } + ] + }, + { + "id": "custom.width", + "value": 80 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 294 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "task duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 43, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "task duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE $__unixEpochFilter(started_at) AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE $__unixEpochFilter(started_at) AND status_id = 2", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Completed build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" } ], "refresh": false, @@ -3940,6 +3994,6 @@ "timezone": "", "title": "Build analytics", "uid": "02mg4oxVk", - "version": 63, + "version": 64, "weekStart": "" } \ No newline at end of file diff --git a/build_analytics/grafana-dashbords/Build details.json b/build_analytics/grafana-dashbords/Build details.json index 24c67db..186d752 100644 --- a/build_analytics/grafana-dashbords/Build details.json +++ b/build_analytics/grafana-dashbords/Build details.json @@ -1,8 +1,8 @@ { "__inputs": [ { - "name": "DS_POSTGRESQL", - "label": "PostgreSQL", + "name": "DS_ALBS_ANALYTICS", + "label": "albs_analytics", "description": "", "type": "datasource", "pluginId": "postgres", @@ -21,7 +21,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.3.2" + "version": "9.3.6" }, { "type": "panel", @@ -93,7 +93,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "", "fieldConfig": { @@ -201,13 +201,13 @@ } ] }, - "pluginVersion": "9.3.2", + "pluginVersion": "9.3.6", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -266,7 +266,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "", "fieldConfig": { @@ -396,7 +396,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -425,7 +425,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -454,7 +454,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -483,7 +483,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -512,7 +512,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -545,7 +545,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "", "fieldConfig": { @@ -735,7 +735,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -764,7 +764,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -793,7 +793,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -822,7 +822,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -851,7 +851,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -884,7 +884,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "Averages for build tasks with \"completed\"\nstatus", "fieldConfig": { @@ -928,13 +928,13 @@ }, "textMode": "auto" }, - "pluginVersion": "9.3.2", + "pluginVersion": "9.3.6", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -971,7 +971,7 @@ "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -1009,7 +1009,7 @@ "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -1046,7 +1046,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1079,7 +1079,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "How much time were spent in queue. \n\nStats for \"completed\" build tasks only", "fieldConfig": { @@ -1159,13 +1159,13 @@ }, "textMode": "auto" }, - "pluginVersion": "9.3.2", + "pluginVersion": "9.3.6", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -1277,7 +1277,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "", "fieldConfig": { @@ -1454,7 +1454,7 @@ "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -1497,7 +1497,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1526,7 +1526,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1555,7 +1555,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1584,7 +1584,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1613,7 +1613,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1642,7 +1642,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1671,13 +1671,13 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", "hide": false, "rawQuery": true, - "rawSql": "SELECT \n SUM(end_ts - start_ts) AS packages_processing\nFROM web_node_stats AS bs \nJOIN build_tasks \n ON bs.build_task_id = build_tasks.id\nWHERE stat_name_id = 1 AND build_tasks.build_id = $build_id ", + "rawSql": "SELECT \n SUM(end_ts - start_ts) AS packages_processing\nFROM web_node_stats AS bs \nJOIN build_tasks \n ON bs.build_task_id = build_tasks.id\nWHERE stat_name_id = 2 AND build_tasks.build_id = $build_id ", "refId": "packages_procession", "sql": { "columns": [ @@ -1704,7 +1704,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "description": "", "fieldConfig": { @@ -1752,13 +1752,13 @@ }, "showUnfilled": false }, - "pluginVersion": "9.3.2", + "pluginVersion": "9.3.6", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "fields": [ @@ -1801,7 +1801,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1830,7 +1830,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1859,7 +1859,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1888,7 +1888,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1917,7 +1917,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1946,7 +1946,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", @@ -1975,14 +1975,14 @@ { "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "editorMode": "code", "format": "table", "hide": false, "rawQuery": true, - "rawSql": "SELECT \n SUM(end_ts - start_ts) AS packages_processing\nFROM web_node_stats AS bs \nJOIN build_tasks \n ON bs.build_task_id = build_tasks.id\nWHERE stat_name_id = 1 AND build_tasks.build_id = $build_id ", - "refId": "packages_procession", + "rawSql": "SELECT \n SUM(end_ts - start_ts) AS packages_processing\nFROM web_node_stats AS bs \nJOIN build_tasks \n ON bs.build_task_id = build_tasks.id\nWHERE stat_name_id = 2 AND build_tasks.build_id = $build_id ", + "refId": "packages_processing", "sql": { "columns": [ { @@ -2006,7 +2006,7 @@ "type": "bargauge" }, { - "collapsed": true, + "collapsed": false, "gridPos": { "h": 1, "w": 24, @@ -2014,361 +2014,362 @@ "y": 21 }, "id": 18, - "panels": [ - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "center", - "displayMode": "auto", - "filterable": true, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 9, - "w": 24, - "x": 0, - "y": 3 - }, - "id": 2, - "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "duration" - } - ] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS duration \nFROM build_tasks AS bt\nJOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\nJOIN arch_enum on bt.arch_id = arch_enum.id\nWHERE bt.build_id = $build_id;", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "All build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" - }, - { - "destinationType": "time", - "targetField": "finished" - } - ], - "fields": {} - } - } - ], - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "displayMode": "auto", - "filterable": true, - "inspect": true - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "(.*duration)|(wait time)" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.width", - "value": 70 - }, - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "arch" - }, - "properties": [ - { - "id": "custom.width", - "value": 111 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" - } - ] - }, - { - "id": "custom.width", - "value": 102 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "custom.width", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "task duration" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 12 - }, - "id": 25, - "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "task duration" - } - ] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE bt.build_id = $build_id AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE bt.build_id = $build_id AND status_id = 2", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "Completed build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" - }, - { - "destinationType": "time", - "targetField": "finished" - } - ], - "fields": {} - } - } - ], - "type": "table" - } - ], + "panels": [], "title": "Build tasks", "type": "row" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_ALBS_ANALYTICS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "center", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": false, + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 2, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "duration" + } + ] + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_ALBS_ANALYTICS}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS duration \nFROM build_tasks AS bt\nJOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\nJOIN arch_enum on bt.arch_id = arch_enum.id\nWHERE bt.build_id = $build_id;", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "All build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_ALBS_ANALYTICS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "displayMode": "auto", + "filterable": true, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "(.*duration)|(wait time)" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 70 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "arch" + }, + "properties": [ + { + "id": "custom.width", + "value": 111 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" + } + ] + }, + { + "id": "custom.width", + "value": 102 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 75 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "task duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 25, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "task duration" + } + ] + }, + "pluginVersion": "9.3.6", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_ALBS_ANALYTICS}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE bt.build_id = $build_id AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE bt.build_id = $build_id AND status_id = 2", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Completed build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" } ], "refresh": false, @@ -2381,7 +2382,7 @@ "current": {}, "datasource": { "type": "postgres", - "uid": "${DS_POSTGRESQL}" + "uid": "${DS_ALBS_ANALYTICS}" }, "definition": "SELECT id\nFROM builds\nORDER BY id DESC", "hide": 0, @@ -2406,6 +2407,6 @@ "timezone": "", "title": "Build details", "uid": "dmVtrz-4k", - "version": 21, + "version": 5, "weekStart": "" } \ No newline at end of file From 5b1e296fbc6b2557fc02e1da18f853aa19eaf22e Mon Sep 17 00:00:00 2001 From: Kirill Zhukov Date: Wed, 22 Mar 2023 11:30:12 +0100 Subject: [PATCH 7/7] ALBS-1043: - db,extractor: added check for cases when build 'moved' between pages - grafana: new dashboard Test tasks.json, added test info to other dashboars --- build_analytics/build_analytics/db.py | 11 + .../build_analytics/extractor/extractor.py | 4 + .../grafana-dashbords/Build analytics.json | 5470 ++++++++++------- .../grafana-dashbords/Build details.json | 1429 ++++- .../grafana-dashbords/Build task details.json | 602 +- .../grafana-dashbords/Test task details.json | 516 ++ 6 files changed, 5408 insertions(+), 2624 deletions(-) create mode 100644 build_analytics/grafana-dashbords/Test task details.json diff --git a/build_analytics/build_analytics/db.py b/build_analytics/build_analytics/db.py index a204192..0dbd7ed 100644 --- a/build_analytics/build_analytics/db.py +++ b/build_analytics/build_analytics/db.py @@ -26,6 +26,17 @@ class DB(): def __del__(self): self.close_conn() + def build_exists(self, build_id: int) -> bool: + sql = f''' + SELECT COUNT(id) + FROM builds + WHERE id = %s; + ''' + cur = self.__conn.cursor() + cur.execute(sql, (build_id,)) + val = int(cur.fetchone()[0]) + return val == 1 + def insert_build(self, build: BuildDB): sql = ''' INSERT INTO builds(id, url, created_at, finished_at) diff --git a/build_analytics/build_analytics/extractor/extractor.py b/build_analytics/build_analytics/extractor/extractor.py index 45770bc..4789b35 100644 --- a/build_analytics/build_analytics/extractor/extractor.py +++ b/build_analytics/build_analytics/extractor/extractor.py @@ -34,6 +34,10 @@ class Extractor: stop = True break + # some builds could move from one page to another + if self.db.build_exists(build_id=build.id): + continue + # inserting build build tasks and build tasks statistics logging.info('inserting %s', build.id) try: diff --git a/build_analytics/grafana-dashbords/Build analytics.json b/build_analytics/grafana-dashbords/Build analytics.json index 91f303a..4c99dac 100644 --- a/build_analytics/grafana-dashbords/Build analytics.json +++ b/build_analytics/grafana-dashbords/Build analytics.json @@ -87,7 +87,7 @@ }, "id": 17, "panels": [], - "title": "Summary", + "title": "Builds", "type": "row" }, { @@ -1427,7 +1427,7 @@ "type": "stat" }, { - "collapsed": true, + "collapsed": false, "gridPos": { "h": 1, "w": 24, @@ -1435,1850 +1435,2331 @@ "y": 13 }, "id": 26, - "panels": [ - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "fixedColor": "#61a69d", - "mode": "fixed" - }, - "custom": { - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - } - }, - "mappings": [], - "unit": "s" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build_binaries" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "purple", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "upload" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "blue", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "packages_processing" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "green", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build_srpm" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "semi-dark-green", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "notarize_artifacts" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "yellow", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "logs_processing" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "orange", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "source_authenticate" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "red", - "mode": "fixed" - } - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "git_checkout" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "light-red", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 8, - "x": 0, - "y": 14 - }, - "id": 33, - "options": { - "legend": { - "displayMode": "table", - "placement": "right", - "showLegend": true, - "values": [ - "percent" - ] - }, - "pieType": "pie", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "tooltip": { - "mode": "single", - "sort": "none" - } - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as upload\nFROM build_node_stats \nWHERE stat_name_id = 0 AND $__unixEpochFilter(start_ts);", - "refId": "upload", - "sql": { - "columns": [ - { - "parameters": [ - { - "name": "start_ts", - "type": "functionParameter" - } - ], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "table": "build_node_stats", - "urlPath": "" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as build_srpm\nFROM build_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as git_checkout\nFROM build_node_stats \nWHERE stat_name_id = 3 AND $__unixEpochFilter(start_ts);", - "refId": "git_checkout", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as build_binaries\nFROM build_node_stats \nWHERE stat_name_id = 4 AND $__unixEpochFilter(start_ts);", - "refId": "build_binaries", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as notarize_artifacts\nFROM build_node_stats \nWHERE stat_name_id = 7 AND $__unixEpochFilter(start_ts)", - "refId": "cas_notarize_artifacts", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as source_authenticate\nFROM build_node_stats \nWHERE stat_name_id = 8 AND $__unixEpochFilter(start_ts);", - "refId": "cas_source_authenticate", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as logs_processing\nFROM web_node_stats \nWHERE stat_name_id = 1 AND $__unixEpochFilter(start_ts);", - "refId": "logs_processing", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as packages_processing\nFROM web_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", - "refId": "packages_procession", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "Duration (%)", - "type": "piechart" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "fixedColor": "#61a69d", - "mode": "fixed" - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - }, - "unit": "s" - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "wait_time" - }, - "properties": [ - { - "id": "color", - "value": { - "fixedColor": "red", - "mode": "fixed" - } - } - ] - } - ] - }, - "gridPos": { - "h": 8, - "w": 16, - "x": 8, - "y": 14 - }, - "id": 20, - "options": { - "displayMode": "basic", - "minVizHeight": 10, - "minVizWidth": 0, - "orientation": "vertical", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "showUnfilled": false - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as git_checkout\nFROM build_node_stats \nWHERE stat_name_id = 3 AND $__unixEpochFilter(start_ts);", - "refId": "git_checkout", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as source_authenticate\nFROM build_node_stats \nWHERE stat_name_id = 8 AND $__unixEpochFilter(start_ts);", - "refId": "cas_source_authenticate", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as build_srpm\nFROM build_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as build_binaries\nFROM build_node_stats \nWHERE stat_name_id = 4 AND $__unixEpochFilter(start_ts);", - "refId": "build_binaries", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as notarize_artifacts\nFROM build_node_stats \nWHERE stat_name_id = 7 AND $__unixEpochFilter(start_ts)", - "refId": "cas_notarize_artifacts", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as logs_processing\nFROM web_node_stats \nWHERE stat_name_id = 1 AND $__unixEpochFilter(start_ts);", - "refId": "logs_processing", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "format": "table", - "hide": false, - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as packages_processing\nFROM web_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", - "refId": "packages_processing", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - }, - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT SUM(end_ts - start_ts) as upload\nFROM build_node_stats \nWHERE stat_name_id = 0 AND $__unixEpochFilter(start_ts);", - "refId": "upload", - "sql": { - "columns": [ - { - "parameters": [ - { - "name": "start_ts", - "type": "functionParameter" - } - ], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "table": "build_node_stats", - "urlPath": "" - } - ], - "title": "Duration (absolute)", - "type": "bargauge" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest git_checkout step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build_task" - }, - "properties": [ - { - "id": "custom.width", - "value": 82 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 87 - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 0, - "y": 22 - }, - "id": 28, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 3 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "git_checkout", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest source_authenticate step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 78 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 3, - "y": 22 - }, - "id": 31, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 8 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "source_authenticate", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest build_binaries step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 81 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 6, - "y": 22 - }, - "id": 29, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 4 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "build_binaries", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest build_srpm step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 81 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 82 - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 9, - "y": 22 - }, - "id": 27, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "build_srpm", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest notarize_artifacts step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 78 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 12, - "y": 22 - }, - "id": 30, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 7 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "notarize_artifacts", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest logs_processing step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 78 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 15, - "y": 22 - }, - "id": 32, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM web_node_stats\nWHERE stat_name_id = 1 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "logs_processing", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build tasks with longest packages_processing step", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 78 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 18, - "y": 22 - }, - "id": 34, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM web_node_stats\nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "packages_processing", - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "Top 5 build_tasks with longest upload", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 79 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build task" - }, - "properties": [ - { - "id": "custom.width", - "value": 88 - } - ] - } - ] - }, - "gridPos": { - "h": 7, - "w": 3, - "x": 21, - "y": 22 - }, - "id": 35, - "options": { - "footer": { - "enablePagination": false, - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT build_task_id AS \"build task\" , (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 0 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", - "refId": "build_srpm", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "upload", - "type": "table" - } - ], + "panels": [], "title": "Build Steps", "type": "row" }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "#61a69d", + "mode": "fixed" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build_binaries" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "upload" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "packages_processing" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build_srpm" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "semi-dark-green", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "notarize_artifacts" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "yellow", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "logs_processing" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "orange", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "source_authenticate" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "git_checkout" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 14 + }, + "id": 33, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "percent" + ] + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as upload\nFROM build_node_stats \nWHERE stat_name_id = 0 AND $__unixEpochFilter(start_ts);", + "refId": "upload", + "sql": { + "columns": [ + { + "parameters": [ + { + "name": "start_ts", + "type": "functionParameter" + } + ], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "table": "build_node_stats", + "urlPath": "" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as build_srpm\nFROM build_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as git_checkout\nFROM build_node_stats \nWHERE stat_name_id = 3 AND $__unixEpochFilter(start_ts);", + "refId": "git_checkout", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as build_binaries\nFROM build_node_stats \nWHERE stat_name_id = 4 AND $__unixEpochFilter(start_ts);", + "refId": "build_binaries", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as notarize_artifacts\nFROM build_node_stats \nWHERE stat_name_id = 7 AND $__unixEpochFilter(start_ts)", + "refId": "cas_notarize_artifacts", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as source_authenticate\nFROM build_node_stats \nWHERE stat_name_id = 8 AND $__unixEpochFilter(start_ts);", + "refId": "cas_source_authenticate", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as logs_processing\nFROM web_node_stats \nWHERE stat_name_id = 1 AND $__unixEpochFilter(start_ts);", + "refId": "logs_processing", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as packages_processing\nFROM web_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", + "refId": "packages_procession", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Duration (%)", + "type": "piechart" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "#61a69d", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "wait_time" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 16, + "x": 8, + "y": 14 + }, + "id": 20, + "options": { + "displayMode": "basic", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "vertical", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": false + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as git_checkout\nFROM build_node_stats \nWHERE stat_name_id = 3 AND $__unixEpochFilter(start_ts);", + "refId": "git_checkout", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as source_authenticate\nFROM build_node_stats \nWHERE stat_name_id = 8 AND $__unixEpochFilter(start_ts);", + "refId": "cas_source_authenticate", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as build_srpm\nFROM build_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as build_binaries\nFROM build_node_stats \nWHERE stat_name_id = 4 AND $__unixEpochFilter(start_ts);", + "refId": "build_binaries", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as notarize_artifacts\nFROM build_node_stats \nWHERE stat_name_id = 7 AND $__unixEpochFilter(start_ts)", + "refId": "cas_notarize_artifacts", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as logs_processing\nFROM web_node_stats \nWHERE stat_name_id = 1 AND $__unixEpochFilter(start_ts);", + "refId": "logs_processing", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": false, + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as packages_processing\nFROM web_node_stats \nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts);", + "refId": "packages_processing", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + }, + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT SUM(end_ts - start_ts) as upload\nFROM build_node_stats \nWHERE stat_name_id = 0 AND $__unixEpochFilter(start_ts);", + "refId": "upload", + "sql": { + "columns": [ + { + "parameters": [ + { + "name": "start_ts", + "type": "functionParameter" + } + ], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "table": "build_node_stats", + "urlPath": "" + } + ], + "title": "Duration (absolute)", + "type": "bargauge" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest git_checkout step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build_task" + }, + "properties": [ + { + "id": "custom.width", + "value": 82 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 87 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 0, + "y": 22 + }, + "id": 28, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 3 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "git_checkout", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest source_authenticate step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 78 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 3, + "y": 22 + }, + "id": 31, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 8 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "source_authenticate", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest build_binaries step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 81 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 6, + "y": 22 + }, + "id": 29, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 4 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "build_binaries", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest build_srpm step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 81 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 82 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 9, + "y": 22 + }, + "id": 27, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "build_srpm", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest notarize_artifacts step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 78 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 12, + "y": 22 + }, + "id": 30, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 7 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "notarize_artifacts", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest logs_processing step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 78 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 15, + "y": 22 + }, + "id": 32, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM web_node_stats\nWHERE stat_name_id = 1 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "logs_processing", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build tasks with longest packages_processing step", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 78 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 18, + "y": 22 + }, + "id": 34, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\", (end_ts - start_ts) as duration\nFROM web_node_stats\nWHERE stat_name_id = 2 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "packages_processing", + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "Top 5 build_tasks with longest upload", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 79 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 21, + "y": 22 + }, + "id": 35, + "options": { + "footer": { + "enablePagination": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT build_task_id AS \"build task\" , (end_ts - start_ts) as duration\nFROM build_node_stats\nWHERE stat_name_id = 0 AND $__unixEpochFilter(start_ts)\nORDER BY duration DESC\nLIMIT 5;", + "refId": "build_srpm", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "upload", + "type": "table" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 49, + "panels": [], + "title": "Tests", + "type": "row" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [] + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 13, + "x": 0, + "y": 30 + }, + "id": 45, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT \n COUNT(tt.id),\n enum.value AS status\nFROM test_tasks AS tt\nINNER JOIN test_tasks_status_enum AS enum\nON tt.status_id = enum.id\nWHERE $__unixEpochFilter(started_at)\nGROUP BY (status);\n", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Tests count (group by status)", + "transformations": [ + { + "id": "rowsToFields", + "options": {} + } + ], + "type": "piechart" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 11, + "x": 13, + "y": 30 + }, + "id": 56, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n MAX(t.duration) AS \"MAX\",\n MIN(t.duration) AS \"MIN\",\n AVG(t.duration) AS \"AVERAGE\",\n PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY t.duration) as \"MEDIAN\",\n PERCENTILE_CONT(0.95) WITHIN GROUP(ORDER BY t.duration) as \"95TH PERCENTILE\"\nFROM\n (SELECT \n tt.started_at * 1000 AS \"started at\",\n tf.finished_at * 1000 AS \"finished at\", \n tf.finished_at - tt.started_at AS duration\n FROM test_tasks AS tt\n INNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\n INNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\n INNER JOIN \n (SELECT \n tss.test_task_id, \n MAX(tss.finish_ts) AS finished_at \n FROM test_steps_stats AS tss\n INNER JOIN test_tasks AS tt\n ON tss.test_task_id = tt.id\n WHERE $__unixEpochFilter(tt.started_at)\n GROUP BY tss.test_task_id) AS tf\n ON tf.test_task_id = tt.id\n WHERE $__unixEpochFilter(tt.started_at)\n ) AS t;", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Tests duration", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 58, + "options": { + "displayMode": "basic", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "vertical", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": false + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n enum.value AS \"step name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nWHERE $__unixEpochFilter(tt.started_at)\nGROUP BY (enum.value); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test duration (group by test step)", + "transformations": [ + { + "id": "rowsToFields", + "options": {} + } + ], + "type": "bargauge" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 42 + }, + "id": 59, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT \n aenum.value AS arch,\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN build_tasks as bt\n ON tt.build_task_id = bt.id\nINNER JOIN arch_enum as aenum\n ON bt.arch_id = aenum.id\nWHERE $__unixEpochFilter(tt.started_at)\nGROUP BY (aenum.value); \n", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Tests duration (group by arch)", + "transformations": [ + { + "id": "rowsToFields", + "options": { + "mappings": [] + } + } + ], + "type": "piechart" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 16, + "x": 8, + "y": 42 + }, + "id": 47, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT \n tt.package_fullname AS \"package name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nWHERE $__unixEpochFilter(started_at)\nGROUP BY (tt.package_fullname); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Tests duration (group by package)", + "transformations": [ + { + "id": "rowsToFields", + "options": { + "mappings": [] + } + } + ], + "type": "piechart" + }, { "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 14 + "y": 49 }, "id": 24, "panels": [ @@ -3304,8 +3785,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -3374,7 +3854,7 @@ "h": 15, "w": 24, "x": 0, - "y": 15 + "y": 62 }, "id": 2, "options": { @@ -3456,527 +3936,893 @@ "type": "table" } ], - "title": "Builds", + "title": "Details: builds", "type": "row" }, { - "collapsed": false, + "collapsed": true, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 15 + "y": 50 }, "id": 39, - "panels": [], - "title": "Build tasks", + "panels": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "task_duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + }, + { + "id": "custom.width", + "value": 124 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + } + ] + }, + { + "id": "custom.width", + "value": 81 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build_id" + }, + "properties": [ + { + "id": "custom.width", + "value": 88 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 274 + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": ".*duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build id" + }, + "properties": [ + { + "id": "custom.width", + "value": 89 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "arch" + }, + "properties": [ + { + "id": "custom.width", + "value": 104 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "finished" + }, + "properties": [ + { + "id": "custom.width", + "value": 220 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "started" + }, + "properties": [ + { + "id": "custom.width", + "value": 197 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 152 + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 61 + }, + "id": 37, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "task_duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "hide": false, + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": " SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS task_duration\n FROM build_tasks AS bt\n JOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\n JOIN arch_enum on bt.arch_id = arch_enum.id \n WHERE $__unixEpochFilter(started_at)", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "hide": true, + "rawQuery": true, + "rawSql": "SELECT\n bt.id, \n bt.build_id,\n SUM(bt.finished_at - bt.started_at) AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\nFROM build_tasks AS bt\nWHERE $__unixEpochFilter(started_at) \nGROUP BY bt.id;", + "refId": "B", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "All build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + }, + { + "id": "joinByField", + "options": { + "byField": "id", + "mode": "outer" + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "(.*duration)|(wait time)" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 70 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "arch" + }, + "properties": [ + { + "id": "custom.width", + "value": 111 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" + } + ] + }, + { + "id": "custom.width", + "value": 80 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 294 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "task duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + } + ] + } + ] + }, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 70 + }, + "id": 43, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "task duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE $__unixEpochFilter(started_at) AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE $__unixEpochFilter(started_at) AND status_id = 2", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Completed build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + } + ], + "title": "Details: build tasks", "type": "row" }, { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "filterable": true, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "task_duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - }, - { - "id": "custom.width", - "value": 124 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" - } - ] - }, - { - "id": "custom.width", - "value": 81 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build_id" - }, - "properties": [ - { - "id": "custom.width", - "value": 88 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "custom.width", - "value": 274 - } - ] - }, - { - "matcher": { - "id": "byRegexp", - "options": ".*duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build id" - }, - "properties": [ - { - "id": "custom.width", - "value": 89 - }, - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "arch" - }, - "properties": [ - { - "id": "custom.width", - "value": 104 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "finished" - }, - "properties": [ - { - "id": "custom.width", - "value": 220 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "started" - }, - "properties": [ - { - "id": "custom.width", - "value": 197 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "status" - }, - "properties": [ - { - "id": "custom.width", - "value": 152 - } - ] - } - ] - }, + "collapsed": true, "gridPos": { - "h": 9, + "h": 1, "w": 24, "x": 0, - "y": 16 + "y": 51 }, - "id": 37, - "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" - ], - "show": false - }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "task_duration" - } - ] - }, - "pluginVersion": "9.3.2", - "targets": [ - { - "cacheDurationSeconds": 300, - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "hide": false, - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": " SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS task_duration\n FROM build_tasks AS bt\n JOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\n JOIN arch_enum on bt.arch_id = arch_enum.id \n WHERE $__unixEpochFilter(started_at)", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - }, + "id": 53, + "panels": [ { "datasource": { "type": "postgres", "uid": "${DS_POSTGRESQL}" }, - "editorMode": "code", - "format": "table", - "hide": true, - "rawQuery": true, - "rawSql": "SELECT\n bt.id, \n bt.build_id,\n SUM(bt.finished_at - bt.started_at) AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\nFROM build_tasks AS bt\nWHERE $__unixEpochFilter(started_at) \nGROUP BY bt.id;", - "refId": "B", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" - } - ], - "groupBy": [ - { - "property": { - "type": "string" - }, - "type": "groupBy" - } - ], - "limit": 50 - } - } - ], - "title": "All build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" }, - { - "destinationType": "time", - "targetField": "finished" - } - ], - "fields": {} - } - }, - { - "id": "joinByField", - "options": { - "byField": "id", - "mode": "outer" - } - } - ], - "type": "table" - }, - { - "datasource": { - "type": "postgres", - "uid": "${DS_POSTGRESQL}" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "custom": { - "align": "left", - "displayMode": "auto", - "filterable": true, - "inspect": false - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "(.*duration)|(wait time)" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.width", - "value": 70 - }, - { - "id": "links", - "value": [ + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package" + }, + "properties": [ + { + "id": "custom.width", + "value": 322 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "revision" + }, + "properties": [ + { + "id": "custom.width", + "value": 62 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] } ] } ] }, - { - "matcher": { - "id": "byName", - "options": "arch" + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 62 + }, + "id": 54, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false }, - "properties": [ + "showHeader": true, + "sortBy": [ { - "id": "custom.width", - "value": 111 + "desc": false, + "displayName": "duration" } ] }, - { - "matcher": { - "id": "byName", - "options": "build id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" - } - ] + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" }, - { - "id": "custom.width", - "value": 80 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "custom.width", - "value": 294 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "task duration" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - } - ] - } - ] - }, - "gridPos": { - "h": 10, - "w": 24, - "x": 0, - "y": 25 - }, - "id": 43, - "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n DISTINCT tt.id,\n tt.build_task_id as \"build task id\",\n tt.package_fullname AS package,\n tt.revision,\n enum.value AS \"status\",\n tt.started_at * 1000 AS \"started at\",\n tf.finished_at * 1000 AS \"finished at\", \n tf.finished_at - tt.started_at AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\nINNER JOIN \n (SELECT \n tss.test_task_id, \n MAX(tss.finish_ts) AS finished_at \n FROM test_steps_stats AS tss\n INNER JOIN test_tasks AS tt\n ON tss.test_task_id = tt.id\n WHERE $__unixEpochFilter(tt.started_at)\n GROUP BY tss.test_task_id) AS tf\n ON tf.test_task_id = tt.id\nWHERE $__unixEpochFilter(tt.started_at);\n", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } ], - "show": false + "title": "Test tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started at" + }, + { + "destinationType": "time", + "targetField": "finished at" + } + ], + "fields": {} + } + } + ], + "type": "table" }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "task duration" - } - ] - }, - "pluginVersion": "9.3.2", - "targets": [ { - "cacheDurationSeconds": 300, "datasource": { "type": "postgres", "uid": "${DS_POSTGRESQL}" }, - "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], - "format": "table", - "method": "GET", - "queryParams": "", - "rawQuery": true, - "rawSql": "SELECT\n bt.id,\n bt.build_id AS \"build id\",\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE $__unixEpochFilter(started_at) AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE $__unixEpochFilter(started_at) AND status_id = 2", - "refId": "A", - "sql": { - "columns": [ - { - "parameters": [], - "type": "function" + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] } - ], - "groupBy": [ + }, + "overrides": [ { - "property": { - "type": "string" + "matcher": { + "id": "byName", + "options": "test task id" }, - "type": "groupBy" - } - ], - "limit": 50 - }, - "urlPath": "" - } - ], - "title": "Completed build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" + "properties": [ + { + "id": "custom.width", + "value": 159 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] }, { - "destinationType": "time", - "targetField": "finished" + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package name" + }, + "properties": [ + { + "id": "custom.width", + "value": 408 + } + ] } - ], - "fields": {} - } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 69 + }, + "id": 61, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "finished" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n tss.test_task_id AS \"test task id\", \n tt.package_fullname AS \"package name\",\n enum.value AS \"step name\",\n tss.start_ts * 1000 AS started,\n tss.finish_ts * 1000 AS finished,\n tss.finish_ts - tss.start_ts AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nWHERE $__unixEpochFilter(tt.started_at);\n", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test steps", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" } ], - "type": "table" + "title": "Details: tests", + "type": "row" } ], "refresh": false, @@ -3994,6 +4840,6 @@ "timezone": "", "title": "Build analytics", "uid": "02mg4oxVk", - "version": 64, + "version": 84, "weekStart": "" } \ No newline at end of file diff --git a/build_analytics/grafana-dashbords/Build details.json b/build_analytics/grafana-dashbords/Build details.json index 186d752..6df780c 100644 --- a/build_analytics/grafana-dashbords/Build details.json +++ b/build_analytics/grafana-dashbords/Build details.json @@ -1,8 +1,8 @@ { "__inputs": [ { - "name": "DS_ALBS_ANALYTICS", - "label": "albs_analytics", + "name": "DS_POSTGRESQL", + "label": "PostgreSQL", "description": "", "type": "datasource", "pluginId": "postgres", @@ -21,7 +21,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.3.6" + "version": "9.3.2" }, { "type": "panel", @@ -87,13 +87,13 @@ }, "id": 16, "panels": [], - "title": "Summary", + "title": "Builds", "type": "row" }, { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "", "fieldConfig": { @@ -201,13 +201,13 @@ } ] }, - "pluginVersion": "9.3.6", + "pluginVersion": "9.3.2", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -266,7 +266,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "", "fieldConfig": { @@ -396,7 +396,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -425,7 +425,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -454,7 +454,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -483,7 +483,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -512,7 +512,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -545,7 +545,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "", "fieldConfig": { @@ -735,7 +735,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -764,7 +764,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -793,7 +793,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -822,7 +822,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -851,7 +851,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -884,7 +884,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "Averages for build tasks with \"completed\"\nstatus", "fieldConfig": { @@ -928,13 +928,13 @@ }, "textMode": "auto" }, - "pluginVersion": "9.3.6", + "pluginVersion": "9.3.2", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -971,7 +971,7 @@ "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -1009,7 +1009,7 @@ "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -1046,7 +1046,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1079,7 +1079,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "How much time were spent in queue. \n\nStats for \"completed\" build tasks only", "fieldConfig": { @@ -1159,13 +1159,13 @@ }, "textMode": "auto" }, - "pluginVersion": "9.3.6", + "pluginVersion": "9.3.2", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -1261,23 +1261,10 @@ ], "type": "stat" }, - { - "collapsed": false, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 12 - }, - "id": 23, - "panels": [], - "title": "Build steps", - "type": "row" - }, { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "", "fieldConfig": { @@ -1423,7 +1410,7 @@ "h": 8, "w": 8, "x": 0, - "y": 13 + "y": 12 }, "id": 20, "options": { @@ -1454,7 +1441,7 @@ "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -1497,7 +1484,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1526,7 +1513,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1555,7 +1542,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1584,7 +1571,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1613,7 +1600,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1642,7 +1629,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1671,7 +1658,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1704,7 +1691,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "", "fieldConfig": { @@ -1735,7 +1722,7 @@ "h": 8, "w": 16, "x": 8, - "y": 13 + "y": 12 }, "id": 21, "options": { @@ -1752,13 +1739,13 @@ }, "showUnfilled": false }, - "pluginVersion": "9.3.6", + "pluginVersion": "9.3.2", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -1801,7 +1788,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1830,7 +1817,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1859,7 +1846,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1888,7 +1875,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1917,7 +1904,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1946,7 +1933,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -1975,7 +1962,7 @@ { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "format": "table", @@ -2011,116 +1998,76 @@ "h": 1, "w": 24, "x": 0, - "y": 21 + "y": 20 }, - "id": 18, + "id": 27, "panels": [], - "title": "Build tasks", + "title": "Tests", "type": "row" }, { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "description": "", "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" + "fixedColor": "blue", + "mode": "palette-classic" }, "custom": { - "align": "center", - "displayMode": "auto", - "filterable": true, - "inspect": false + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - } - ] - } + "mappings": [] }, - "overrides": [ - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "targetBlank": false, - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "duration" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - } - ] + "overrides": [] }, "gridPos": { - "h": 9, - "w": 24, + "h": 6, + "w": 13, "x": 0, - "y": 22 + "y": 21 }, - "id": 2, + "id": 29, "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" - ], - "show": false + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "duration" - } - ] + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } }, - "pluginVersion": "9.3.6", + "pluginVersion": "9.3.2", "targets": [ { - "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", - "fields": [ - { - "jsonPath": "" - } - ], "format": "table", - "method": "GET", - "queryParams": "", "rawQuery": true, - "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS duration \nFROM build_tasks AS bt\nJOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\nJOIN arch_enum on bt.arch_id = arch_enum.id\nWHERE bt.build_id = $build_id;", + "rawSql": "SELECT \n COUNT(tt.id),\n enum.value AS status\nFROM test_tasks AS tt\nINNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\nINNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\nINNER JOIN builds AS b\n ON bt.build_id = b.id\nWHERE b.id = $build_id\nGROUP BY (status);\n", "refId": "A", "sql": { "columns": [ @@ -2138,46 +2085,28 @@ } ], "limit": 50 - }, - "urlPath": "" - } - ], - "title": "All build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ - { - "destinationType": "time", - "targetField": "started" - }, - { - "destinationType": "time", - "targetField": "finished" - } - ], - "fields": {} } } ], - "type": "table" + "title": "Tests count (group by status)", + "transformations": [ + { + "id": "rowsToFields", + "options": {} + } + ], + "type": "piechart" }, { "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "fieldConfig": { "defaults": { "color": { - "mode": "thresholds" - }, - "custom": { - "align": "auto", - "displayMode": "auto", - "filterable": true, - "inspect": true + "fixedColor": "blue", + "mode": "fixed" }, "mappings": [], "thresholds": { @@ -2192,131 +2121,39 @@ "value": 80 } ] - } + }, + "unit": "s" }, - "overrides": [ - { - "matcher": { - "id": "byRegexp", - "options": "(.*duration)|(wait time)" - }, - "properties": [ - { - "id": "unit", - "value": "s" - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "id" - }, - "properties": [ - { - "id": "custom.width", - "value": 70 - }, - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" - } - ] - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "arch" - }, - "properties": [ - { - "id": "custom.width", - "value": 111 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "build id" - }, - "properties": [ - { - "id": "links", - "value": [ - { - "title": "", - "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" - } - ] - }, - { - "id": "custom.width", - "value": 102 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "name" - }, - "properties": [ - { - "id": "custom.width", - "value": 75 - } - ] - }, - { - "matcher": { - "id": "byName", - "options": "task duration" - }, - "properties": [ - { - "id": "custom.width", - "value": 100 - } - ] - } - ] + "overrides": [] }, "gridPos": { - "h": 7, - "w": 24, - "x": 0, - "y": 31 + "h": 6, + "w": 11, + "x": 13, + "y": 21 }, - "id": 25, + "id": 31, "options": { - "footer": { - "fields": "", - "reducer": [ - "sum" + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" ], - "show": false + "fields": "", + "values": false }, - "showHeader": true, - "sortBy": [ - { - "desc": true, - "displayName": "task duration" - } - ] + "textMode": "auto" }, - "pluginVersion": "9.3.6", + "pluginVersion": "9.3.2", "targets": [ { "cacheDurationSeconds": 300, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "editorMode": "code", "fields": [ @@ -2328,7 +2165,7 @@ "method": "GET", "queryParams": "", "rawQuery": true, - "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE bt.build_id = $build_id AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE bt.build_id = $build_id AND status_id = 2", + "rawSql": "SELECT \n MAX(t.duration) AS \"MAX\",\n MIN(t.duration) AS \"MIN\",\n AVG(t.duration) AS \"AVERAGE\",\n PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY t.duration) as \"MEDIAN\",\n PERCENTILE_CONT(0.95) WITHIN GROUP(ORDER BY t.duration) as \"95TH PERCENTILE\"\nFROM\n (SELECT \n tt.started_at * 1000 AS \"started at\",\n tf.finished_at * 1000 AS \"finished at\", \n tf.finished_at - tt.started_at AS duration\n FROM test_tasks AS tt\n INNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\n INNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\n INNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\n INNER JOIN builds AS b\n ON bt.build_id = b.id\n INNER JOIN \n (SELECT \n tss.test_task_id, \n MAX(tss.finish_ts) AS finished_at \n FROM test_steps_stats AS tss\n INNER JOIN test_tasks AS tt\n ON tss.test_task_id = tt.id\n INNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\n INNER JOIN builds AS b\n ON bt.build_id = b.id\n WHERE b.id = $build_id\n GROUP BY tss.test_task_id) AS tf\n ON tf.test_task_id = tt.id\n WHERE b.id = $build_id\n ) AS t;", "refId": "A", "sql": { "columns": [ @@ -2350,26 +2187,1024 @@ "urlPath": "" } ], - "title": "Completed build tasks", - "transformations": [ - { - "id": "convertFieldType", - "options": { - "conversions": [ + "title": "Tests duration", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ { - "destinationType": "time", - "targetField": "started" + "color": "green" }, { - "destinationType": "time", - "targetField": "finished" + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 33, + "options": { + "displayMode": "basic", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "vertical", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": false + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n enum.value AS \"step name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nINNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\nINNER JOIN builds AS b\n ON bt.build_id = b.id\nWHERE b.id = $build_id\nGROUP BY (enum.value); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" } ], - "fields": {} + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test duration (group by test step)", + "transformations": [ + { + "id": "rowsToFields", + "options": {} + } + ], + "type": "bargauge" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 33 + }, + "id": 35, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT \n aenum.value AS arch,\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN build_tasks as bt\n ON tt.build_task_id = bt.id\nINNER JOIN arch_enum as aenum\n ON bt.arch_id = aenum.id\nINNER JOIN builds AS b\n ON bt.build_id = b.id\nWHERE b.id = $build_id\nGROUP BY (aenum.value); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 } } ], - "type": "table" + "title": "Tests duration (group by arch)", + "transformations": [ + { + "id": "rowsToFields", + "options": { + "mappings": [] + } + } + ], + "type": "piechart" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 16, + "x": 8, + "y": 33 + }, + "id": 37, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT \n tt.package_fullname AS \"package name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\nINNER JOIN builds AS b\n ON bt.build_id = b.id\nWHERE b.id = $build_id\nGROUP BY (tt.package_fullname); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Tests duration (group by package)", + "transformations": [ + { + "id": "rowsToFields", + "options": { + "mappings": [] + } + } + ], + "type": "piechart" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 39 + }, + "id": 18, + "panels": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "center", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "targetBlank": false, + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 2, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n status_enum.value AS status,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n bt.finished_at - bt.started_at AS duration \nFROM build_tasks AS bt\nJOIN build_task_status_enum AS status_enum ON bt.status_id = status_enum.id\nJOIN arch_enum on bt.arch_id = arch_enum.id\nWHERE bt.build_id = $build_id;", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "All build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "displayMode": "auto", + "filterable": true, + "inspect": true + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "(.*duration)|(wait time)" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 70 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}\n\n" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "arch" + }, + "properties": [ + { + "id": "custom.width", + "value": 111 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/dmVtrz-4k/build-details?orgId=1&var-build_id=${__value.raw}\n\n\n" + } + ] + }, + { + "id": "custom.width", + "value": 102 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "name" + }, + "properties": [ + { + "id": "custom.width", + "value": 75 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "task duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 25, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "task duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT\n bt.id,\n bt.name,\n arch_enum.value AS arch,\n bt.started_at * 1000 AS started,\n bt.finished_at * 1000 AS finished,\n task_duration AS \"task duration\",\n web_node_duration AS \"web node duration\",\n build_node_duration AS \"build node duration\",\n task_duration - web_node_duration - build_node_duration as \"wait time\"\n FROM build_tasks AS bt\n JOIN arch_enum on bt.arch_id = arch_enum.id \n LEFT JOIN \n (\n SELECT\n bt.id,\n bt.finished_at - bt.started_at AS task_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM web_node_stats AS ws \n WHERE ws.build_task_id = bt.id AND stat_name_id=0) AS web_node_duration,\n (SELECT SUM(end_ts - start_ts) \n FROM build_node_stats AS bs \n WHERE bs.build_task_id = bt.id AND stat_name_id=6) AS build_node_duration\n FROM build_tasks AS bt\n WHERE bt.build_id = $build_id AND status_id = 2\n GROUP BY bt.id\n ) as d\n ON bt.id = d.id\n WHERE bt.build_id = $build_id AND status_id = 2", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Completed build tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + } + ], + "title": "Details: build tasks", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 39, + "panels": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package" + }, + "properties": [ + { + "id": "custom.width", + "value": 322 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 93 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "revision" + }, + "properties": [ + { + "id": "custom.width", + "value": 62 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "build task id" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/vtQClqxVk/build-task-details?orgId=1&var-build_task=${__value.raw}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 41, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "duration" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n DISTINCT tt.id,\n tt.build_task_id as \"build task id\",\n tt.package_fullname AS package,\n tt.revision,\n enum.value AS \"status\",\n tt.started_at * 1000 AS \"started at\",\n tf.finished_at * 1000 AS \"finished at\", \n tf.finished_at - tt.started_at AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\nINNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\nINNER JOIN builds AS b\n ON bt.build_id = b.id\nINNER JOIN \n (SELECT \n tss.test_task_id, \n MAX(tss.finish_ts) AS finished_at \n FROM test_steps_stats AS tss\n INNER JOIN test_tasks AS tt\n ON tss.test_task_id = tt.id\n INNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\n INNER JOIN builds AS b\n ON bt.build_id = b.id\n WHERE b.id = $build_id\n GROUP BY tss.test_task_id) AS tf\n ON tf.test_task_id = tt.id\nWHERE b.id = $build_id;", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started at" + }, + { + "destinationType": "time", + "targetField": "finished at" + } + ], + "fields": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "test task id" + }, + "properties": [ + { + "id": "custom.width", + "value": 159 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package name" + }, + "properties": [ + { + "id": "custom.width", + "value": 408 + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 43, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "finished" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n tss.test_task_id AS \"test task id\", \n tt.package_fullname AS \"package name\",\n enum.value AS \"step name\",\n tss.start_ts * 1000 AS started,\n tss.finish_ts * 1000 AS finished,\n tss.finish_ts - tss.start_ts AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nINNER JOIN build_tasks AS bt\n ON tt.build_task_id = bt.id\nINNER JOIN builds AS b\n ON bt.build_id = b.id\nWHERE b.id = $build_id\n", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test steps", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + } + ], + "title": "Details: tests", + "type": "row" } ], "refresh": false, @@ -2382,7 +3217,7 @@ "current": {}, "datasource": { "type": "postgres", - "uid": "${DS_ALBS_ANALYTICS}" + "uid": "${DS_POSTGRESQL}" }, "definition": "SELECT id\nFROM builds\nORDER BY id DESC", "hide": 0, @@ -2407,6 +3242,6 @@ "timezone": "", "title": "Build details", "uid": "dmVtrz-4k", - "version": 5, + "version": 34, "weekStart": "" } \ No newline at end of file diff --git a/build_analytics/grafana-dashbords/Build task details.json b/build_analytics/grafana-dashbords/Build task details.json index 2249199..20b5c71 100644 --- a/build_analytics/grafana-dashbords/Build task details.json +++ b/build_analytics/grafana-dashbords/Build task details.json @@ -35,6 +35,12 @@ "name": "Grafana", "version": "9.3.2" }, + { + "type": "panel", + "id": "piechart", + "name": "Pie chart", + "version": "" + }, { "type": "datasource", "id": "postgres", @@ -77,6 +83,17 @@ "links": [], "liveNow": false, "panels": [ + { + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 28, + "title": "Build task", + "type": "row" + }, { "datasource": { "type": "postgres", @@ -143,7 +160,7 @@ "h": 3, "w": 24, "x": 0, - "y": 0 + "y": 1 }, "id": 5, "options": { @@ -196,7 +213,7 @@ "urlPath": "" } ], - "title": "Task summary", + "title": "Build task", "transformations": [ { "id": "convertFieldType", @@ -259,10 +276,10 @@ ] }, "gridPos": { - "h": 9, + "h": 8, "w": 24, "x": 0, - "y": 3 + "y": 4 }, "id": 12, "options": { @@ -629,14 +646,219 @@ "type": "bargauge" }, { - "collapsed": true, + "collapsed": false, "gridPos": { "h": 1, "w": 24, "x": 0, "y": 12 }, - "id": 8, + "id": 22, + "panels": [], + "title": "Test tasks", + "type": "row" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 11, + "x": 0, + "y": 13 + }, + "id": 24, + "options": { + "displayMode": "basic", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": false + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n enum.value AS \"step name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nWHERE tt.build_task_id = $build_task\nGROUP BY (enum.value); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test duration (group by test step)", + "transformations": [ + { + "id": "rowsToFields", + "options": {} + } + ], + "type": "bargauge" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + } + }, + "mappings": [], + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 13, + "x": 11, + "y": 13 + }, + "id": 18, + "options": { + "legend": { + "displayMode": "table", + "placement": "right", + "showLegend": true, + "values": [ + "value" + ] + }, + "pieType": "donut", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "format": "table", + "rawQuery": true, + "rawSql": "SELECT \n tt.package_fullname AS \"package name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nWHERE tt.build_task_id = $build_task\nGROUP BY (tt.package_fullname); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + } + } + ], + "title": "Tests duration (group by package)", + "transformations": [ + { + "id": "rowsToFields", + "options": { + "mappings": [] + } + } + ], + "type": "piechart" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 20, "panels": [ { "datasource": { @@ -650,7 +872,7 @@ "mode": "thresholds" }, "custom": { - "align": "auto", + "align": "left", "displayMode": "auto", "filterable": true, "inspect": true @@ -712,7 +934,7 @@ "h": 5, "w": 24, "x": 0, - "y": 13 + "y": 22 }, "id": 2, "options": { @@ -750,7 +972,7 @@ "method": "GET", "queryParams": "", "rawQuery": true, - "rawSql": "SELECT \n enum.value,\n stats.start_ts * 1000 AS started,\n stats.end_ts * 1000 AS finished,\n stats.end_ts - stats.start_ts AS duration\nFROM web_node_stats AS stats\nINNER JOIN web_node_stats_enum AS enum\n ON stats.stat_name_id = enum.id\nWHERE build_task_id = $build_task", + "rawSql": "SELECT \n enum.value as step,\n stats.start_ts * 1000 AS started,\n stats.end_ts * 1000 AS finished,\n stats.end_ts - stats.start_ts AS duration\nFROM web_node_stats AS stats\nINNER JOIN web_node_stats_enum AS enum\n ON stats.stat_name_id = enum.id\nWHERE build_task_id = $build_task", "refId": "web node stats", "sql": { "columns": [ @@ -805,7 +1027,7 @@ "mode": "thresholds" }, "custom": { - "align": "auto", + "align": "left", "displayMode": "auto", "filterable": true, "inspect": true @@ -852,10 +1074,10 @@ ] }, "gridPos": { - "h": 11, + "h": 8, "w": 24, "x": 0, - "y": 18 + "y": 27 }, "id": 3, "options": { @@ -893,7 +1115,7 @@ "method": "GET", "queryParams": "", "rawQuery": true, - "rawSql": "SELECT enum.value,\n stats.start_ts * 1000 AS started,\n stats.end_ts * 1000 AS finished,\n stats.end_ts - stats.start_ts AS duration\nFROM build_node_stats AS stats\nINNER JOIN build_node_stats_enum AS enum\n ON stats.stat_name_id = enum.id\nWHERE build_task_id = $build_task", + "rawSql": "SELECT enum.value AS step,\n stats.start_ts * 1000 AS started,\n stats.end_ts * 1000 AS finished,\n stats.end_ts - stats.start_ts AS duration\nFROM build_node_stats AS stats\nINNER JOIN build_node_stats_enum AS enum\n ON stats.stat_name_id = enum.id\nWHERE build_task_id = $build_task", "refId": "web node stats", "sql": { "columns": [ @@ -937,7 +1159,357 @@ "type": "table" } ], - "title": "Details", + "title": "Details: build task", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 22 + }, + "id": 30, + "panels": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "package" + }, + "properties": [ + { + "id": "custom.width", + "value": 389 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 72 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "revision" + }, + "properties": [ + { + "id": "custom.width", + "value": 119 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + } + ] + }, + "gridPos": { + "h": 5, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 26, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "id" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n DISTINCT tt.id,\n tt.package_fullname AS package,\n tt.revision,\n enum.value AS \"status\",\n tt.started_at * 1000 AS \"started at\",\n tf.finished_at * 1000 AS \"finished at\", \n tf.finished_at - tt.started_at AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\nINNER JOIN \n (SELECT \n tss.test_task_id, \n MAX(tss.finish_ts) AS finished_at \n FROM test_steps_stats AS tss\n INNER JOIN test_tasks AS tt\n ON tss.test_task_id = tt.id\n WHERE tt.build_task_id = $build_task\n GROUP BY tss.test_task_id) AS tf\n ON tf.test_task_id = tt.id\nWHERE tt.build_task_id = $build_task; ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test tasks", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started at" + }, + { + "destinationType": "time", + "targetField": "finished at" + } + ], + "fields": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "test task id" + }, + "properties": [ + { + "id": "custom.width", + "value": 159 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package name" + }, + "properties": [ + { + "id": "custom.width", + "value": 408 + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 16, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "finished" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n tt.package_fullname AS \"package name\",\n tss.test_task_id AS \"test task id\", \n enum.value AS \"step name\",\n tss.start_ts * 1000 AS started,\n tss.finish_ts * 1000 AS finished,\n tss.finish_ts - tss.start_ts AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nWHERE tt.build_task_id = $build_task; ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test steps", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + } + ], + "title": "Details: test tasks", "type": "row" } ], @@ -975,6 +1547,6 @@ "timezone": "", "title": "Build task details", "uid": "vtQClqxVk", - "version": 37, + "version": 61, "weekStart": "" } \ No newline at end of file diff --git a/build_analytics/grafana-dashbords/Test task details.json b/build_analytics/grafana-dashbords/Test task details.json new file mode 100644 index 0000000..2568011 --- /dev/null +++ b/build_analytics/grafana-dashbords/Test task details.json @@ -0,0 +1,516 @@ +{ + "__inputs": [ + { + "name": "DS_POSTGRESQL", + "label": "PostgreSQL", + "description": "", + "type": "datasource", + "pluginId": "postgres", + "pluginName": "PostgreSQL" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "panel", + "id": "bargauge", + "name": "Bar gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "9.3.2" + }, + { + "type": "datasource", + "id": "postgres", + "name": "PostgreSQL", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": false, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package" + }, + "properties": [ + { + "id": "custom.width", + "value": 253 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "id" + }, + "properties": [ + { + "id": "custom.width", + "value": 80 + } + ] + } + ] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 4, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n DISTINCT tt.id,\n tt.package_fullname AS package,\n tt.revision,\n enum.value AS \"status\",\n tt.started_at * 1000 AS \"started at\",\n tf.finished_at * 1000 AS \"finished at\", \n tf.finished_at - tt.started_at AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_tasks_status_enum AS enum\n ON tt.status_id = enum.id\nINNER JOIN \n (SELECT \n tss.test_task_id, \n MAX(tss.finish_ts) AS finished_at \n FROM test_steps_stats AS tss\n INNER JOIN test_tasks AS tt\n ON tss.test_task_id = tt.id\n WHERE tt.id = $id\n GROUP BY tss.test_task_id) AS tf\n ON tf.test_task_id = tt.id\nWHERE tt.id = $id;", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Task info", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started at" + }, + { + "destinationType": "time", + "targetField": "finished at" + } + ], + "fields": {} + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "blue", + "mode": "fixed" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 8, + "options": { + "displayMode": "basic", + "minVizHeight": 10, + "minVizWidth": 0, + "orientation": "vertical", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": false + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n enum.value AS \"step name\",\n SUM(tss.finish_ts - tss.start_ts) AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nWHERE tt.id = $id\nGROUP BY (enum.value); ", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test duration (group by test step)", + "transformations": [ + { + "id": "rowsToFields", + "options": {} + } + ], + "type": "bargauge" + }, + { + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "left", + "displayMode": "auto", + "filterable": true, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "test task id" + }, + "properties": [ + { + "id": "custom.width", + "value": 159 + }, + { + "id": "links", + "value": [ + { + "title": "", + "url": "/d/8nFXlkB4z/test-task-details?orgId=1&var-id=${__value.raw}" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "duration" + }, + "properties": [ + { + "id": "unit", + "value": "s" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "package name" + }, + "properties": [ + { + "id": "custom.width", + "value": 408 + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 11 + }, + "id": 6, + "options": { + "footer": { + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "finished" + } + ] + }, + "pluginVersion": "9.3.2", + "targets": [ + { + "cacheDurationSeconds": 300, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "editorMode": "code", + "fields": [ + { + "jsonPath": "" + } + ], + "format": "table", + "method": "GET", + "queryParams": "", + "rawQuery": true, + "rawSql": "SELECT \n tt.package_fullname AS \"package name\",\n tss.test_task_id AS \"test task id\", \n enum.value AS \"step name\",\n tss.start_ts * 1000 AS started,\n tss.finish_ts * 1000 AS finished,\n tss.finish_ts - tss.start_ts AS duration\nFROM test_tasks AS tt\nINNER JOIN test_steps_stats AS tss\n ON tt.id = tss.test_task_id\nINNER JOIN test_steps_enum AS enum\n ON tss.stat_name_id = enum.id\nWHERE tt.id = $id", + "refId": "A", + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "urlPath": "" + } + ], + "title": "Test steps", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "started" + }, + { + "destinationType": "time", + "targetField": "finished" + } + ], + "fields": {} + } + } + ], + "type": "table" + } + ], + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": {}, + "datasource": { + "type": "postgres", + "uid": "${DS_POSTGRESQL}" + }, + "definition": "SELECT id\nFROM test_tasks\nORDER BY id DESC", + "hide": 0, + "includeAll": false, + "label": "Test task id", + "multi": false, + "name": "id", + "options": [], + "query": "SELECT id\nFROM test_tasks\nORDER BY id DESC", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Test task details", + "uid": "8nFXlkB4z", + "version": 8, + "weekStart": "" +} \ No newline at end of file