From 16348d1c7a191e5e474511a72ba007f5ff3a0c85 Mon Sep 17 00:00:00 2001 From: dvanaken Date: Thu, 9 Jan 2020 02:47:22 -0500 Subject: [PATCH] Updated fixtures, human-readable values values in knob/metric comparison view --- server/website/tests/test_parser.py | 59 --------------- server/website/website/db/base/parser.py | 8 -- server/website/website/db/myrocks/parser.py | 7 -- .../website/db/oracle/target_objective.py | 4 +- server/website/website/db/parser.py | 8 -- .../website/website/templates/dbms_data.html | 8 +- server/website/website/utils.py | 2 - server/website/website/views.py | 74 ++++++++++++------- 8 files changed, 55 insertions(+), 115 deletions(-) diff --git a/server/website/tests/test_parser.py b/server/website/tests/test_parser.py index 82c5e13..8ea4555 100644 --- a/server/website/tests/test_parser.py +++ b/server/website/tests/test_parser.py @@ -207,14 +207,6 @@ class BaseParserTests(object, metaclass=ABCMeta): with self.assertRaises(Exception): self.test_dbms.format_dbms_knobs(test_exceptions) - @abstractmethod - def test_filter_numeric_metrics(self): - pass - - @abstractmethod - def test_filter_tunable_knobs(self): - pass - class PostgresParserTests(BaseParserTests, TestCase): @@ -501,57 +493,6 @@ class PostgresParserTests(BaseParserTests, TestCase): self.assertEqual(test_formatted_knobs.get('global.geqo_effort'), 5) self.assertEqual(test_formatted_knobs.get('global.wal_buffers'), '1kB') - def test_filter_numeric_metrics(self): - super().test_filter_numeric_metrics() - - test_metrics = {'pg_stat_bgwriter.checkpoints_req': (2, 'global'), - 'pg_stat_archiver.last_failed_wal': (1, 'global'), - 'pg_stat_database.stats_reset': (6, 'database'), - 'pg_statio_user_indexes.indexrelname': (1, 'index'), - 'pg_stat_bgwriter.maxwritten_clean': (2, 'global'), - 'pg_stat_database.tup_fetched': (2, 'database'), - 'pg_statio_user_tables.heap_blks_read': (2, 'table'), - 'pg_FAKE_METRIC': (2, 'database')} - - filtered_metrics = self.test_dbms.filter_numeric_metrics(test_metrics) - - self.assertEqual(len(list(filtered_metrics.keys())), 4) - self.assertEqual(filtered_metrics.get('pg_stat_bgwriter.checkpoints_req'), - (2, 'global')) - self.assertEqual(filtered_metrics.get('pg_stat_archiver.last_failed_wal'), None) - self.assertEqual(filtered_metrics.get('pg_stat_database.stats_reset'), None) - self.assertEqual(filtered_metrics.get('pg_statio_user_indexes.indexrelname'), - None) - self.assertEqual(filtered_metrics.get('pg_stat_bgwriter.maxwritten_clean'), - (2, 'global')) - self.assertEqual(filtered_metrics.get('pg_stat_database.tup_fetched'), - (2, 'database')) - self.assertEqual(filtered_metrics.get('pg_statio_user_tables.heap_blks_read'), - (2, 'table')) - self.assertEqual(filtered_metrics.get('pg_FAKE_KNOB'), None) - - def test_filter_tunable_knobs(self): - super().test_filter_tunable_knobs() - - test_knobs = {'global.wal_sync_method': 5, - 'global.random_page_cost': 3, - 'global.archive_command': 1, - 'global.cpu_tuple_cost': 3, - 'global.force_parallel_mode': 5, - 'global.enable_hashjoin': 3, - 'global.geqo_effort': 2, - 'global.wal_buffers': 2, - 'global.FAKE_KNOB': 2} - - filtered_knobs = self.test_dbms.filter_tunable_knobs(test_knobs) - - self.assertEqual(len(list(filtered_knobs.keys())), 3) - self.assertEqual(filtered_knobs.get('global.wal_sync_method'), 5) - self.assertEqual(filtered_knobs.get('global.wal_buffers'), 2) - self.assertEqual(filtered_knobs.get('global.random_page_cost'), 3) - self.assertEqual(filtered_knobs.get('global.cpu_tuple_cost'), None) - self.assertEqual(filtered_knobs.get('global.FAKE_KNOB'), None) - def test_parse_helper(self): super().test_parse_helper() diff --git a/server/website/website/db/base/parser.py b/server/website/website/db/base/parser.py index 0137963..74373f9 100644 --- a/server/website/website/db/base/parser.py +++ b/server/website/website/db/base/parser.py @@ -420,12 +420,4 @@ class BaseParser: formatted_knobs[knob_name] = fvalue return formatted_knobs - def filter_numeric_metrics(self, metrics): - return OrderedDict(((k, v) for k, v in list(metrics.items()) if - k in self.numeric_metric_catalog_)) - - def filter_tunable_knobs(self, knobs): - return OrderedDict(((k, v) for k, v in list(knobs.items()) if - k in self.tunable_knob_catalog_)) - # pylint: enable=no-self-use diff --git a/server/website/website/db/myrocks/parser.py b/server/website/website/db/myrocks/parser.py index 114a599..435a390 100644 --- a/server/website/website/db/myrocks/parser.py +++ b/server/website/website/db/myrocks/parser.py @@ -206,10 +206,3 @@ class MyRocksParser(BaseParser): knob_data[name] = conv_value return knob_data - def filter_numeric_metrics(self, metrics): - return OrderedDict([(k, v) for k, v in list(metrics.items()) if - self.partial_name(k) in self.numeric_metric_catalog_]) - - def filter_tunable_knobs(self, knobs): - return OrderedDict([(k, v) for k, v in list(knobs.items()) if - self.partial_name(k) in self.tunable_knob_catalog_]) diff --git a/server/website/website/db/oracle/target_objective.py b/server/website/website/db/oracle/target_objective.py index 553aa3d..27a24e7 100644 --- a/server/website/website/db/oracle/target_objective.py +++ b/server/website/website/db/oracle/target_objective.py @@ -11,11 +11,11 @@ from website.types import DBMSType class DBTime(BaseTargetObjective): def __init__(self): - super().__init__(name='db_time', pprint='DB Time', unit='milliseconds', short_unit='ms', + super().__init__(name='db_time', pprint='DB Time', unit='seconds', short_unit='s', improvement=LESS_IS_BETTER) def compute(self, metrics, observation_time): - return float(metrics['global.sys_time_model.db time']) / observation_time + return float(metrics['global.sys_time_model.db time']) / observation_time / 1000. target_objective_list = tuple((DBMSType.ORACLE, target_obj) for target_obj in [ # pylint: disable=invalid-name diff --git a/server/website/website/db/parser.py b/server/website/website/db/parser.py index ebbbdc2..97fdf7d 100644 --- a/server/website/website/db/parser.py +++ b/server/website/website/db/parser.py @@ -73,14 +73,6 @@ def format_dbms_knobs(dbms_id, knobs): return _get(dbms_id).format_dbms_knobs(knobs) -def filter_numeric_metrics(dbms_id, metrics): - return _get(dbms_id).filter_numeric_metrics(metrics) - - -def filter_tunable_knobs(dbms_id, knobs): - return _get(dbms_id).filter_tunable_knobs(knobs) - - def calculate_change_in_metrics(dbms_id, metrics_start, metrics_end): return _get(dbms_id).calculate_change_in_metrics( metrics_start, metrics_end) diff --git a/server/website/website/templates/dbms_data.html b/server/website/website/templates/dbms_data.html index bdd96e1..ba2f456 100644 --- a/server/website/website/templates/dbms_data.html +++ b/server/website/website/templates/dbms_data.html @@ -41,9 +41,9 @@
Name
-
Value {{ target_obj }}
+
Value   {{ target_obj }}
{% if compare != "none" %} -
Comparing Value {{ cmp_target_obj }}
+
Comparing Value   {{ cmp_target_obj }}
{% endif %} {% for pair in featured_data %} @@ -71,9 +71,9 @@
Name
-
Value
+
Value   {{ target_obj }}
{% if compare != "none" %} -
Comparing Value
+
Comparing Value   {{ cmp_target_obj }}
{% endif %} {% for pair in all_data %} diff --git a/server/website/website/utils.py b/server/website/website/utils.py index 0f2d0b5..31579b3 100644 --- a/server/website/website/utils.py +++ b/server/website/website/utils.py @@ -310,8 +310,6 @@ class ConversionUtil(object): raise ValueError('Invalid min suffix for system: suffix={}, system={}'.format( min_suffix, system)) - LOG.info('min_suffix: %s, min_factor: %s, unit: %s, value: %s\nMOD_SYS:\n%s\n\n', - min_suffix, min_factor, unit, value, mod_system) for factor, suffix in mod_system: adj_factor = factor / min_factor if value % adj_factor == 0: diff --git a/server/website/website/views.py b/server/website/website/views.py index 8a5748e..d9a3763 100644 --- a/server/website/website/views.py +++ b/server/website/website/views.py @@ -415,7 +415,7 @@ def result_view(request, project_id, session_id, result_id): vwidth = max(len(str(v)) for v in cfg.values()) next_conf = '' for k, v in cfg.items(): - next_conf += '{: <{kwidth}} = {: >{vwidth}}\n'.format( + next_conf += '{: <{kwidth}} = {: <{vwidth}}\n'.format( k, v, kwidth=kwidth, vwidth=vwidth) except Exception as e: # pylint: disable=broad-except LOG.exception("Failed to format the next config (type=%s): %s.\n\n%s\n", @@ -749,45 +749,69 @@ def metric_data_view(request, project_id, session_id, data_id): # pylint: disab def dbms_data_view(request, context, dbms_data, session, target_obj): - if context['data_type'] == 'knobs': + data_type = context['data_type'] + dbms_id = session.dbms.pk + + def _format_knobs(_dict): + if data_type == 'knobs' and session.dbms.type in (DBMSType.ORACLE,): + _knob_meta = KnobCatalog.objects.filter( + dbms_id=dbms_id, unit=KnobUnitType.BYTES) + _parser = parser._get(dbms_id) # pylint: disable=protected-access + for _meta in _knob_meta: + if _meta.name in _dict: + try: + _v = int(_dict[_meta.name]) + _v = _parser.format_integer(_v, _meta) + except (ValueError, TypeError): + LOG.warning("Error parsing knob %s=%s.", _meta.name, + _v, exc_info=True) + _dict[_meta.name] = _v + + if data_type == 'knobs': model_class = KnobData - filter_fn = parser.filter_tunable_knobs - obj_data = dbms_data.knobs + featured_names = set(SessionKnob.objects.filter( + session=session, tunable=True).values_list( + 'knob__name', flat=True)) else: model_class = MetricData - filter_fn = parser.filter_numeric_metrics - obj_data = dbms_data.metrics + num_types = (MetricType.COUNTER, MetricType.STATISTICS) + featured_names = set(MetricCatalog.objects.filter( + dbms=session.dbms, metric_type__in=num_types).values_list( + 'name', flat=True)) - dbms_id = dbms_data.dbms.pk + obj_data = getattr(dbms_data, data_type) all_data_dict = JSONUtil.loads(obj_data) - featured_dict = filter_fn(dbms_id, all_data_dict) + _format_knobs(all_data_dict) - target_obj_name = target_objectives.get_instance( - session.dbms.pk, session.target_objective).pprint - target_obj = '('+target_obj_name+'='+str(int(target_obj))+')' - if 'compare' in request.GET and request.GET['compare'] != 'none': - comp_id = request.GET['compare'] + featured_dict = OrderedDict([(k, v) for k, v in all_data_dict.items() + if k in featured_names]) + target_inst = target_objectives.get_instance(dbms_id, session.target_objective) + target_obj_name = target_inst.pprint + target_fmt = "({}: {{v:.0f}}{})".format(target_obj_name, target_inst.short_unit).format + target_obj = target_fmt(v=target_obj) + + comp_id = request.GET.get('compare', 'none') + if comp_id != 'none': compare_obj = model_class.objects.get(pk=comp_id) - comp_data = compare_obj.knobs if \ - context['data_type'] == 'knobs' else compare_obj.metrics + comp_data = getattr(compare_obj, data_type) comp_dict = JSONUtil.loads(comp_data) - comp_featured_dict = filter_fn(dbms_id, comp_dict) + _format_knobs(comp_dict) all_data = [(k, v, comp_dict[k]) for k, v in list(all_data_dict.items())] - featured_data = [(k, v, comp_featured_dict[k]) - for k, v in list(featured_dict.items())] + featured_data = [(k, v, comp_dict[k]) for k, v in list(featured_dict.items())] - result = Result.objects.filter(knob_data=compare_obj)[0] - cmp_target_obj = JSONUtil.loads(result.metric_data.data)[session.target_objective] - cmp_target_obj = '('+target_obj_name+'='+str(int(cmp_target_obj))+')' + if data_type == 'knobs': + met_data = Result.objects.get(knob_data=compare_obj).metric_data.data + else: + met_data = dbms_data.data + + cmp_target_obj = JSONUtil.loads(met_data)[session.target_objective] + cmp_target_obj = target_fmt(v=cmp_target_obj) else: - comp_id = None all_data = list(all_data_dict.items()) featured_data = list(featured_dict.items()) cmp_target_obj = "" - peer_data = model_class.objects.filter( - dbms=dbms_data.dbms, session=dbms_data.session) - peer_data = [peer for peer in peer_data if peer.pk != dbms_data.pk] + peer_data = model_class.objects.filter(session=session).exclude(pk=dbms_data.pk) context['all_data'] = all_data context['featured_data'] = featured_data