diff --git a/brian_dashboard_manager/environment.py b/brian_dashboard_manager/environment.py index b5057098e019cdb840eaf1b3599ad3053a21c529..865f17a9398f932ad788947da0a3e1640d904c55 100644 --- a/brian_dashboard_manager/environment.py +++ b/brian_dashboard_manager/environment.py @@ -1,6 +1,9 @@ import json import logging.config import os +import pkg_resources +import sentry_sdk +from sentry_sdk.integrations.flask import FlaskIntegration def setup_logging(): @@ -13,6 +16,14 @@ def setup_logging(): default_filename = os.path.join( os.path.dirname(__file__), 'logging_default_config.json') filename = os.getenv('LOGGING_CONFIG', default_filename) + + sentry_dsn = os.getenv('SENTRY_DSN') + if sentry_dsn: + sentry_sdk.init( + dsn=sentry_dsn, + integrations=[FlaskIntegration()], + release=pkg_resources.get_distribution('brian-dashboard-manager').version) + with open(filename) as f: # TODO: this mac workaround should be removed ... d = json.loads(f.read()) diff --git a/brian_dashboard_manager/grafana/dashboard.py b/brian_dashboard_manager/grafana/dashboard.py index ccaf83b8ca09c1301a61497aeae27216a3da82a2..37b67163e27fc33c19fe325801b4781e7489d772 100644 --- a/brian_dashboard_manager/grafana/dashboard.py +++ b/brian_dashboard_manager/grafana/dashboard.py @@ -4,12 +4,15 @@ Grafana Dashhboard API endpoints wrapper functions. import logging import os import json +import time from requests.exceptions import HTTPError from brian_dashboard_manager.grafana.utils.request import TokenRequest logger = logging.getLogger(__name__) +NUM_RETRIES = 3 + def get_dashboard_definitions(dir=None): """ @@ -231,9 +234,21 @@ def create_dashboard(request: TokenRequest, dashboard: dict, folder_id=None): if folder_id: payload['folderId'] = folder_id - try: - r = request.post('api/dashboards/db', json=payload) - return r.json() - except HTTPError: - logger.exception(f'Error when provisioning dashboard {title}') + # retry up to NUM_RETRIES times + for _ in range(NUM_RETRIES): + try: + r = request.post('api/dashboards/db', json=payload) + return r.json() + except HTTPError as e: + message = '' + if e.response is not None and e.response.status_code < 500: + # log the error message from Grafana + message = e.response.json() + + # only retry on server side errors + if e.response is not None and e.response.status_code < 500: + break + + logger.exception(f'Error when provisioning dashboard {title}: {message}') + time.sleep(1) # sleep for 1 second before retrying return None diff --git a/brian_dashboard_manager/grafana/provision.py b/brian_dashboard_manager/grafana/provision.py index 6ffdcab4ad13d32a6f2adf7f0ecfb717ebe7b54f..3d71d8722b188566c7535158ee363a4e1d19dc9b 100644 --- a/brian_dashboard_manager/grafana/provision.py +++ b/brian_dashboard_manager/grafana/provision.py @@ -708,9 +708,6 @@ def provision_maybe(config): now = datetime.datetime.now() write_timestamp(now.timestamp(), provisioning) provision(config) - except Exception as e: - logger.exception('Uncaught Exception:') - raise e finally: now = datetime.datetime.now() write_timestamp(now.timestamp(), False) @@ -742,7 +739,7 @@ def provision(config): return next( o for o in orgs_to_provision if o['name'] == org['name']) except StopIteration: - logger.error( + logger.info( f'Org {org["name"]} does not have valid configuration.') return None diff --git a/brian_dashboard_manager/templating/helpers.py b/brian_dashboard_manager/templating/helpers.py index 51878cc319c7782e7353e12de9c2357cc1bd9cec..2e0089a1b535152a7ad2924b81108b01e5299edd 100644 --- a/brian_dashboard_manager/templating/helpers.py +++ b/brian_dashboard_manager/templating/helpers.py @@ -20,7 +20,7 @@ PANEL_WIDTH = 24 logger = logging.getLogger(__file__) -def num_generator(start=1): +def num_generator(start=30): """ Generator for numbers starting from the value of `start` diff --git a/brian_dashboard_manager/templating/templates/nren_access/nren-dashboard.json.j2 b/brian_dashboard_manager/templating/templates/nren_access/nren-dashboard.json.j2 index 130ddfa036aa1e3f7d3c51121c7bf3a35e602e00..eeb9dbb9fb0151e4f25a0f100e495796bad1e2ff 100644 --- a/brian_dashboard_manager/templating/templates/nren_access/nren-dashboard.json.j2 +++ b/brian_dashboard_manager/templating/templates/nren_access/nren-dashboard.json.j2 @@ -39,6 +39,23 @@ "version": 1, "links": [], "panels": [ + { + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "content": "", + "mode": "html" + }, + "pluginVersion": "8.2.5", + "title": "INFO: The average values displayed are only mean values for timescales of 2 days or less", + "type": "text" + }, {% for panel in aggregate_panels %} {{ panel }}, {% endfor %} diff --git a/brian_dashboard_manager/templating/templates/shared/dashboard.json.j2 b/brian_dashboard_manager/templating/templates/shared/dashboard.json.j2 index 1c6564d719aeacd1bec7f47cdacf74ffb465689d..7132cf0e43d708a7efdcc3c3e3315359ce77a116 100644 --- a/brian_dashboard_manager/templating/templates/shared/dashboard.json.j2 +++ b/brian_dashboard_manager/templating/templates/shared/dashboard.json.j2 @@ -39,6 +39,23 @@ "version": 1, "links": [], "panels": [ + { + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "content": "", + "mode": "html" + }, + "pluginVersion": "8.2.5", + "title": "INFO: The average values displayed are only mean values for timescales of 2 days or less", + "type": "text" + }{{ "," if panels }} {% for panel in panels %} {{ panel }}{{ "," if not loop.last }} {% endfor %} diff --git a/changelog.md b/changelog.md index 678f2e9e6a8df231df50bc09124dbd77176ee661..daf7df5d8ce05316d8d2f21c63652cefd068ba55 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. +## [0.53] - 2023-06-21 +- Add banner explaining difference between average/mean for >48h time ranges + ## [0.52] - 2023-04-17 - Changed HTTP requests to reuse TCP connections to improve provisioning time - Changed Jinja template code to cache templates on startup diff --git a/requirements.txt b/requirements.txt index c4cf279340074c24ff4fad9e7766c9f3441f0138..b650084178d47fa18e888ba4ae3ffe970e1d9712 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ responses sphinx sphinx-rtd-theme +sentry-sdk[flask] \ No newline at end of file diff --git a/setup.py b/setup.py index 5b2b11f0ac5cd1d3cfa3b68ba54dd7c3ab1a12f4..bd93bf37a7dcae0578f7753a98ccfdd975682b73 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name='brian-dashboard-manager', - version="0.52", + version="0.53", author='GEANT', author_email='swd@geant.org', description='', @@ -12,7 +12,8 @@ setup( 'requests', 'jsonschema', 'flask', - 'jinja2' + 'jinja2', + 'sentry-sdk[flask]' ], include_package_data=True, ) diff --git a/test/test_aggregrate.py b/test/test_aggregrate.py index 7c494ba0283110ffaf5e0bd7b9d70617264f283a..b70cd58042ba42ba75e089cd47cba094108c30b1 100644 --- a/test/test_aggregrate.py +++ b/test/test_aggregrate.py @@ -337,5 +337,5 @@ def test_provision_aggregate(data_config, mocker, client): panels = result['panels'] expected_title = f'Aggregate - {TEST_DASHBOARD["dashboard_name"]}' assert result['title'] == expected_title - assert len(panels) == 14 - assert len(panels[0]['targets']) == len(TEST_DASHBOARD['interfaces']) + assert len(panels) == 15 + assert len(panels[1]['targets']) == len(TEST_DASHBOARD['interfaces']) diff --git a/test/test_grafana_dashboard.py b/test/test_grafana_dashboard.py index effec7094269999bcc2aaaf18af3b76e43339a2f..e3da83f02c59e21ca0d49348e396d11e8b1aec7b 100644 --- a/test/test_grafana_dashboard.py +++ b/test/test_grafana_dashboard.py @@ -195,7 +195,7 @@ def test_create_dashboard_no_uid_error(data_config): assert 'id' not in body['dashboard'] # have already tested a successful response, respond with error here. - return 400, {}, '' + return 400, {}, '{}' responses.add_callback( method=responses.POST, diff --git a/tox.ini b/tox.ini index 4210c4fbd48478d94b81e1c91851784950976253..f2c726d273badaeac99d80aa1b1ca0736b1422dd 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,7 @@ envlist = py36 [flake8] exclude = venv,.tox +max-line-length = 120 [testenv] setenv =