diff --git a/app/__init__.py b/app/__init__.py index 665b7fe5..311578b3 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -14,7 +14,9 @@ from flask import request from flask import Flask from flask import current_app from flask import g +from flask import has_request_context from flask import render_template +from flask.logging import default_handler from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from flask_login import LoginManager @@ -49,6 +51,25 @@ def handle_sco_value_error(exc): return render_template("sco_value_error.html", exc=exc), 404 +def internal_server_error(e): + # note that we set the 500 status explicitly + return render_template("error_500.html", SCOVERSION=sco_version.SCOVERSION), 500 + + +class RequestFormatter(logging.Formatter): + """Ajoute URL et remote_addr for logging""" + + def format(self, record): + if has_request_context(): + record.url = request.url + record.remote_addr = request.remote_addr + else: + record.url = None + record.remote_addr = None + + return super().format(record) + + def create_app(config_class=DevConfig): app = Flask(__name__, static_url_path="/ScoDoc/static", static_folder="static") app.logger.setLevel(logging.DEBUG) @@ -64,6 +85,7 @@ def create_app(config_class=DevConfig): sco_cache.CACHE = cache app.register_error_handler(ScoValueError, handle_sco_value_error) + app.register_error_handler(500, internal_server_error) from app.auth import bp as auth_bp @@ -87,44 +109,47 @@ def create_app(config_class=DevConfig): app.register_blueprint( absences_bp, url_prefix="/ScoDoc//Scolarite/Absences" ) - - # Config logs pour PRODUCTION - if not app.debug and not app.testing: - # On supprime le logguer par défaut qui va vers stderr et pollue le slogs systemes - # nb: pas trouvé plus élégant - app.logger.handlers.pop() - if app.config["MAIL_SERVER"]: - auth = None - if app.config["MAIL_USERNAME"] or app.config["MAIL_PASSWORD"]: - auth = (app.config["MAIL_USERNAME"], app.config["MAIL_PASSWORD"]) - secure = None - if app.config["MAIL_USE_TLS"]: - secure = () - host_name = socket.gethostname() - mail_handler = SMTPHandler( - mailhost=(app.config["MAIL_SERVER"], app.config["MAIL_PORT"]), - fromaddr="no-reply@" + app.config["MAIL_SERVER"], - toaddrs=["exception@scodoc.org"], - subject="ScoDoc Exception from " + host_name, - credentials=auth, - secure=secure, - ) - mail_handler.setLevel(logging.ERROR) - app.logger.addHandler(mail_handler) - - # Config logs pour DEV et PRODUCTION + scodoc_exc_formatter = RequestFormatter( + "[%(asctime)s] %(remote_addr)s requested %(url)s\n" + "%(levelname)s in %(module)s: %(message)s" + ) if not app.testing: + if not app.debug: + # --- Config logs pour PRODUCTION + # On supprime le logguer par défaut qui va vers stderr et pollue les logs systemes + app.logger.removeHandler(default_handler) + # --- Mail des messages ERROR et CRITICAL + if app.config["MAIL_SERVER"]: + auth = None + if app.config["MAIL_USERNAME"] or app.config["MAIL_PASSWORD"]: + auth = (app.config["MAIL_USERNAME"], app.config["MAIL_PASSWORD"]) + secure = None + if app.config["MAIL_USE_TLS"]: + secure = () + host_name = socket.gethostname() + mail_handler = SMTPHandler( + mailhost=(app.config["MAIL_SERVER"], app.config["MAIL_PORT"]), + fromaddr="no-reply@" + app.config["MAIL_SERVER"], + toaddrs=["exception@scodoc.org"], + subject="ScoDoc Exception from " + host_name, + credentials=auth, + secure=secure, + ) + mail_handler.setFormatter(scodoc_exc_formatter) + mail_handler.setLevel(logging.ERROR) + app.logger.addHandler(mail_handler) + else: + # Pour logs en DEV uniquement: + default_handler.setFormatter(scodoc_exc_formatter) + + # Config logs pour DEV et PRODUCTION # Configuration des logs (actifs aussi en mode development) # usually /opt/scodoc-data/log/scodoc.log: # rotated by logrotate file_handler = WatchedFileHandler( app.config["SCODOC_LOG_FILE"], encoding="utf-8" ) - file_handler.setFormatter( - logging.Formatter( - "%(asctime)s pid=%(process)d th=%(thread)s %(levelname)s: %(message)s " # "[in %(pathname)s:%(lineno)d]" - ) - ) + file_handler.setFormatter(scodoc_exc_formatter) file_handler.setLevel(logging.INFO) app.logger.addHandler(file_handler) diff --git a/app/templates/error_500.html b/app/templates/error_500.html new file mode 100644 index 00000000..ba960d7a --- /dev/null +++ b/app/templates/error_500.html @@ -0,0 +1,18 @@ +{% extends 'base.html' %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block title %}Une erreur est survenue !{% endblock %} +{% block body %} +

Une erreur est survenue !

+

Oops... ScoDoc version {{SCOVERSION}} a + un problème, désolé.

+ +

Si le problème persiste, contacter l'administrateur de votre site, + ou écrire la liste "notes" notes@listes.univ-paris13.fr en + indiquant la version du logiciel + (plus d'informations sur les listes de diffusion). +

+ +

retour à la page d'accueil

+ +{% endblock %} \ No newline at end of file diff --git a/app/views/scodoc.py b/app/views/scodoc.py index 5c12673c..47c51b6b 100644 --- a/app/views/scodoc.py +++ b/app/views/scodoc.py @@ -65,16 +65,17 @@ def table_etud_in_accessible_depts(): # essais -@bp.route("/testlog") -def testlog(): - import time - from flask import current_app - from app import log +# @bp.route("/testlog") +# def testlog(): +# import time +# from flask import current_app +# from app import log - log(f"testlog called: handlers={current_app.logger.handlers}") - current_app.logger.debug(f"testlog message DEBUG") - current_app.logger.info(f"testlog message INFO") - current_app.logger.warning(f"testlog message WARNING") - current_app.logger.error(f"testlog message ERROR") - current_app.logger.critical(f"testlog message CRITICAL") - return "testlog completed at " + str(time.time()) +# log(f"testlog called: handlers={current_app.logger.handlers}") +# current_app.logger.debug(f"testlog message DEBUG") +# current_app.logger.info(f"testlog message INFO") +# current_app.logger.warning(f"testlog message WARNING") +# current_app.logger.error(f"testlog message ERROR") +# current_app.logger.critical(f"testlog message CRITICAL") +# raise SyntaxError("une erreur de syntaxe") +# return "testlog completed at " + str(time.time())