commit a6fe7bf1c7c7052b9f20e16b772ebe1e2929442c Author: no Date: Fri Nov 29 14:00:20 2024 +0100 first commit 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 0000000..d7eecc0 Binary files /dev/null and b/app/__pycache__/__init__.cpython-310.pyc differ diff --git a/app/__pycache__/utils.cpython-310.pyc b/app/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000..a93f23d Binary files /dev/null and b/app/__pycache__/utils.cpython-310.pyc differ diff --git a/app/api/__pycache__/fuenf_minuten.cpython-310.pyc b/app/api/__pycache__/fuenf_minuten.cpython-310.pyc new file mode 100644 index 0000000..1ee35ad Binary files /dev/null and b/app/api/__pycache__/fuenf_minuten.cpython-310.pyc differ 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 0000000..4c9891b Binary files /dev/null and b/app/api/__pycache__/max_time_diff.cpython-310.pyc differ 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 0000000..aa5bc6f Binary files /dev/null and b/app/api/__pycache__/tag_nacht.cpython-310.pyc differ 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)