def testmonitor(): """ Gives an overview of the unit test performance results and the endpoints that they hit. :return: """ from numpy import median with session_scope() as db_session: latest_version = get_latest_test_version(db_session) tests_latest = count_times_tested(db_session, TestEndpoint.app_version == latest_version) tests = count_times_tested(db_session) median_latest = get_test_data_grouped(db_session, median, TestEndpoint.app_version == latest_version) median = get_test_data_grouped(db_session, median) tested_times = get_last_tested_times(db_session) result = [] for endpoint in get_tested_endpoint_names(db_session): result.append({ 'name': endpoint, 'color': get_color(endpoint), 'tests-latest-version': get_value(tests_latest, endpoint), 'tests-overall': get_value(tests, endpoint), 'median-latest-version': get_value(median_latest, endpoint), 'median-overall': get_value(median, endpoint), 'last-tested': get_value(tested_times, endpoint, default=None) }) return render_template('fmd_testmonitor/testmonitor.html', result=result)
def get_endpoint_versions(db_session, endpoint_id, versions): """ :param db_session: session for the database :param endpoint_id: id for the endpoint :param versions: a list of version to be filtered on :return: a list of dicts with the performance of each version """ times = get_version_data_grouped(db_session, lambda x: simplify(x, 100), Request.endpoint_id == endpoint_id) first_requests = get_first_requests(db_session, endpoint_id) return [{ 'version': v, 'date': get_value(first_requests, v), 'values': get_value(times, v), 'color': get_color(v) } for v in versions]
def get_endpoint_users(db_session, endpoint_id, users): """ :param db_session: session for the database :param endpoint_id: id for the endpoint :param users: a list of users to be filtered on :return: a list of dicts with the performance of each user """ times = get_user_data_grouped(db_session, lambda x: simplify(x, 100), Request.endpoint_id == endpoint_id) first_requests = get_first_requests(db_session, endpoint_id) return [{ 'user': u, 'date': get_value(first_requests, u), 'values': get_value(times, u), 'color': get_color(u) } for u in users]
def get_multi_version_data(session, endpoints, versions): """ :param session: session for the database :param endpoints: a list of all endpoints for which the data must be collected (represented by their name) :param versions: a list of versions :return: a 2d list of data """ endpoints = [get_endpoint_by_name(session, name) for name in endpoints] requests = [ count_requests_group(session, Request.version_requested == v) for v in versions ] total_hits = numpy.zeros(len(versions)) hits = numpy.zeros((len(endpoints), len(versions))) for i, _ in enumerate(versions): total_hits[i] = max(1, sum([value for key, value in requests[i]])) for j, _ in enumerate(endpoints): for i, _ in enumerate(versions): hits[j][i] = get_value(requests[i], endpoints[j].id) * 100 / total_hits[i] return hits.tolist()
def version_ip_graph(db_session, endpoint_id, form): """ :param db_session: session for the database :param endpoint_id: the endpoint to filter the data on :param form: form for reducing the size of the graph :return: an HTML bubble plot """ users = get_ips(db_session, endpoint_id, form.get_slider_value(0)) versions = get_versions(db_session, endpoint_id, form.get_slider_value(1)) first_request = get_first_requests(db_session, endpoint_id) values = get_two_columns_grouped(db_session, Request.ip, Request.endpoint_id == endpoint_id) data = [[get_value(values, (user, v)) for v in versions] for user in users] average = get_average_bubble_size(data) trace = [ scatter(x=[ format_version(v, get_value(first_request, v)) for v in versions ], hovertext=[ 'Time: {:,.1f}ms'.format(data[i][j]) for j in range(len(versions)) ], y=[users[i]] * len(versions), name=users[i], mode='markers', marker={ 'color': [get_color(users[i])] * len(versions), 'size': [math.sqrt(d) for d in data[i]], 'sizeref': average, 'sizemode': 'area' }) for i in range(len(users)) ] layout = get_layout(height=350 + 40 * len(trace), xaxis={ 'title': 'Versions', 'type': 'category' }, yaxis={ 'title': 'IP-addresses', 'type': 'category', 'autorange': 'reversed' }, margin=get_margin(b=200)) return get_figure(layout, trace)
def get_endpoint_overview(db_session): """ :param db_session: session for the database :return: A list of properties for each endpoint that is found in the database """ week_ago = datetime.datetime.utcnow() - datetime.timedelta(days=7) now_local = to_local_datetime(datetime.datetime.utcnow()) today_local = now_local.replace(hour=0, minute=0, second=0, microsecond=0) today_utc = to_utc_datetime(today_local) hits_today = count_requests_group(db_session, Request.time_requested > today_utc) hits_week = count_requests_group(db_session, Request.time_requested > week_ago) hits = count_requests_group(db_session) median_today = get_endpoint_data_grouped(db_session, median, Request.time_requested > today_utc) median_week = get_endpoint_data_grouped(db_session, median, Request.time_requested > week_ago) median_overall = get_endpoint_data_grouped(db_session, median) access_times = get_last_requested(db_session) return [{ 'id': endpoint.id, 'name': endpoint.name, 'monitor': endpoint.monitor_level, 'color': get_color(endpoint.name), 'hits-today': get_value(hits_today, endpoint.id), 'hits-week': get_value(hits_week, endpoint.id), 'hits-overall': get_value(hits, endpoint.id), 'median-today': get_value(median_today, endpoint.id), 'median-week': get_value(median_week, endpoint.id), 'median-overall': get_value(median_overall, endpoint.id), 'last-accessed': get_value(access_times, endpoint.name, default=None) } for endpoint in get_endpoints(db_session)]
def get_endpoint_overview(session): """ :param session: session for the database :return: A list of properties for each endpoint that is found in the database """ week_ago = datetime.datetime.utcnow() - datetime.timedelta(days=7) now_local = to_local_datetime(datetime.datetime.utcnow()) today_local = now_local.replace(hour=0, minute=0, second=0, microsecond=0) today_utc = to_utc_datetime(today_local) # First flush last requested info to db cache.flush_cache() error_hits_criterion = and_(Request.status_code >= 400, Request.status_code < 600) hits_today = count_requests_group(session, Request.time_requested > today_utc) hits_today_errors = count_requests_group( session, and_(Request.time_requested > today_utc, error_hits_criterion) ) hits_week = count_requests_group(session, Request.time_requested > week_ago) hits_week_errors = count_requests_group( session, and_(Request.time_requested > week_ago, error_hits_criterion) ) hits = count_requests_group(session) median_today = get_endpoint_data_grouped(session, median, Request.time_requested > today_utc) median_week = get_endpoint_data_grouped(session, median, Request.time_requested > week_ago) median_overall = get_endpoint_data_grouped(session, median) access_times = get_last_requested(session) return [ { 'id': endpoint.id, 'name': endpoint.name, 'monitor': endpoint.monitor_level, 'color': get_color(endpoint.name), 'hits-today': get_value(hits_today, endpoint.id), 'hits-today-errors': get_value(hits_today_errors, endpoint.id), 'hits-week': get_value(hits_week, endpoint.id), 'hits-week-errors': get_value(hits_week_errors, endpoint.id), 'hits-overall': get_value(hits, endpoint.id), 'median-today': get_value(median_today, endpoint.id), 'median-week': get_value(median_week, endpoint.id), 'median-overall': get_value(median_overall, endpoint.id), 'last-accessed': get_value(access_times, endpoint.name, default=None), } for endpoint in get_endpoints(session) ]
def get_api_performance(db_session, endpoints): """ :param db_session: session for the database :param endpoints: a list of endpoints, encoded by their name :return: for every endpoint in endpoints, a list with the performance """ db_endpoints = [get_endpoint_by_name(db_session, end) for end in endpoints] data = get_endpoint_data_grouped(db_session, lambda x: simplify(x, 10)) return [ {'name': end.name, 'values': get_value(data, end.id, default=[])} for end in db_endpoints ]
def test_update_last_accessed(self): """ Test whether the function returns the right values. """ import datetime time = datetime.datetime.utcnow() from flask_monitoringdashboard.database.endpoint import update_last_accessed, get_last_requested from flask_monitoringdashboard.database.count_group import get_value with session_scope() as db_session: update_last_accessed(db_session, NAME) result = get_value(get_last_requested(db_session), NAME) result_utc = to_utc_datetime(result) self.assertTrue((result_utc - time).seconds < 1)
def versions_graph(db_session, endpoint_id, form): times = get_version_data_grouped(db_session, lambda x: simplify(x, 10), Request.endpoint_id == endpoint_id) first_requests = get_first_requests(db_session, endpoint_id, form.get_slider_value()) data = [ boxplot(name=format_version( request.version_requested, get_value(first_requests, request.version_requested)), values=get_value(times, request.version_requested), marker={'color': get_color(request.version_requested)}) for request in first_requests ] layout = get_layout(height=350 + 40 * len(first_requests), xaxis={'title': 'Execution time (ms)'}, yaxis={ 'type': 'category', 'title': 'Version', 'autorange': 'reversed' }, margin=get_margin()) return get_figure(layout=layout, data=data)
def get_2d_version_data(session, endpoint_id, versions, column_data, column): """ :param session: session for the database :param endpoint_id: id of the endpoint :param versions: a list of versions :param column_data: a is of the other column :param column: column from the Request table :return: a dict with 2d information about the version and another column """ first_request = get_first_requests(session, endpoint_id) values = get_two_columns_grouped(session, column, Request.endpoint_id == endpoint_id) data = [[get_value(values, (data, v)) for v in versions] for data in column_data] return { 'versions': [{ 'version': v, 'date': get_value(first_request, v) } for v in versions], 'data': data, }
def overview(): week_ago = datetime.datetime.utcnow() - datetime.timedelta(days=7) now_local = to_local_datetime(datetime.datetime.utcnow()) today_local = now_local.replace(hour=0, minute=0, second=0, microsecond=0) today_utc = to_utc_datetime(today_local) result = [] with session_scope() as db_session: from numpy import median hits_today = count_requests_group(db_session, Request.time_requested > today_utc) hits_week = count_requests_group(db_session, Request.time_requested > week_ago) hits = count_requests_group(db_session) median_today = get_endpoint_data_grouped( db_session, median, Request.time_requested > today_utc) median_week = get_endpoint_data_grouped( db_session, median, Request.time_requested > week_ago) median = get_endpoint_data_grouped(db_session, median) access_times = get_last_requested(db_session) for endpoint in get_endpoints(db_session): result.append({ 'id': endpoint.id, 'name': endpoint.name, 'color': get_color(endpoint.name), 'hits-today': get_value(hits_today, endpoint.id), 'hits-week': get_value(hits_week, endpoint.id), 'hits-overall': get_value(hits, endpoint.id), 'median-today': get_value(median_today, endpoint.id), 'median-week': get_value(median_week, endpoint.id), 'median-overall': get_value(median, endpoint.id), 'last-accessed': get_value(access_times, endpoint.name, default=None) }) version = get_details(db_session)['dashboard-version'] return render_template('fmd_dashboard/overview.html', result=result, is_admin=is_admin(), title='Dashboard Overview', version=version)
def endpoint_graph(): """ Creates a graph with the execution times per endpoint :return: """ with session_scope() as db_session: data = get_endpoint_data_grouped(db_session, lambda x: simplify(x, 10)) values = [ boxplot(get_value(data, end.id, default=[]), name=end.name) for end in get_endpoints(db_session) ] layout = get_layout(height=350 + 40 * len(values), xaxis={'title': 'Execution time (ms)'}, margin=get_margin()) return get_figure(layout, values)
def get_num_requests_data(session, start_date, end_date): """ :param session: session for the database :param start_date: datetime object :param end_date: datetime object and: end_date >= start_date :return: a list of the number of requests for each endpoint and on which day """ numdays = (end_date - start_date).days + 1 days = [start_date + datetime.timedelta(days=i) for i in range(numdays)] hits = count_requests_per_day(session, days) endpoints = get_endpoints(session) data = [{ 'name': end.name, 'values': [get_value(hits_day, end.id) for hits_day in hits] } for end in endpoints] return {'days': [d.strftime('%Y-%m-%d') for d in days], 'data': data}
def version_usage_graph(db_session, form): """ Used for getting a Heatmap with an overview of which endpoints are used in which versions :param db_session: session for the database :param form: instance of SliderForm :return: """ endpoints = get_endpoints(db_session) versions = get_versions(db_session, limit=form.get_slider_value()) requests = [ count_requests_group(db_session, Request.version_requested == v) for v in versions ] total_hits = [] hits = [[]] * len(endpoints) for hits_version in requests: total_hits.append(max(1, sum([value for key, value in hits_version]))) for j in range(len(endpoints)): hits[j] = [0] * len(versions) for i in range(len(versions)): hits[j][i] = get_value(requests[i], endpoints[j].id) * 100 / total_hits[i] layout = get_layout(xaxis={ 'title': 'Versions', 'type': 'category' }, yaxis={ 'type': 'category', 'autorange': 'reversed' }, margin=get_margin()) trace = heatmap(z=hits, x=versions, y=['{} '.format(e.name) for e in endpoints], colorbar={ 'titleside': 'top', 'tickmode': 'array', }) return get_figure(layout=layout, data=[trace])
def users_graph(id, form): """ Return an HTML box plot with a specific number of :param id: get the data for this endpoint only :param form: instance of SliderForm :return: """ with session_scope() as db_session: users = get_users(db_session, id, form.get_slider_value()) times = get_user_data_grouped(db_session, lambda x: simplify(x, 10), Request.endpoint_id == id) data = [boxplot(name=u, values=get_value(times, u)) for u in users] layout = get_layout(height=350 + 40 * len(data), xaxis={'title': 'Execution time (ms)'}, yaxis={ 'type': 'category', 'title': 'User' }) return get_figure(layout, data)
def requests_graph(form): """ Returns a horizontal box plot with the number of requests per day. :param form: must be the form that is obtained by get_daterange_form :return: """ days = form.get_days() with session_scope() as db_session: hits = count_requests_per_day(db_session, days) data = [barplot(x=[get_value(hits_day, end.id) for hits_day in hits], y=days, name=end.name) for end in get_endpoints(db_session)] layout = get_layout( barmode='stack', height=350 + 40 * len(days), showlegend=True, xaxis={'title': 'Number of requests'}, yaxis={'type': 'category'} ) return get_figure(layout=layout, data=data)
def rules(): """ Renders a table with all rules from the user_app. The fmd_dashboard rules are excluded In case of the POST request, the data from the form is validated and processed, such that the required rules are monitored :return: """ if request.method == 'POST': with session_scope() as db_session: endpoint_name = request.form['name'] value = int(request.form['value']) update_endpoint(db_session, endpoint_name, value=value) # Remove wrapper original = getattr(user_app.view_functions[endpoint_name], 'original', None) if original: user_app.view_functions[endpoint_name] = original with session_scope() as db_session: add_decorator(get_endpoint_by_name(db_session, endpoint_name)) return 'OK' with session_scope() as db_session: last_accessed = get_last_requested(db_session) all_rules = [] for rule in get_rules(): db_rule = get_endpoint_by_name(db_session, rule.endpoint) all_rules.append({ 'color': get_color(rule.endpoint), 'rule': rule.rule, 'endpoint': rule.endpoint, 'methods': rule.methods, 'last_accessed': get_value(last_accessed, rule.endpoint, default=None), 'form': get_monitor_form(rule.endpoint, db_rule.monitor_level) }) return render_template('fmd_rules.html', rules=all_rules, information=get_rules_info())
def test_update_last_accessed(session, endpoint, timestamp): update_last_requested(session, endpoint.name, timestamp=timestamp) result = get_value(get_last_requested(session), endpoint.name) assert result == timestamp