fix: [dashboard] Filter out dashboard event-stream SSL.SSLEOFError from the log if a client disconnects

This commit is contained in:
terrtia 2024-07-04 15:52:20 +02:00
parent f37349a6cc
commit ced00d14cb
No known key found for this signature in database
GPG key ID: 1E1B1F50D84613D0
5 changed files with 65 additions and 41 deletions

View file

@ -27,7 +27,3 @@ def get_config(name=None):
config = json.load(f) config = json.load(f)
config['handlers']['file']['filename'] = os.path.join(os.environ['AIL_HOME'], 'logs', name) config['handlers']['file']['filename'] = os.path.join(os.environ['AIL_HOME'], 'logs', name)
return config return config
if __name__ == '__main__':
pass

View file

@ -81,13 +81,30 @@ log_dir = os.path.join(os.environ['AIL_HOME'], 'logs')
if not os.path.isdir(log_dir): if not os.path.isdir(log_dir):
os.makedirs(log_dir) os.makedirs(log_dir)
logging.config.dictConfig(ail_logger.get_config(name='flask')) # ========= LOGS =========#
class FilterLogErrors(logging.Filter):
def filter(self, record):
# print(dict(record.__dict__))
if record.levelname == 'ERROR':
if record.msg.startswith('Error on request:'):
if 'ssl.SSLEOFError: EOF occurred in violation of protocol' in record.msg:
return False
return True
logging.config.dictConfig(ail_logger.get_config(name='flask'))
flask_logger = logging.getLogger()
ignore_filter = FilterLogErrors()
for handler in flask_logger.handlers:
handler.addFilter(ignore_filter)
# ========= =========#
# ========= TLS =========# # ========= TLS =========#
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(certfile=os.path.join(Flask_dir, 'server.crt'), keyfile=os.path.join(Flask_dir, 'server.key')) ssl_context.load_cert_chain(certfile=os.path.join(Flask_dir, 'server.crt'), keyfile=os.path.join(Flask_dir, 'server.key'))
ssl_context.suppress_ragged_eofs = True
# print(ssl_context.get_ciphers()) # print(ssl_context.get_ciphers())
# ========= =========# # ========= =========#

View file

@ -11,7 +11,7 @@ import datetime
import time import time
import flask import flask
from flask import Flask, render_template, jsonify, request, Blueprint, url_for from flask import Flask, render_template, jsonify, request, Blueprint, url_for, stream_with_context
from Role_Manager import login_admin, login_analyst, login_read_only from Role_Manager import login_admin, login_analyst, login_read_only
from flask_login import login_required from flask_login import login_required
@ -38,33 +38,34 @@ max_dashboard_logs = Flask_config.max_dashboard_logs
dashboard = Blueprint('dashboard', __name__, template_folder='templates') dashboard = Blueprint('dashboard', __name__, template_folder='templates')
# ============ FUNCTIONS ============ # ============ FUNCTIONS ============
def event_stream(): def event_stream():
pubsub = r_serv_log.pubsub() pubsub = r_serv_log.pubsub()
pubsub.psubscribe("Script" + '.*') pubsub.psubscribe("Script" + '.*')
for msg in pubsub.listen(): try:
for msg in pubsub.listen():
mtype = msg['type']
pattern = msg['pattern']
channel = msg['channel']
data = msg['data']
# print(msg) msg = {'channel': channel, 'type': mtype, 'pattern': pattern, 'data': data}
type = msg['type']
pattern = msg['pattern']
channel = msg['channel']
data = msg['data']
msg = {'channel': channel, 'type': type, 'pattern': pattern, 'data': data} level = (msg['channel']).split('.')[1]
if msg['type'] == 'pmessage' and level != "DEBUG":
level = (msg['channel']).split('.')[1] yield 'data: %s\n\n' % json.dumps(msg)
if msg['type'] == 'pmessage' and level != "DEBUG": except GeneratorExit:
yield 'data: %s\n\n' % json.dumps(msg) print("Generator Exited")
pubsub.unsubscribe()
def event_stream_dashboard(): def event_stream_dashboard():
try: try:
while True: while True:
# jsonify(row1=get_queues())
data = {'queues': get_queues()} data = {'queues': get_queues()}
yield f'data: {json.dumps(data)}\n\n' yield f'data: {json.dumps(data)}\n\n'
time.sleep(1) time.sleep(1)
except GeneratorExit: except GeneratorExit:
print("Generator Exited") print("Generator dashboard Exited")
pass
def get_queues(): def get_queues():
# We may want to put the llen in a pipeline to do only one query. # We may want to put the llen in a pipeline to do only one query.
@ -117,7 +118,7 @@ def logs():
@login_required @login_required
@login_read_only @login_read_only
def _dashboard(): def _dashboard():
return flask.Response(event_stream_dashboard(), content_type="text/event-stream") return flask.Response(stream_with_context(event_stream_dashboard()), content_type="text/event-stream")
@dashboard.route("/_get_last_logs_json") @dashboard.route("/_get_last_logs_json")
@login_required @login_required

View file

@ -18,7 +18,7 @@
<script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script> <script src="{{ url_for('static', filename='js/bootstrap4.min.js')}}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/indexjavascript.js')}}" <script type="text/javascript" src="{{ url_for('static', filename='js/indexjavascript.js')}}"
data-urlstuff="{{ url_for('dashboard.stuff') }}" data-urllog="{{ url_for('dashboard.logs') }}"> data-urllog="{{ url_for('dashboard.logs') }}">
</script> </script>
<style> <style>
@ -38,15 +38,6 @@
<script> <script>
window.default_minute = {{ default_minute }}; window.default_minute = {{ default_minute }};
window.glob_tabvar = []; // Avoid undefined
window.threshold_stucked_module = {{ threshold_stucked_module }}
function update_values() {
$.getJSON("{{ url_for('dashboard.stuff') }}",
function(data) {
window.glob_tabvar = data;
});
};
update_values();
</script> </script>
</head> </head>
@ -162,7 +153,11 @@
</body> </body>
<script> var url_showSavedPath = "{{ url_for('investigations_b.get_object_gid') }}"; </script>
<script>
var url_showSavedPath = "{{ url_for('investigations_b.get_object_gid') }}";
</script>
<script> <script>
$("#page-Dashboard").addClass("active"); $("#page-Dashboard").addClass("active");
@ -317,21 +312,32 @@ function create_queue_table(data) {
Tablediv.appendChild(table); Tablediv.appendChild(table);
} }
//
//
document.addEventListener("DOMContentLoaded", function() {
let eventSource = new EventSource("{{ url_for('dashboard._dashboard') }}");
eventSource.onmessage = function(event) {
var event_queues
$(document).ready(function() {
// Hide Browser Error: connection interrupted while the page was loading
$(window).on("beforeunload", function() {
event_queues.close();
source.close();
});
event_queues = new EventSource("{{ url_for('dashboard._dashboard') }}");
event_queues.onmessage = function(event) {
let data = JSON.parse(event.data); let data = JSON.parse(event.data);
create_queue_table(data['queues']) create_queue_table(data['queues'])
}; };
event_queues.onerror = function(event) {
eventSource.onerror = function(event) {
console.error('EventSource failed:', event); console.error('EventSource failed:', event);
eventSource.close(); // Close the connection event_queues.close();
}; };
}); });
</script> </script>
</html> </html>

View file

@ -140,6 +140,10 @@ source.onmessage = function(event) {
var feed = JSON.parse( event.data ); var feed = JSON.parse( event.data );
create_log_table(feed); create_log_table(feed);
}; };
source.onerror = function(event) {
console.error('EventSource failed:', event);
source.close();
};
function pad_2(number) { function pad_2(number) {
return (number < 10 ? '0' : '') + number; return (number < 10 ? '0' : '') + number;