From 1758f972f1a2cc4ba773500e6d0d5357a5d16551 Mon Sep 17 00:00:00 2001 From: redref Date: Tue, 31 Jan 2017 23:33:03 +0100 Subject: [PATCH 1/5] Reports counts - add total and noop --- puppetboard/app.py | 21 ++++++++++----------- puppetboard/static/css/puppetboard.css | 8 ++++++++ puppetboard/templates/_macros.html | 13 +++++++++++++ puppetboard/templates/reports.json.tpl | 2 +- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/puppetboard/app.py b/puppetboard/app.py index 20571ea..c7301dc 100644 --- a/puppetboard/app.py +++ b/puppetboard/app.py @@ -534,21 +534,20 @@ def reports_ajax(env, node_name): report_event_counts = {} # Create a map from the metrics data to what the templates # use to express the data. - report_map = { - 'success': 'successes', - 'failure': 'failures', - 'skipped': 'skips', - 'noops': 'noop' - } + events_metrics = ['success', 'failure', 'noop'] + resources_metrics = ['total', 'skipped'] for report in reports_events: if total is None: total = puppetdb.total - report_counts = {'successes': 0, 'failures': 0, 'skips': 0} - for metrics in report.metrics: - if 'name' in metrics and metrics['name'] in report_map: - key_name = report_map[metrics['name']] - report_counts[key_name] = metrics['value'] + report_counts = {} + for metric in report.metrics: + if ('category' in metric and metric['category'] == 'events' and + 'name' in metric and metric['name'] in events_metrics): + report_counts[metric['name']] = metric['value'] + if ('category' in metric and metric['category'] == 'resources' and + 'name' in metric and metric['name'] in resources_metrics): + report_counts[metric['name']] = metric['value'] report_event_counts[report.hash_] = report_counts diff --git a/puppetboard/static/css/puppetboard.css b/puppetboard/static/css/puppetboard.css index 19506f5..71b6856 100644 --- a/puppetboard/static/css/puppetboard.css +++ b/puppetboard/static/css/puppetboard.css @@ -72,6 +72,14 @@ h1.ui.header.no-margin-bottom { background-color: #DB843D; } +.ui.header.total { + color: #989898; +} + +.ui.label.total { + background-color: #989898; +} + .ui.label.unchanged { background-color: #89A54E; } diff --git a/puppetboard/templates/_macros.html b/puppetboard/templates/_macros.html index fe28cc5..7a07f15 100644 --- a/puppetboard/templates/_macros.html +++ b/puppetboard/templates/_macros.html @@ -57,6 +57,19 @@ {% endif %} {%- endmacro %} +{% macro report_status(caller, status, node_name, events, current_env, unreported_time=False, report_hash=False) -%} + {{ status|upper }} + {% if status == 'unreported' %} + {{ unreported_time|upper }} + {% else %} + {{events['total']}}{% else %}">0{% endif%} + {{events['failure']}}{% else %}">0{% endif%} + {{events['success']}}{% else %}">0{% endif%} + {{events['skipped']}}{% else %}">0{% endif%} + {{events['noop']}}{% else %}">0{% endif%} + {% endif %} +{%- endmacro %} + {% macro datatable_init(table_html_id, ajax_url, default_length, length_selector, extra_options=None) -%} // Init datatable $.fn.dataTable.ext.errMode = 'throw'; diff --git a/puppetboard/templates/reports.json.tpl b/puppetboard/templates/reports.json.tpl index 2c24659..9f74e31 100644 --- a/puppetboard/templates/reports.json.tpl +++ b/puppetboard/templates/reports.json.tpl @@ -15,7 +15,7 @@ "{{ report[column.attr] }}" {%- elif column.type == 'status' -%} {% filter jsonprint -%} - {{ macros.status_counts(status=report.status, node_name=report.node, events=report_event_counts[report.hash_], report_hash=report.hash_, current_env=current_env) }} + {{ macros.report_status(status=report.status, node_name=report.node, events=report_event_counts[report.hash_], report_hash=report.hash_, current_env=current_env) }} {%- endfilter %} {%- elif column.type == 'node' -%} {% filter jsonprint %}{{ report.node }}{% endfilter %} From bb26c5bbeae6e0405e97c1b0c35ac6a5ea1ebf17 Mon Sep 17 00:00:00 2001 From: redref Date: Wed, 1 Feb 2017 13:56:31 +0100 Subject: [PATCH 2/5] Metrics display tune --- puppetboard/app.py | 24 ++++++++---------------- puppetboard/templates/_macros.html | 12 ++++++------ puppetboard/templates/reports.json.tpl | 2 +- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/puppetboard/app.py b/puppetboard/app.py index c7301dc..4aef489 100644 --- a/puppetboard/app.py +++ b/puppetboard/app.py @@ -531,25 +531,17 @@ def reports_ajax(env, node_name): reports_events = [] total = 0 - report_event_counts = {} - # Create a map from the metrics data to what the templates - # use to express the data. - events_metrics = ['success', 'failure', 'noop'] - resources_metrics = ['total', 'skipped'] + # Convert metrics to relational dict + metrics = {} for report in reports_events: if total is None: total = puppetdb.total - report_counts = {} - for metric in report.metrics: - if ('category' in metric and metric['category'] == 'events' and - 'name' in metric and metric['name'] in events_metrics): - report_counts[metric['name']] = metric['value'] - if ('category' in metric and metric['category'] == 'resources' and - 'name' in metric and metric['name'] in resources_metrics): - report_counts[metric['name']] = metric['value'] - - report_event_counts[report.hash_] = report_counts + metrics[report.hash_] = {'resources': {}, 'events': {}} + for m in report.metrics: + if m['category'] not in metrics[report.hash_]: + metrics[report.hash_][m['category']] = {} + metrics[report.hash_][m['category']][m['name']] = m['value'] if total is None: total = 0 @@ -560,7 +552,7 @@ def reports_ajax(env, node_name): total=total, total_filtered=total, reports=reports, - report_event_counts=report_event_counts, + metrics=metrics, envs=envs, current_env=env, columns=REPORTS_COLUMNS[:max_col]) diff --git a/puppetboard/templates/_macros.html b/puppetboard/templates/_macros.html index 7a07f15..f7ce947 100644 --- a/puppetboard/templates/_macros.html +++ b/puppetboard/templates/_macros.html @@ -57,16 +57,16 @@ {% endif %} {%- endmacro %} -{% macro report_status(caller, status, node_name, events, current_env, unreported_time=False, report_hash=False) -%} +{% macro report_status(caller, status, node_name, metrics, current_env, unreported_time=False, report_hash=False) -%} {{ status|upper }} {% if status == 'unreported' %} {{ unreported_time|upper }} {% else %} - {{events['total']}}{% else %}">0{% endif%} - {{events['failure']}}{% else %}">0{% endif%} - {{events['success']}}{% else %}">0{% endif%} - {{events['skipped']}}{% else %}">0{% endif%} - {{events['noop']}}{% else %}">0{% endif%} + {{ metrics.resources.total }}{% else %}">0{% endif%} + {{ metrics.events.failure }}{% else %}">0{% endif%} + {{ metrics.events.success }}{% else %}">0{% endif%} + {{ metrics.resources.skipped }}{% else %}">0{% endif%} + {{ metrics.events.noop }}{% else %}">0{% endif%} {% endif %} {%- endmacro %} diff --git a/puppetboard/templates/reports.json.tpl b/puppetboard/templates/reports.json.tpl index 9f74e31..b773105 100644 --- a/puppetboard/templates/reports.json.tpl +++ b/puppetboard/templates/reports.json.tpl @@ -15,7 +15,7 @@ "{{ report[column.attr] }}" {%- elif column.type == 'status' -%} {% filter jsonprint -%} - {{ macros.report_status(status=report.status, node_name=report.node, events=report_event_counts[report.hash_], report_hash=report.hash_, current_env=current_env) }} + {{ macros.report_status(status=report.status, node_name=report.node, metrics=metrics[report.hash_], report_hash=report.hash_, current_env=current_env) }} {%- endfilter %} {%- elif column.type == 'node' -%} {% filter jsonprint %}{{ report.node }}{% endfilter %} From 16b197e0ce20635b876924322616dbdbbef86622 Mon Sep 17 00:00:00 2001 From: redref Date: Thu, 2 Feb 2017 10:05:49 +0100 Subject: [PATCH 3/5] Make counters configureable --- puppetboard/app.py | 2 +- puppetboard/default_settings.py | 5 +++++ puppetboard/static/css/puppetboard.css | 14 +++++--------- puppetboard/templates/_macros.html | 10 +++++----- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/puppetboard/app.py b/puppetboard/app.py index 4aef489..296f13e 100644 --- a/puppetboard/app.py +++ b/puppetboard/app.py @@ -537,7 +537,7 @@ def reports_ajax(env, node_name): if total is None: total = puppetdb.total - metrics[report.hash_] = {'resources': {}, 'events': {}} + metrics[report.hash_] = {} for m in report.metrics: if m['category'] not in metrics[report.hash_]: metrics[report.hash_][m['category']] = {} diff --git a/puppetboard/default_settings.py b/puppetboard/default_settings.py index 717925b..7bd6cc1 100644 --- a/puppetboard/default_settings.py +++ b/puppetboard/default_settings.py @@ -18,6 +18,11 @@ LOGLEVEL = 'info' NORMAL_TABLE_COUNT = 100 LITTLE_TABLE_COUNT = 10 TABLE_COUNT_SELECTOR = [10, 20, 50, 100, 500] +DISPLAYED_METRICS = ['resources.total', + 'events.failure', + 'events.success', + 'resources.skipped', + 'events.noop'] OFFLINE_MODE = False ENABLE_CATALOG = False OVERVIEW_FILTER = None diff --git a/puppetboard/static/css/puppetboard.css b/puppetboard/static/css/puppetboard.css index 71b6856..db50a38 100644 --- a/puppetboard/static/css/puppetboard.css +++ b/puppetboard/static/css/puppetboard.css @@ -44,7 +44,7 @@ h1.ui.header.no-margin-bottom { color: #AA4643; } -.ui.label.failed { +.ui.label.failed, .ui.label.events.failure { background-color: #AA4643; } @@ -52,7 +52,7 @@ h1.ui.header.no-margin-bottom { color: #4572A7; } -.ui.label.changed { +.ui.label.changed, .ui.label.events.success { background-color: #4572A7; } @@ -68,15 +68,11 @@ h1.ui.header.no-margin-bottom { color: #DB843D; } -.ui.label.noop { +.ui.label.noop, .ui.label.events.noop { background-color: #DB843D; } -.ui.header.total { - color: #989898; -} - -.ui.label.total { +.ui.label.resources.total { background-color: #989898; } @@ -88,7 +84,7 @@ h1.ui.header.no-margin-bottom { color: orange; } -.ui.label.skipped { +.ui.label.skipped, .ui.label.resources.skipped { background-color: orange; } diff --git a/puppetboard/templates/_macros.html b/puppetboard/templates/_macros.html index f7ce947..b39fadb 100644 --- a/puppetboard/templates/_macros.html +++ b/puppetboard/templates/_macros.html @@ -62,11 +62,11 @@ {% if status == 'unreported' %} {{ unreported_time|upper }} {% else %} - {{ metrics.resources.total }}{% else %}">0{% endif%} - {{ metrics.events.failure }}{% else %}">0{% endif%} - {{ metrics.events.success }}{% else %}">0{% endif%} - {{ metrics.resources.skipped }}{% else %}">0{% endif%} - {{ metrics.events.noop }}{% else %}">0{% endif%} + {% for metric in config.DISPLAYED_METRICS %} + {% set path = metric.split('.') %} + {% set title = ' '.join(path) %} + {{ "%.2g"|format(metrics[path[0]][path[1]]) }}{% else %}">0{% endif%} + {% endfor %} {% endif %} {%- endmacro %} From 42ed123fe37d1e234f80624609ebec9269e733cd Mon Sep 17 00:00:00 2001 From: redref Date: Thu, 2 Feb 2017 18:23:09 +0100 Subject: [PATCH 4/5] Fix number formating in counters --- puppetboard/templates/_macros.html | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/puppetboard/templates/_macros.html b/puppetboard/templates/_macros.html index b39fadb..e4cb163 100644 --- a/puppetboard/templates/_macros.html +++ b/puppetboard/templates/_macros.html @@ -65,7 +65,17 @@ {% for metric in config.DISPLAYED_METRICS %} {% set path = metric.split('.') %} {% set title = ' '.join(path) %} - {{ "%.2g"|format(metrics[path[0]][path[1]]) }}{% else %}">0{% endif%} + {% if metrics[path[0]] and metrics[path[0]][path[1]] %} + {% set value = metrics[path[0]][path[1]] %} + {% if value != 0 and value|int != value %} + {% set format_str = '%.2f' %} + {% else %} + {% set format_str = '%s' %} + {% endif %} + {{ format_str|format(value) }} + {% else %} + 0 + {% endif%} {% endfor %} {% endif %} {%- endmacro %} From 671d538a8bcd00714c3cdc873a0df359a7f16639 Mon Sep 17 00:00:00 2001 From: Mike Terzo Date: Thu, 2 Feb 2017 20:14:02 -0500 Subject: [PATCH 5/5] Add report column settings to docker_settings --- puppetboard/docker_settings.py | 8 +++++++- test/test_docker_settings.py | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/puppetboard/docker_settings.py b/puppetboard/docker_settings.py index e32ac2a..3f61b33 100644 --- a/puppetboard/docker_settings.py +++ b/puppetboard/docker_settings.py @@ -33,6 +33,13 @@ TABLE_COUNT_DEF = "10,20,50,100,500" TABLE_COUNT_SELECTOR = [int(x) for x in os.getenv('TABLE_COUNT_SELECTOR', TABLE_COUNT_DEF).split(',')] +DISP_METR_DEF = ','.join(['resources.total', 'events.failure', + 'events.success', 'resources.skipped', + 'events.noop']) + +DISPLAYED_METRICS = [x.strip() for x in os.getenv('DISPLAYED_METRICS', + DISP_METR_DEF).split(',')] + OFFLINE_MODE = bool(os.getenv('OFFLINE_MODE', 'False').upper() == 'TRUE') ENABLE_CATALOG = bool(os.getenv('ENABLE_CATALOG', 'False').upper() == 'TRUE') OVERVIEW_FILTER = os.getenv('OVERVIEW_FILTER', None) @@ -46,7 +53,6 @@ GRAPH_FACTS_DEFAULT = ','.join(['architecture', 'clientversion', 'domain', GRAPH_FACTS = [x.strip() for x in os.getenv('GRAPH_FACTS', GRAPH_FACTS_DEFAULT).split(',')] - GRAPH_TYPE = os.getenv('GRAPH_TYPE', 'pie') # Tuples are hard to express as an environment variable, so here diff --git a/test/test_docker_settings.py b/test/test_docker_settings.py index 4b36a6d..6a44ab1 100644 --- a/test/test_docker_settings.py +++ b/test/test_docker_settings.py @@ -116,3 +116,11 @@ def test_env_table_selector(cleanUpEnv): os.environ['TABLE_COUNT_SELECTOR'] = '5,15,25' reload(docker_settings) assert [5, 15, 25] == docker_settings.TABLE_COUNT_SELECTOR + + +def test_env_column_options(cleanUpEnv): + os.environ['DISPLAYED_METRICS'] = 'resources.total, events.failure' + + reload(docker_settings) + assert ['resources.total', + 'events.failure'] == docker_settings.DISPLAYED_METRICS