From a6fe7bf1c7c7052b9f20e16b772ebe1e2929442c Mon Sep 17 00:00:00 2001 From: no Date: Fri, 29 Nov 2024 14:00:20 +0100 Subject: [PATCH] first commit --- README.md | 0 app/__init__.py | 25 ++++ app/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 916 bytes app/__pycache__/utils.cpython-310.pyc | Bin 0 -> 484 bytes .../__pycache__/fuenf_minuten.cpython-310.pyc | Bin 0 -> 2408 bytes .../__pycache__/max_time_diff.cpython-310.pyc | Bin 0 -> 1755 bytes app/api/__pycache__/tag_nacht.cpython-310.pyc | Bin 0 -> 1098 bytes app/api/fuenf_minuten.py | 78 ++++++++++ app/api/max_time_diff.py | 60 ++++++++ app/api/tag_nacht.py | 24 +++ app/static/js/fuenf_minuten.js | 137 ++++++++++++++++++ app/static/js/max_time_diff.js | 43 ++++++ app/static/js/tag_nacht.js | 19 +++ app/templates/index.html | 52 +++++++ app/utils.py | 10 ++ run.py | 7 + 16 files changed, 455 insertions(+) create mode 100644 README.md create mode 100644 app/__init__.py create mode 100644 app/__pycache__/__init__.cpython-310.pyc create mode 100644 app/__pycache__/utils.cpython-310.pyc create mode 100644 app/api/__pycache__/fuenf_minuten.cpython-310.pyc create mode 100644 app/api/__pycache__/max_time_diff.cpython-310.pyc create mode 100644 app/api/__pycache__/tag_nacht.cpython-310.pyc create mode 100644 app/api/fuenf_minuten.py create mode 100644 app/api/max_time_diff.py create mode 100644 app/api/tag_nacht.py create mode 100644 app/static/js/fuenf_minuten.js create mode 100644 app/static/js/max_time_diff.js create mode 100644 app/static/js/tag_nacht.js create mode 100644 app/templates/index.html create mode 100644 app/utils.py create mode 100644 run.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..f0d7be6 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,25 @@ +from flask import Flask, render_template + +def create_app(): + app = Flask(__name__) + app.config.from_mapping( + MYSQL_HOST='192.168.132.195', + MYSQL_USER='flaskuser', + MYSQL_PASSWORD='password', + MYSQL_DB='otrs', + WEB_SERVICE_ID=13 + ) + + from .api.tag_nacht import tag_nacht_bp + from .api.max_time_diff import max_time_diff_bp + from .api.fuenf_minuten import fuenf_minuten_bp + + app.register_blueprint(tag_nacht_bp) + app.register_blueprint(max_time_diff_bp) + app.register_blueprint(fuenf_minuten_bp) + + @app.route('/') + def index(): + return render_template('index.html') + + return app diff --git a/app/__pycache__/__init__.cpython-310.pyc b/app/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7eecc05d10ad6d0ddbbb78251fae132f0a1e264 GIT binary patch literal 916 zcmY+C-A>d%6vxj@+uc&SESi{T;+2UcHL;t8Xe1#-VV4L|K&levX436UmqNdo&LVDh zui(~4Fp*0i#uwe=}L5VF3XA`MKUd#{hrT;_koz@D>1y zrvSi!p%@ZGP=X0Yz%bL!fM`tjz%ee=IR}@f2z5Eij?y*%vU7M%aniX4yPLT%=-W*y{%J_-9FO%3oLIZ%`Ak-76 zK9_SXk!7+~5qSBH_X;kKqky;kJa17NrIDo6&A*pMCG$vCP^C;fd=d!mOHTbfcbDQU z@Z)0Ht#&!KPQX&Cj19f~ZWiJ#|D+9wS^kK7voq6Prufy&*3Ak?#& zJC+Q>#0wvdHPY$06}O#s+*bYfKWD$f<*>c=hPJB7@pBx8e^FRSY>bO4wI G8~+FNrrRL^ literal 0 HcmV?d00001 diff --git a/app/__pycache__/utils.cpython-310.pyc b/app/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a93f23d8126da04f71a4b75ce2cb40f871a8546f GIT binary patch literal 484 zcmYjO%TB{E5F95?2+)E!_J+hM63`z&h)0n?;@N-@;ZUWqDJf|jY!}o!SNIQp$yZMN z0^)$22IyMy&RXm7cvdu<3jlEYb~M-~z=thn!vU}ZK&=8`U?fLO7?_hgBR6&ln9Jx3 zV#-K_(EGG^PeWoB)3KDi(7mKA(^*0rK7f5ox(+~NNQRDfhm?^Ps_fL+tut+bd9O4= z=%1Q}lbh(`xOaFKUH;;$=%8zsrswCoQFMLQ?U-O%clJVR=)F+d(6Qpu1ZASsvydzf zSfZ1DqIl>TZ!}Slc|4zrqTs0((#+LRS__PyisCLCyhApD>GrkOmO|+EU7o0ijc49h zTs~zfZzpBh9_uVuo8`o;47l#Gey?WBL_zJ(8`cIA)XV>t%K$hMbJjScu esFYNV|01Sn$uVFx}Ds@E8F2E&vc9$b&XIKyBqfX{!fnJ9UskKop{S>9%&DA)tt)XojST z_F6sAseYU#8KRTyYlY-U>J{|SL5|GSp^$$k_bH^}?4}pe4s(4GXO4N`yUo)$!|3yn zauLrsA!F1Rmfh*RQ{(~^Uu#iekweP~e4jeP4g7ev8B)J#wOv0H)bAS0m*fJ9b0PDr z4x>%?zFZkzOUK zfzne(QkrN3rKd)~ZbyjU5vpXsMSWBUk?KP)6{XJ71L&nmwx>n#21qVa-oRV6mx)j! zsfnZujm$)uH}F>JBLqSt`ADCVW<};$C&nCH=(_i!^jS92F7#0*(xZ&*o7zA@5T(y@ z1L$RiMy`xJUX8MSIg>h@82|#Il56DpD~Pfs=%YT`hdQJ{atW%#1zeZZ&wrMxLva-6e zGMpSL9(=L-@XI(&84FnW001^!At>g-NpR%hx^%dNZI5F+bdIp;lcka^!Zx-;e)89E zM;`Tyc3lO?VT|#9xv_(#UyFNz;CQ2s7m^9t>gKMw)xf2VhG}hAYkM1w1&2{v&;-dM zzB~VHX}-NQPw@QC>b!fmAeWDwE#j@}(@JCE-cZeKpSNAk-N3h;AoRs}o9$Y454T*4 z(8I9RqRgVcV5j5h{T;Jr;uCtvDSP2M)N%=agy;F#0OO5H2~Q!zn`UF*G%I+XCsR|l zU)QQnpWw}B6PSsc!eTPmo|lC7VICUgJ+t1}*n6^3DlP1lD^DBdB3^jRf)l*@2q)v` z_+eoY&-22Eh#Ciy5V0^~{leGM!-T&VHk(AeRjbzP_?v3EGL@~VjNO-sAYr>bVNtdZ z5G~tod9U2S_g7>a<4ORus85+K0yb6;6Z4-;NbpJQcx{}jLb7la-I(d(rSr0}Yu2~S zg|Uto-#<5tc;)|2R1)OaeX{4Sx!oADHF1oqm5J2^1b#GSGf^jQs@_Kyk%PD(khOP z%bG5(f4e)fr^$LsFb^Gva^4I*@3h#}Ym|qc;HwUrdcI|ukaeprU+>!h(1HlQpXs3p z5txGr5i|!x`9=9zd9KurR*EaJ%7PR2F#sgp`SLOg z0@l^8QpsW~Cz0gKZ~v1O8?SaSlu z>9*p`h~ZdoQsErgo)@PbFW@xJnlByNNvf>M1uM+3y!1FLJ41F?k_}}sX1C;LI!Upt zuNM!!WHioSJobr{VZ+SDh)!5!H>E!v05nNS2>|kH9vR3$x{^nls-u)@d}1I&HP8*D zD4L=pW&G35bzN6;NLOyChN3G5x`p(glz%FPnK+$fhDnx(j7XY>6r@ApdVENcZdtzF wrj`|7y_5*+uoI_Q5DJ>Wn}VDi0f{@-*V+LIJ-RLr5|@7;ZbBXzN?tM0zxcO~iU0rr literal 0 HcmV?d00001 diff --git a/app/api/__pycache__/max_time_diff.cpython-310.pyc b/app/api/__pycache__/max_time_diff.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c9891b6f860288fd5fecd25fc40aaacce0069fd GIT binary patch literal 1755 zcmb7E&2HO95T50qC`w|S0xe=7XtzZJSb!ZFX?tke1hp+15#XP~GNMKog66Jdx)iDG zF6$pqMFIEfCrAreKrcP^8TuC6V^4ks11XB76j@HtLzlpcvorh6H{Xbp)@lv_0Q#fV z|EmP>w=(9J2>{;!0N(-t0tCe{KwUJ@y4pbR>I0)|ARrpiV{>42Ed&%1gO-R%tP8zs zQ~Rh)O2j7R3ynC$_!-Vo*CCZQ)T>u2Pu-B^^*EzL79~QKj(D0xy;E6Y^kqi5kd-iF zj3&YlhQljOT|n|~p9-HG_+gqPG!#*q$l4${@kKPCK8bq0Gq-Wet|RGWEcS2krMQ20C!_#x%teAN{IP`YfW%I_lp0Y~UkBWR39Z{D>r8lmaAPK>cO(x#S4 ztg$xIb6_9lh<_?{r9gzvQ5%GD4kIHsF3mBFOi~_MIlKbmRmd7wE=f^oq=3m`CZestQ?-(z$P z^@Sbja1k)!lR!{u(}Yakrl+beXXfhab#9l&Hnt{j$ILP?%pT8Z(GW87)&Kf|*>0A(}@DaUJV zyi~Z=YI|GW#y+0eYK4pjf)<2S@T3X_vwSOT%Uf$M&BfO7?sIPsFYWF%y*<4CVjici zfRqI9!tA%Uz4rdv_P5Q}=H^n{+t}S{F3;ax{(qT@RI{RIj5qgow{bu62|dXAead{A z2zEMicb<8B9zLcAoU$LHkopn9Pw)di3&417r#VjxuY3C)&)dNdc;TAH){7fcS?8p? zss1f;1+f|5X_E?&38$G0KY6!r+iTw~%>pK=)%tJD`d0i9u6N(RH7|Tl!!#kBxhn3C3aK#z0HhJHK9_o*3Z^SxNgY~Y#(2tPiJs6f z6O^f;DXlO~dQo56Ju1S(G@;TA3{{6~LyBoo9*a(Kv?GgEK zc*<-5P|EP908rJc$VD!)wJNeS8yUKL*F~Ck5822@3%Z7^;&EPUmWI^hymn0+-ADFM z+CMw>iZqMNObzXcSW3Z(HfAQGm`~KReLo2X)c57W?Is)yrO8sIry^F=G`D@Cl(D}a Wq$G>!Q`JVUCiXq3B3G+wF8UX264xyN literal 0 HcmV?d00001 diff --git a/app/api/__pycache__/tag_nacht.cpython-310.pyc b/app/api/__pycache__/tag_nacht.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa5bc6f04486ee20bcc8d651bd96861a2ede7381 GIT binary patch literal 1098 zcmZXU&u`l{6vrPa%T}B;LyI1o!wO!CRQnOHr}mHrOKfck&^m*aESP|SP()f$D~T#e zt#u*ql3jP$y$Acae~H(g@+Y*XfhrIi*gFu9cu(K=K70=nckc870RH@Nl77MfAMIt` zTmbkH0MrNo7%-GWfg)7k2p3M|AYhm|d8cqA7Xe4C!@JC7-M^iv$9oHp^_GZvtn(LK zqiBO|gy8pYtiJDZO7dy;?lT%B>m(h3mS$*ajsZZ!HO!%b1zN%!F*L^w zTHpq2=T(Q{9hjmeM$n*zyM(#Zz@obZ1iHr@%hNa`xJK6~1m7LUTL_>}2q9tcA{d^L z*0(l141?9p+Qo4&Cda4elgEkVvF21~1^3BOaCQ*{WAc<7jz{FlGjeA0c1Q7S_g2hW z@FEPz?l?=Y^ePaHN8~UhR*6X?q*Z+X|Ix^HSOXQn5)s&lPY5b`UF(*pooNNrmOd#Ho% zZ+gf>_t4ny8@EN2w&hm)OL@1}S+2e`=uuk61*g<(-2&0e%D7V4cCG$e&GrdxVdL!= Wg4H=cu%l4+$8jIF&^Gq)Hu?`A`V#v9 literal 0 HcmV?d00001 diff --git a/app/api/fuenf_minuten.py b/app/api/fuenf_minuten.py new file mode 100644 index 0000000..f9d8700 --- /dev/null +++ b/app/api/fuenf_minuten.py @@ -0,0 +1,78 @@ +from flask import Blueprint, jsonify, request, current_app +from ..utils import get_db_connection + +fuenf_minuten_bp = Blueprint('fuenf_minuten', __name__, url_prefix='/fuenf_minuten') + +@fuenf_minuten_bp.route('/', strict_slashes=False) +def fuenf_minuten(): + # Abrufen der Filterparameter aus der Anfrage + start_date = request.args.get('start_date') + end_date = request.args.get('end_date') + start_time = request.args.get('start_time', '00:00') + end_time = request.args.get('end_time', '23:59') + + if not start_date or not end_date: + return jsonify({'error': 'Bitte sowohl Start- als auch End-Datum auswählen.'}) + + # Aufbau der Verbindung zur Datenbank + conn = get_db_connection() + cursor = conn.cursor() + + # SQL-Abfrage + query = """ + WITH time_slots AS ( + SELECT DATE_FORMAT(create_time, '%Y-%m-%d %H:%i') AS time_slot, COUNT(*) AS transmission_count + FROM gi_debugger_entry + WHERE webservice_id = %s + AND create_time BETWEEN %s AND %s + GROUP BY time_slot + ), + all_times AS ( + SELECT DATE_FORMAT(TIMESTAMPADD(MINUTE, (@row := @row + 5), %s), '%Y-%m-%d %H:%i') AS time_slot + FROM (SELECT @row := -5) AS vars + CROSS JOIN ( + SELECT 1 AS dummy + FROM gi_debugger_entry + LIMIT 100000 + ) AS generator + WHERE TIMESTAMPADD(MINUTE, @row, %s) <= %s + ) + SELECT all_times.time_slot, COALESCE(time_slots.transmission_count, 0) AS transmission_count + FROM all_times + LEFT JOIN time_slots ON all_times.time_slot = time_slots.time_slot + ORDER BY all_times.time_slot; + """ + start_datetime = f"{start_date} {start_time}" + end_datetime = f"{end_date} {end_time}" + + # Debugging: Ausgabe der Parameter + print(f"Start datetime: {start_datetime}") + print(f"End datetime: {end_datetime}") + print(f"Executing query for WEB_SERVICE_ID: {current_app.config['WEB_SERVICE_ID']}") + + try: + # Ausführen der SQL-Abfrage + cursor.execute(query, ( + current_app.config['WEB_SERVICE_ID'], + start_datetime, + end_datetime, + start_datetime, + start_datetime, + end_datetime + )) + results = cursor.fetchall() + + # Debugging: Ausgabe der Ergebnisse + print("SQL query executed successfully.") + print("Results:", results) + + conn.close() + + # Formatierung der Ergebnisse für die API-Antwort + return jsonify([{'time_slot': row[0], 'transmission_count': row[1]} for row in results]) + + except Exception as e: + # Fehlerbehandlung und Debugging + conn.close() + print("Error during SQL execution:", str(e)) + return jsonify({'error': str(e)}) diff --git a/app/api/max_time_diff.py b/app/api/max_time_diff.py new file mode 100644 index 0000000..cea4695 --- /dev/null +++ b/app/api/max_time_diff.py @@ -0,0 +1,60 @@ +from flask import Blueprint, jsonify, request, current_app +from ..utils import get_db_connection + +max_time_diff_bp = Blueprint('max_time_diff', __name__, url_prefix='/max_time_diff') + +@max_time_diff_bp.route('/', strict_slashes=False) +def max_time_diff(): + start_date = request.args.get('start_date') + end_date = request.args.get('end_date') + start_time = request.args.get('start_time', '00:00') + end_time = request.args.get('end_time', '23:59') + + if not start_date or not end_date: + return jsonify({'error': 'Bitte sowohl Start- als auch End-Datum auswählen.'}) + + conn = get_db_connection() + cursor = conn.cursor() + + # Angepasste SQL-Abfrage + query = """ + WITH time_differences AS ( + SELECT + create_time AS start_time, + LEAD(create_time) OVER (ORDER BY create_time) AS end_time, + TIMESTAMPDIFF(SECOND, create_time, LEAD(create_time) OVER (ORDER BY create_time)) AS time_diff + FROM gi_debugger_entry + WHERE webservice_id = %s + AND create_time BETWEEN %s AND %s + ) + SELECT start_time, end_time, time_diff + FROM time_differences + WHERE time_diff = ( + SELECT MAX(time_diff) + FROM time_differences + ); + """ + start_datetime = f"{start_date} {start_time}" + end_datetime = f"{end_date} {end_time}" + + try: + cursor.execute(query, (current_app.config['WEB_SERVICE_ID'], start_datetime, end_datetime)) + result = cursor.fetchone() + conn.close() + + # Ergebnis zurückgeben + if result and result[2] is not None: + return jsonify({ + 'max_time_diff_seconds': result[2], + 'start_time': result[0], + 'end_time': result[1] + }) + else: + return jsonify({ + 'max_time_diff_seconds': 0, + 'start_time': None, + 'end_time': None + }) + except Exception as e: + conn.close() + return jsonify({'error': str(e)}) diff --git a/app/api/tag_nacht.py b/app/api/tag_nacht.py new file mode 100644 index 0000000..a71c9b1 --- /dev/null +++ b/app/api/tag_nacht.py @@ -0,0 +1,24 @@ +from flask import Blueprint, jsonify, current_app +from ..utils import get_db_connection + +tag_nacht_bp = Blueprint('tag_nacht', __name__, url_prefix='/tag_nacht') + +@tag_nacht_bp.route('/') +def tag_nacht(): + conn = get_db_connection() + cursor = conn.cursor() + query = """ + SELECT + CASE + WHEN HOUR(create_time) BETWEEN 7 AND 18 THEN 'Day' + ELSE 'Night' + END AS time_period, + COUNT(*) AS transmission_count + FROM gi_debugger_entry + WHERE webservice_id = %s + GROUP BY time_period + """ + cursor.execute(query, (current_app.config['WEB_SERVICE_ID'],)) + results = cursor.fetchall() + conn.close() + return jsonify([{'time_period': row[0], 'transmission_count': row[1]} for row in results]) diff --git a/app/static/js/fuenf_minuten.js b/app/static/js/fuenf_minuten.js new file mode 100644 index 0000000..7c24fb4 --- /dev/null +++ b/app/static/js/fuenf_minuten.js @@ -0,0 +1,137 @@ +// Globale Variable für den Chart +let fuenfMinutenChart; + +// Funktion zum Abrufen und Aktualisieren des Charts +function fetchAndUpdateChart() { + const startDate = document.getElementById('startDate').value; + const endDate = document.getElementById('endDate').value; + const startTime = document.getElementById('startTime').value || '00:00'; + const endTime = document.getElementById('endTime').value || '23:59'; + + if (!startDate || !endDate) { + alert('Bitte sowohl Start- als auch End-Datum auswählen!'); + return; + } + + fetch(`/fuenf_minuten?start_date=${startDate}&end_date=${endDate}&start_time=${startTime}&end_time=${endTime}`) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then(data => { + if (!Array.isArray(data)) { + throw new Error('Ungültige Daten vom Server.'); + } + + console.log('5-Minuten-Daten:', data); + + const labels = data.map(item => item.time_slot); + const values = data.map(item => item.transmission_count); + + // Farben für Balken (rot für 0-Werte, blau für andere Werte) + const backgroundColors = values.map(value => value === 0 ? 'rgba(255, 99, 132, 0.5)' : 'rgba(54, 162, 235, 0.5)'); + const borderColors = values.map(value => value === 0 ? 'rgba(255, 99, 132, 1)' : 'rgba(54, 162, 235, 1)'); + + const ctx = document.getElementById('fuenfMinutenChart').getContext('2d'); + + // Zerstöre den bestehenden Chart, falls vorhanden + if (fuenfMinutenChart) { + fuenfMinutenChart.destroy(); + } + + // Erstelle den neuen Chart + fuenfMinutenChart = new Chart(ctx, { + type: 'bar', + data: { + labels: labels, + datasets: [{ + label: `Übertragungen`, + data: values, + backgroundColor: backgroundColors, + borderColor: borderColors, + borderWidth: 1 + }] + }, + options: { + scales: { + x: { + title: { + display: true, + text: 'Zeit' + } + }, + y: { + title: { + display: true, + text: 'Anzahl' + }, + beginAtZero: true + } + } + } + }); + }) + .catch(err => console.error('Fehler bei der 5-Minuten-Datenabfrage:', err)); +} + +// Funktion, um Standardwerte für Datum und Zeit zu setzen +function setDefaultDateTime() { + const now = new Date(); + const yesterday = new Date(); + yesterday.setDate(now.getDate() - 1); + + // Standardwerte für Start- und Enddatum + document.getElementById('startDate').value = yesterday.toISOString().split('T')[0]; + document.getElementById('endDate').value = now.toISOString().split('T')[0]; + + // Standardwerte für Start- und Endzeit + document.getElementById('startTime').value = '00:00'; + document.getElementById('endTime').value = '23:59'; +} + +// Eventlistener: Initialer Abruf beim Seitenladen +document.addEventListener('DOMContentLoaded', () => { + setDefaultDateTime(); // Standardwerte setzen + fetchAndUpdateChart(); // Standard-Daten laden +}); + +// Eventlistener: Filteränderung +document.getElementById('timeFilter').addEventListener('change', (event) => { + const filter = event.target.value; + + // Anpassung der Datumswerte basierend auf dem Filter + const now = new Date(); + let startDate; + switch (filter) { + case '24h': + startDate = new Date(); + startDate.setDate(now.getDate() - 1); + break; + case '7d': + startDate = new Date(); + startDate.setDate(now.getDate() - 7); + break; + case '1m': + startDate = new Date(); + startDate.setMonth(now.getMonth() - 1); + break; + case '1y': + startDate = new Date(); + startDate.setFullYear(now.getFullYear() - 1); + break; + case 'all': + startDate = null; + break; + default: + startDate = null; + } + + if (startDate) { + document.getElementById('startDate').value = startDate.toISOString().split('T')[0]; + document.getElementById('endDate').value = now.toISOString().split('T')[0]; + } + + fetchAndUpdateChart(); +}); diff --git a/app/static/js/max_time_diff.js b/app/static/js/max_time_diff.js new file mode 100644 index 0000000..fe1d771 --- /dev/null +++ b/app/static/js/max_time_diff.js @@ -0,0 +1,43 @@ +document.getElementById('calculateButton').addEventListener('click', () => { + const startDate = document.getElementById('startDate').value; + const endDate = document.getElementById('endDate').value; + const startTime = document.getElementById('startTime').value || '00:00'; + const endTime = document.getElementById('endTime').value || '23:59'; + + if (!startDate || !endDate) { + alert('Bitte sowohl Start- als auch End-Datum auswählen!'); + return; + } + + fetch(`/max_time_diff?start_date=${startDate}&end_date=${endDate}&start_time=${startTime}&end_time=${endTime}`) + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + return response.json(); + }) + .then(data => { + console.log('Max-Diff-Daten:', data); + + const resultElement = document.getElementById('maxTimeDiff'); + if (data.error) { + resultElement.textContent = `Fehler: ${data.error}`; + } else if (data.max_time_diff_seconds !== undefined) { + const maxDiff = data.max_time_diff_seconds; + const hours = Math.floor(maxDiff / 3600); + const minutes = Math.floor((maxDiff % 3600) / 60); + const seconds = maxDiff % 60; + + const startTime = data.start_time; + const endTime = data.end_time; + + resultElement.textContent = `Maximale Zeitdifferenz: ${hours}h ${minutes}m ${seconds}s zwischen ${startTime} und ${endTime}`; + } else { + resultElement.textContent = 'Keine Daten verfügbar.'; + } + }) + .catch(err => { + console.error('Fehler bei der Max-Diff-Anfrage:', err); + document.getElementById('maxTimeDiff').textContent = 'Fehler beim Abrufen der Daten.'; + }); +}); diff --git a/app/static/js/tag_nacht.js b/app/static/js/tag_nacht.js new file mode 100644 index 0000000..0d457ef --- /dev/null +++ b/app/static/js/tag_nacht.js @@ -0,0 +1,19 @@ + +fetch('/tag_nacht') + .then(response => response.json()) + .then(data => { + const labels = data.map(item => item.time_period); + const values = data.map(item => item.transmission_count); + const ctx = document.getElementById('tagNachtChart').getContext('2d'); + new Chart(ctx, { + type: 'bar', + data: { + labels: labels, + datasets: [{ + label: 'Tag/Nacht Übertragungen', + data: values, + backgroundColor: ['rgba(75, 192, 192, 0.5)', 'rgba(192, 75, 75, 0.5)'] + }] + } + }); + }); diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..1d3525f --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,52 @@ + + + + + + + Webservice Monitoring + + + + + + +

Webservice Monitoring

+
+

Tag/Nacht-Aktivität

+ +
+
+

Maximale Zeitdifferenz

+ + + + + + + + + +

Lädt...

+
+
+

5-Minuten-Chart

+ + + + + + + + + + +
+ + diff --git a/app/utils.py b/app/utils.py new file mode 100644 index 0000000..002ba35 --- /dev/null +++ b/app/utils.py @@ -0,0 +1,10 @@ +import mysql.connector +from flask import current_app + +def get_db_connection(): + return mysql.connector.connect( + host=current_app.config['MYSQL_HOST'], + user=current_app.config['MYSQL_USER'], + password=current_app.config['MYSQL_PASSWORD'], + database=current_app.config['MYSQL_DB'] + ) diff --git a/run.py b/run.py new file mode 100644 index 0000000..ed85b0b --- /dev/null +++ b/run.py @@ -0,0 +1,7 @@ +from app import create_app + +app = create_app() + +if __name__ == "__main__": +# app.run(debug=True) + app.run(host='0.0.0.0', port=5000)