Skip to content

Commit 18d5aaf

Browse files
authored
Merge pull request #23 from mircealungu/users
Users
2 parents d8cd94d + 2378f16 commit 18d5aaf

16 files changed

+497
-501
lines changed

dashboard/database/function_calls.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,14 @@ def get_data_per_version(version):
6969
return result
7070

7171

72-
def get_versions():
72+
def get_versions(end=None):
7373
with session_scope() as db_session:
7474
result = db_session.query(FunctionCall.version,
7575
func.min(FunctionCall.time).label('startedUsingOn')). \
76-
group_by(FunctionCall.version).order_by(asc('startedUsingOn')).all()
77-
db_session.expunge_all()
78-
return result
76+
filter((FunctionCall.endpoint == end) | (end is None)).group_by(FunctionCall.version).order_by(
77+
asc('startedUsingOn')).all()
78+
db_session.expunge_all()
79+
return result
7980

8081

8182
def get_data_per_endpoint(end):

dashboard/forms.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from flask_wtf import FlaskForm
2-
from wtforms import validators
3-
from wtforms import SubmitField, PasswordField, StringField
2+
from wtforms import validators, SubmitField, PasswordField, StringField, SelectMultipleField
43

54

65
class MonitorDashboard(FlaskForm):
@@ -26,4 +25,4 @@ class ChangeSetting(FlaskForm):
2625

2726
class RunTests(FlaskForm):
2827
""" Used for serving a login form on /{{ link }}/testmonitor. """
29-
submit = SubmitField('Run selected tests')
28+
submit = SubmitField('Run selected tests')

dashboard/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
def get_session_id():
1111
# implement here your own custom function
12-
return "12345"
12+
return "1234"
1313

1414
dashboard.config.get_group_by = get_session_id
1515
dashboard.bind(app=user_app)

dashboard/routings/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import dashboard.routings.setup
1212
import dashboard.routings.result
1313
import dashboard.routings.export_data
14+
import dashboard.routings.measurements
1415

1516
# Provide a secret-key for using WTF-forms
1617
if user_app.secret_key is None:
@@ -26,4 +27,4 @@ def static(filename):
2627
# All rules below are for viewing the dashboard-pages
2728
@blueprint.route('/')
2829
def index():
29-
return redirect(url_for('dashboard.measurements'))
30+
return redirect(url_for('dashboard.measurements', index=0))

dashboard/routings/measurements.py

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import datetime
2+
3+
import plotly
4+
import plotly.graph_objs as go
5+
import pygal
6+
from flask import session, render_template
7+
8+
from dashboard import blueprint, config
9+
from dashboard.database.endpoint import get_last_accessed_times, get_num_requests
10+
from dashboard.database.function_calls import get_times, get_reqs_endpoint_day, get_versions, get_data_per_version, \
11+
get_endpoints, get_data_per_endpoint
12+
from dashboard.security import secure
13+
14+
15+
@blueprint.route('/measurements/<int:index>')
16+
@secure
17+
def measurements(index):
18+
"""
19+
Returns a page with one of the 4 graphs below:
20+
TODO: rewrite graph at index==1 to plotly, such that function can be simplified
21+
:param index:
22+
:return:
23+
"""
24+
25+
# returns a page with the number of requests per endpoint
26+
if index == 1:
27+
page = 'measurements/measurements_pygal.html'
28+
graph = get_stacked_bar()
29+
30+
# returns a page with the execution times per version
31+
elif index == 2:
32+
page = 'measurements/measurements_plotly.html'
33+
graph = get_boxplot_per_version()
34+
35+
# returns a page with the execution time per endpoint
36+
elif index == 3:
37+
page = 'measurements/measurements_plotly.html'
38+
graph = get_boxplot_per_endpoint()
39+
40+
# default: return a page with a heatmap of number of requests
41+
else:
42+
index = 0
43+
page = 'measurements/measurements_plotly.html'
44+
graph = get_heatmap(end=None)
45+
46+
return render_template(page, link=config.link, curr=2, times=get_times(),
47+
access=get_last_accessed_times(), session=session, index=index, graph=graph)
48+
49+
50+
def get_stacked_bar():
51+
data = get_reqs_endpoint_day()
52+
graph = pygal.graph.horizontalstackedbar.HorizontalStackedBar(height=100 + len(data) * 7)
53+
graph.title = 'Number of requests per endpoint per day'
54+
graph.x_labels = []
55+
endpoints = []
56+
for d in data:
57+
if d.newTime not in graph.x_labels:
58+
graph.x_labels.append(d.newTime)
59+
if d.endpoint not in endpoints:
60+
endpoints.append(d.endpoint)
61+
62+
graph.x_labels.sort(reverse=True)
63+
for e in endpoints:
64+
lst = []
65+
for t in graph.x_labels:
66+
found = False
67+
for d in data:
68+
if e == d.endpoint and t == d.newTime:
69+
found = True
70+
lst.append(d.cnt)
71+
if not found:
72+
lst.append(0)
73+
graph.add(e, lst)
74+
75+
return graph.render_data_uri()
76+
77+
78+
def get_boxplot_per_version():
79+
"""
80+
Creates a graph with the execution times per version
81+
:return:
82+
"""
83+
versions = get_versions()
84+
85+
data = []
86+
for v in versions:
87+
values = [c.execution_time for c in get_data_per_version(v.version)]
88+
data.append(go.Box(x=values, name="{0} {1}".format(v.version, v.startedUsingOn.strftime("%b %d %H:%M"))))
89+
90+
layout = go.Layout(
91+
autosize=False,
92+
width=900,
93+
height=350 + 40 * len(versions),
94+
plot_bgcolor='rgba(249,249,249,1)',
95+
showlegend=False,
96+
title='Execution time for every version',
97+
xaxis=dict(title='Execution time (ms)'),
98+
yaxis=dict(tickangle=-50, autorange='reversed')
99+
)
100+
return plotly.offline.plot(go.Figure(data=data, layout=layout), output_type='div', show_link=False)
101+
102+
103+
def get_boxplot_per_endpoint():
104+
"""
105+
Creates a graph with the execution times per endpoint
106+
:return:
107+
"""
108+
endpoints = [str(e.endpoint) for e in get_endpoints()]
109+
110+
data = []
111+
for e in endpoints:
112+
values = [c.execution_time for c in get_data_per_endpoint(e)]
113+
if len(e) > 16:
114+
e = '...' + e[-14:]
115+
data.append(go.Box(x=values, name=e))
116+
117+
layout = go.Layout(
118+
autosize=False,
119+
width=900,
120+
height=350 + 40 * len(endpoints),
121+
plot_bgcolor='rgba(249,249,249,1)',
122+
showlegend=False,
123+
title='Execution time for every endpoint',
124+
xaxis=dict(title='Execution time (ms)'),
125+
yaxis=dict(tickangle=-45)
126+
)
127+
return plotly.offline.plot(go.Figure(data=data, layout=layout), output_type='div', show_link=False)
128+
129+
130+
def get_heatmap(end):
131+
# list of hours: 1:00 - 23:00
132+
hours = ['0' + str(hour) + ':00' for hour in range(0, 10)] + \
133+
[str(hour) + ':00' for hour in range(10, 24)]
134+
135+
data = get_num_requests(end)
136+
# list of days (format: year-month-day)
137+
days = [str(d.newTime[:10]) for d in data]
138+
# remove duplicates and sort the result
139+
days = sorted(list(set(days)))
140+
if len(days) > 0:
141+
first_day = max(datetime.datetime.strptime(days[0], '%Y-%m-%d'),
142+
datetime.datetime.now() - datetime.timedelta(days=30))
143+
last_day = datetime.datetime.strptime(days[len(days)-1], '%Y-%m-%d')
144+
else:
145+
first_day = datetime.datetime.now() - datetime.timedelta(days=30)
146+
last_day = datetime.datetime.now()
147+
148+
# create empty 2D-dictionary with the keys: [hour][day]
149+
requests = {}
150+
for hour in hours:
151+
requests_day = {}
152+
for day in days:
153+
requests_day[day] = 0
154+
requests[hour] = requests_day
155+
156+
# add data to the dictionary
157+
for d in data:
158+
day = str(d.newTime[:10])
159+
hour = str(d.newTime[11:16])
160+
requests[hour][day] = d.count
161+
162+
# create a 2D-list out of the dictionary
163+
requests_list = []
164+
for hour in hours:
165+
day_list = []
166+
for day in days:
167+
day_list.append(requests[hour][day])
168+
requests_list.append(day_list)
169+
170+
layout = go.Layout(
171+
autosize=False,
172+
width=900,
173+
height=800,
174+
plot_bgcolor='rgba(249,249,249,1)',
175+
showlegend=False,
176+
title='Heatmap of number of requests',
177+
xaxis=go.XAxis(range=[first_day, last_day],
178+
title='Date'),
179+
yaxis=dict(title='Time', autorange='reversed')
180+
)
181+
182+
trace = go.Heatmap(z=requests_list, x=days, y=hours)
183+
return plotly.offline.plot(go.Figure(data=[trace], layout=layout), output_type='div', show_link=False)

0 commit comments

Comments
 (0)