def add_fake_data():
    """ Adds data to the database for testing purposes. Module dashboard must be imported locally. """
    from flask_monitoringdashboard.database import session_scope, FunctionCall, MonitorRule, Tests, TestsGrouped
    from flask_monitoringdashboard import config

    # Add functionCalls
    with session_scope() as db_session:
        for i in range(len(EXECUTION_TIMES)):
            call = FunctionCall(endpoint=NAME, execution_time=EXECUTION_TIMES[i], version=config.version,
                                time=TIMES[i], group_by=GROUP_BY, ip=IP)
            db_session.add(call)

    # Add MonitorRule
    with session_scope() as db_session:
        db_session.add(MonitorRule(endpoint=NAME, monitor=True, time_added=datetime.datetime.utcnow(),
                                   version_added=config.version, last_accessed=TIMES[0]))

    # Add Tests
    with session_scope() as db_session:
        db_session.add(Tests(name=NAME, succeeded=True))

    # Add TestsGrouped
    with session_scope() as db_session:
        for test_name in TEST_NAMES:
            db_session.add(TestsGrouped(endpoint=NAME, test_name=test_name))
def get_all_measurement(endpoint):
    """Return all entries with measurements from a given endpoint. Used for creating a histogram. """
    with session_scope() as db_session:
        result = db_session.query(FunctionCall).filter(
            FunctionCall.endpoint == endpoint).all()
        db_session.expunge_all()
        return result
    def run(self):
        # sleep for average * ODC ms
        with session_scope() as db_session:
            average = get_avg_duration(
                db_session,
                self._endpoint.id) * config.outlier_detection_constant
        time.sleep(average / 1000)
        if not self._stopped:
            stack_list = []
            try:
                frame = sys._current_frames()[self._current_thread]
            except KeyError:
                log('Can\'t get the stacktrace of the main thread.')
                return
            in_endpoint_code = False
            # filename, line number, function name, source code line
            for fn, ln, fun, line in traceback.extract_stack(frame):
                if self._endpoint.name == fun:
                    in_endpoint_code = True
                if in_endpoint_code:
                    stack_list.append(
                        'File: "{}", line {}, in "{}": "{}"'.format(
                            fn, ln, fun, line))

            # Set the values in the object
            self._stacktrace = '<br />'.join(stack_list)
            self._cpu_percent = str(
                psutil.cpu_percent(interval=None, percpu=True))
            self._memory = str(psutil.virtual_memory())
Exemple #4
0
 def run(self):
     with session_scope() as db_session:
         update_last_accessed(db_session, endpoint_name=self._endpoint.name)
         add_request(db_session,
                     duration=self._duration,
                     endpoint_id=self._endpoint.id,
                     ip=self._ip)
def get_outliers_sorted(endpoint, sort_column):
    """ Returns a list of all outliers of a specific endpoint. The list is sorted based on the column that is given."""
    with session_scope() as db_session:
        result = db_session.query(Outlier).filter(
            Outlier.endpoint == endpoint).order_by(desc(sort_column)).all()
        db_session.expunge_all()
        return result
def get_data_per_version(version):
    """ Returns all data in the FunctionCall table, grouped by their version. """
    with session_scope() as db_session:
        result = db_session.query(FunctionCall.execution_time, FunctionCall.version). \
            filter(FunctionCall.version == version).all()
        db_session.expunge_all()
        return result
def get_endpoints():
    with session_scope() as db_session:
        result = db_session.query(FunctionCall.endpoint,
                                  func.count(FunctionCall.endpoint).label('cnt')). \
            group_by(FunctionCall.endpoint).order_by(asc('cnt')).all()
        db_session.expunge_all()
        return result
    def get_answer(self, endpoint, requests_criterion, baseline_requests_criterion):
        with session_scope() as session:
            latencies_sample = get_latencies_sample(session, endpoint.id,
                                                    requests_criterion)
            baseline_latencies_sample = get_latencies_sample(
                session, endpoint.id, baseline_requests_criterion
            )

            if len(latencies_sample) == 0 or len(baseline_latencies_sample) == 0:
                return MedianLatencyReportAnswer(
                    is_significant=False,
                    latencies_sample=latencies_sample,
                    baseline_latencies_sample=baseline_latencies_sample,
                )

            median = float(np.median(latencies_sample))
            baseline_median = float(np.median(baseline_latencies_sample))

            percentual_diff = (median - baseline_median) / baseline_median * 100

            _, p, _, _ = median_test(latencies_sample, baseline_latencies_sample)

            is_significant = abs(float(percentual_diff)) > 0 and float(p) < 0.05

            return MedianLatencyReportAnswer(
                is_significant=is_significant,
                percentual_diff=percentual_diff,
                # Sample latencies
                latencies_sample=latencies_sample,
                baseline_latencies_sample=baseline_latencies_sample,
                # Latency medians
                median=median,
                baseline_median=baseline_median,
            )
def add_fake_data():
    """ Adds data to the database for testing purposes. Module flask_monitoringdashboard must be imported locally. """
    from flask_monitoringdashboard.database import session_scope, Request, Endpoint, Outlier
    from flask_monitoringdashboard import config

    # Add requests
    with session_scope() as db_session:
        for i in range(len(REQUESTS)):
            call = Request(id=REQUEST_IDS[i],
                           endpoint_id=ENDPOINT_ID,
                           duration=REQUESTS[i],
                           version_requested=config.version,
                           time_requested=TIMES[i],
                           group_by=GROUP_BY,
                           ip=IP)
            db_session.add(call)

        # Add endpoint
        db_session.add(
            Endpoint(id=ENDPOINT_ID,
                     name=NAME,
                     monitor_level=1,
                     time_added=datetime.datetime.utcnow(),
                     version_added=config.version,
                     last_requested=TIMES[0]))

        # Add Outliers
        for i in range(OUTLIER_COUNT):
            db_session.add(
                Outlier(request_id=i + 1,
                        cpu_percent='[%d, %d, %d, %d]' %
                        (i, i + 1, i + 2, i + 3)))
Exemple #10
0
def get_boxplot_endpoints(endpoint=None, form=None):
    """
    Generates a box plot visualization for the unit test endpoint hits performance results.
    :param endpoint: if specified, generate box plot for a specific endpoint, otherwise, generate for all tests
    :param form: the form that can be used for showing a subset of the data
    :return:
    """
    trace = []
    with session_scope() as db_session:
        if form:
            ids = get_travis_builds(db_session, limit=form.get_slider_value())
        else:
            ids = get_travis_builds(db_session)

        if not ids:
            return None
        for id in ids:
            if endpoint:
                values = get_endpoint_measurements_job(db_session,
                                                       name=endpoint,
                                                       job_id=id)
            else:
                values = get_endpoint_measurements(db_session, suite=id)

            trace.append(boxplot(values=values, label='{} -'.format(id)))

        layout = get_layout(xaxis={'title': 'Execution time (ms)'},
                            yaxis={
                                'title': 'Travis Build',
                                'autorange': 'reversed'
                            })

        return get_figure(layout=layout, data=trace)
def get_last_accessed_times():
    """ Returns a list of all endpoints and their last accessed time. """
    with session_scope() as db_session:
        result = db_session.query(MonitorRule.endpoint,
                                  MonitorRule.last_accessed).all()
        db_session.expunge_all()
        return result
Exemple #12
0
def user_edit():
    """Update the user in the database."""
    user_id = int(request.form['user_id'])
    is_admin = request.form['is_admin'] == 'true'
    if flask.session.get(config.link + '_user_id') == user_id and not is_admin:
        return jsonify({
            'message':
            'Cannot remove the admin permissions from itself.'
        }), BAD_REQUEST_STATUS

    with session_scope() as session:
        try:
            user = session.query(User).filter(User.id == user_id).one()
            user.is_admin = is_admin

            old_password = request.form.get('old_password')
            if old_password is not None:
                if user.check_password(old_password):
                    new_password = request.form['new_password']
                    new_password2 = request.form['new_password2']

                    if new_password != new_password2:
                        return jsonify({'message': "Passwords don't match."
                                        }), BAD_REQUEST_STATUS

                    user.set_password(new_password)
                else:
                    return jsonify({'message': "Old password doesn't match."
                                    }), BAD_REQUEST_STATUS
        except NoResultFound:
            return jsonify({'message':
                            "User ID doesn't exist."}), BAD_REQUEST_STATUS
        except Exception as e:
            return jsonify({'message': str(e)}), BAD_REQUEST_STATUS
    return 'OK'
Exemple #13
0
def make_report():
    arguments = request.json

    try:
        comparison_interval = DateInterval(
            datetime.fromtimestamp(
                int(arguments['comparison_interval']['from'])),
            datetime.fromtimestamp(int(
                arguments['comparison_interval']['to'])))

        compared_to_interval = DateInterval(
            datetime.fromtimestamp(
                int(arguments['compared_to_interval']['from'])),
            datetime.fromtimestamp(int(
                arguments['compared_to_interval']['to'])))

    except Exception:
        return 'Invalid payload', 422

    endpoint_summaries = []
    with session_scope() as db_session:
        for endpoint in get_endpoints(db_session):
            endpoint_summary = make_endpoint_summary(endpoint,
                                                     comparison_interval,
                                                     compared_to_interval)
            endpoint_summaries.append(endpoint_summary)

    return dict(summaries=endpoint_summaries)
Exemple #14
0
def version_ip(endpoint_id):
    """
        input must be a JSON-object, with a list of versions and IP-addresses, such as:
          {
            ip: ['127.0.0.1', '127.0.0.2'],
            versions: ['0.1', '0.2', '0.3']
          }
    :return: A JSON-list for all IP-addresses, with a JSON-list for every version.
        output: {
            data: [
              [10, 11, 12],
              [13, 14, 15]
            ],
            versions: [
              { date: '...', version: '0.1'},
              { date: '...', version: '0.2'},
              { date: '...', version: '0.3'}
            ]
          }
    """
    data = json.loads(request.data)['data']
    versions = data['versions']
    ips = data['ip']

    with session_scope() as db_session:
        return jsonify(get_version_ip_data(db_session, endpoint_id, versions, ips))
Exemple #15
0
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)
Exemple #16
0
def get_overview():
    """
    Get information per endpoint about the number of hits and median execution time
    :return: A JSON-list with a JSON-object per endpoint
    """
    with session_scope() as session:
        return jsonify(get_endpoint_overview(session))
Exemple #17
0
def version_user(endpoint_id):
    """
        input must be a JSON-object, with a list of versions and users, such as:
          {
            users: ['user0', user1],
            versions: ['0.1', '0.2', '0.3']
          }
    :return: A JSON-list for all users, with a JSON-list for every version.
        output: {
            data: [
              [10, 11, 12],
              [13, 14, 15]
            ],
            versions: [
              { date: '...', version: '0.1'},
              { date: '...', version: '0.2'},
              { date: '...', version: '0.3'}
            ]
          }
    """
    data = json.loads(request.data)['data']
    versions = data['versions']
    users = data['users']

    with session_scope() as db_session:
        return jsonify(get_version_user_data(db_session, endpoint_id, versions, users))
Exemple #18
0
def endpoints():
    """
    :return: A JSON-list with information about every endpoint (encoded in a JSON-object)
        For more information per endpoint, see :func: get_overview
    """
    with session_scope() as session:
        return jsonify([row2dict(row) for row in get_endpoints(session)])
Exemple #19
0
def get_json_data_from(time_from, time_to=None):
    """
    The returned data is the data that is encrypted using a security token. This security token is set in the
    configuration.
    :param time_from: (optional) if specified, only the data-values after this date are returned.
                      input must be an timestamp value (utc) (= integer)
                      :param time_to: (optional) if specified, only the data-values before this date are returned.
                      input must be an timestamp value (utc) (= integer)
    :return: all entries from the database. (endpoint-table)
    """
    data = []
    try:
        with session_scope() as db_session:
            time1 = datetime.datetime.utcfromtimestamp(int(time_from))
            time2 = None
            if time_to:
                time2 = datetime.datetime.utcfromtimestamp(int(time_to))
            for entry in get_data_between(db_session, time1, time2):
                # nice conversion to json-object
                data.append({
                    'endpoint_id': entry.endpoint_id,
                    'duration': entry.duration,
                    'time_requested': str(entry.time_requested),
                    'version_requested': entry.version_requested,
                    'group_by': entry.group_by,
                    'ip': entry.ip
                })
        return jwt.encode({'data': json.dumps(data)},
                          config.security_token,
                          algorithm='HS256')
    except ValueError as e:
        return 'ValueError: {}'.format(e)
def add_tests_grouped(json):
    """ Adds endpoint - unit tests combinations to the database. """
    with session_scope() as db_session:
        for combination in json:
            db_session.add(
                TestsGrouped(endpoint=combination['endpoint'],
                             test_name=combination['test_name']))
Exemple #21
0
def get_json_details():
    """
    Some details about the deployment, such as the current version, etc...
    :return: a json-object with the details.
    """
    with session_scope() as db_session:
        return jsonify(get_details(db_session))
def grouped_profiler(endpoint_id):
    with session_scope() as db_session:
        details = get_endpoint_details(db_session, endpoint_id)
        requests = get_grouped_profiled_requests(db_session, endpoint_id)
        db_session.expunge_all()
    total_duration = sum([r.duration for r in requests])
    histogram = defaultdict(list)  # path -> [list of values]
    path_hash = PathHash()

    for r in requests:
        for index, stack_line in enumerate(r.stack_lines):
            key = path_hash.get_stacklines_path(r.stack_lines, index)
            histogram[key].append(stack_line.duration)

    table = []
    for key, duration_list in sorted(histogram.items(),
                                     key=lambda row: row[0]):
        table.append(
            GroupedStackLine(indent=path_hash.get_indent(key) - 1,
                             code=path_hash.get_code(key),
                             values=duration_list,
                             total_sum=total_duration,
                             total_hits=len(requests)))
    for index, item in enumerate(table):
        table[index].compute_body(index, table)

    sunburst = json.dumps(table_to_json(table))
    return render_template('fmd_dashboard/profiler_grouped.html',
                           details=details,
                           table=table,
                           sunburst=sunburst,
                           title='Grouped Profiler results for {}'.format(
                               details['endpoint']))
Exemple #23
0
def get_boxplot_tests(form=None):
    """
    Generates a box plot visualization for the unit test performance results.
    :param form: the form that can be used for showing a subset of the data
    :return:
    """
    trace = []
    with session_scope() as db_session:
        if form:
            suites = get_test_suites(db_session, limit=form.get_slider_value())
        else:
            suites = get_test_suites(db_session)

        if not suites:
            return None
        for s in suites:
            values = get_suite_measurements(db_session, suite=s)
            trace.append(boxplot(values=values, label='{} -'.format(s)))

        layout = get_layout(xaxis={'title': 'Execution time (ms)'},
                            yaxis={
                                'title': 'Travis Build',
                                'autorange': 'reversed'
                            })

        return get_figure(layout=layout, data=trace)
Exemple #24
0
def submit_test_results():
    """
    Endpoint for letting Travis submit its unit test performance results to the Dashboard.
    :return: nothing, 204 (No Content)
    """
    results = request.get_json()
    travis_job_id = -1
    if results['travis_job']:
        travis_job_id = results['travis_job']
    app_version = '-1'
    if 'app_version' in results:
        app_version = results['app_version']
    test_runs = results['test_runs']
    endpoint_hits = results['endpoint_exec_times']

    with session_scope() as db_session:
        for test_run in test_runs:
            time = datetime.datetime.strptime(test_run['time'],
                                              '%Y-%m-%d %H:%M:%S.%f')
            add_or_update_test(db_session, test_run['name'],
                               test_run['successful'], time, app_version)
            add_test_result(db_session, test_run['name'],
                            test_run['exec_time'], time, app_version,
                            travis_job_id, test_run['iter'])

        for endpoint_hit in endpoint_hits:
            add_endpoint_hit(db_session, endpoint_hit['endpoint'],
                             endpoint_hit['exec_time'],
                             endpoint_hit['test_name'], app_version,
                             travis_job_id)

    return '', 204
Exemple #25
0
def grouped_profiler(endpoint_id):
    with session_scope() as session:
        changed_functions = get_lines_changed_since_version('9b0948', '9c72e0')
        previous_version = get_grouped_profiler(session, endpoint_id, '9b0948')
        new_version = jsonify(
            get_grouped_profiler(session, endpoint_id, '9c72e0',
                                 previous_version, changed_functions))
        return new_version
Exemple #26
0
 def test_get_date_of_first_request(self):
     """
         Test whether the function returns the right values.
     """
     from flask_monitoringdashboard.database.request import get_date_of_first_request
     with session_scope() as db_session:
         self.assertEqual(get_date_of_first_request(db_session),
                          int(time.mktime(TIMES[0].timetuple())))
Exemple #27
0
def endpoint():
    # if session_scope is imported at the top of the file, the database config won't take effect
    from flask_monitoringdashboard.database import session_scope
    with session_scope() as db_session:
        print(db_session.bind.dialect.name)

    print("Hello, world")
    return 'Ok'
Exemple #28
0
 def test_get_endpoint_measurements(self):
     with session_scope() as db_session:
         self.assertEqual(get_endpoint_measurements(db_session, "1"), [0])
         db_session.add(TestEndpoint(endpoint_id=ENDPOINT_ID, test_id=1, duration=1234, app_version="1.0",
                                     travis_job_id="1", time_added=datetime.datetime.utcnow()))
         db_session.add(TestEndpoint(endpoint_id=ENDPOINT_ID, test_id=1, duration=2345, app_version="1.0",
                                     travis_job_id="1", time_added=datetime.datetime.utcnow()))
         self.assertEqual(get_endpoint_measurements(db_session, "1"), [1234, 2345])
def view_csv():
    csv = [','.join(CSV_COLUMNS)]
    with session_scope() as db_session:
        for entry in get_data(db_session):
            csv.append(
                ','.join([str(entry.__getattribute__(c))
                          for c in CSV_COLUMNS]) + '\n')
    return render_template('fmd_export-data.html', data=csv)
Exemple #30
0
def users_list():
    """
    :return: A JSON-object with configuration details
    """
    if not is_admin():
        return jsonify([])
    with session_scope() as session:
        return jsonify(get_all_users(session))