Browse Source

feat: 完善日志系统

SongZihuan 3 years ago
parent
commit
d59c0b744d
11 changed files with 200 additions and 24 deletions
  1. 24 1
      configure/__init__.py
  2. 2 9
      gunicorn.conf.py
  3. 4 3
      main.py
  4. 2 2
      view/about_me.py
  5. 10 1
      view/archive.py
  6. 38 1
      view/auth.py
  7. 74 2
      view/base.py
  8. 24 2
      view/docx.py
  9. 7 1
      view/index.py
  10. 9 1
      view/msg.py
  11. 6 1
      view/oss.py

+ 24 - 1
configure/__init__.py

@@ -1,6 +1,8 @@
 import json
+import logging
+import os
 
-
+logging.basicConfig(encoding='utf-8')
 conf = dict()
 
 
@@ -60,3 +62,24 @@ def configure(conf_file: str, encoding="utf-8"):
         conf["aliyun-secret"] = aliyun["Secret"]
         conf["aliyun-bucket-endpoint"] = aliyun["Bucket-Endpoint"]
         conf["aliyun-bucket-name"] = aliyun["Bucket-Name"]
+
+    log = _conf.get("log")
+    if log is None:
+        conf["log-home"] = None
+        conf["log-format"] = ("[%(levelname)s]:%(name)s:%(asctime)s "
+                              "(%(filename)s:%(lineno)d %(funcName)s) "
+                              "%(process)d %(thread)d "
+                              "%(message)s")
+        conf["log-level"] = logging.INFO
+    else:
+        conf["log-home"] = log.get("home")
+        if conf["log-home"]:
+            os.makedirs(conf["log-home"], exist_ok=True)
+        conf["log-level"] = {"debug": logging.DEBUG,
+                             "info": logging.INFO,
+                             "warning": logging.WARNING,
+                             "error": logging.ERROR}.get(log.get("level", "info"))
+        conf["log-format"] = log.get("format", ("[%(levelname)s]:%(name)s:%(asctime)s "
+                                                "(%(filename)s:%(lineno)d %(funcName)s) "
+                                                "%(process)d %(thread)d "
+                                                "%(message)s"))

+ 2 - 9
gunicorn.conf.py

@@ -16,21 +16,16 @@ hblog_path = os.path.join(os.environ['HOME'], "hblog")
 os.makedirs(hblog_path, exist_ok=True, mode=0o775)
 
 # 设置访问日志和错误信息日志路径
-log_format = ("[%(levelname)s] %(name)s %(asctime)s "
-              "(%(pathname)s:%(lineno)d %(funcName)s) "
+log_format = ("[%(levelname)s]:%(name)s:%(asctime)s "
+              "(%(filename)s:%(lineno)d %(funcName)s) "
               "%(process)d %(thread)d "
               "%(message)s")
 log_formatter = logging.Formatter(log_format)
 
-console_handle = logging.StreamHandler(sys.stdout)
-console_handle.setFormatter(log_formatter)
-
 # 错误日志
 gunicorn_error_logger = logging.getLogger("gunicorn.error")
 gunicorn_error_logger.setLevel(logging.WARNING)
 
-gunicorn_error_logger.addHandler(console_handle)
-
 errorlog = os.path.join(hblog_path, "gunicorn_error.log")
 time_handle = logging.handlers.TimedRotatingFileHandler(errorlog, when="d", backupCount=30, encoding='utf-8')
 gunicorn_error_logger.addHandler(time_handle)
@@ -40,8 +35,6 @@ time_handle.setFormatter(log_formatter)
 gunicorn_access_logger = logging.getLogger("gunicorn.access")
 gunicorn_access_logger.setLevel(logging.INFO)
 
-gunicorn_access_logger.addHandler(console_handle)
-
 accesslog = os.path.join(hblog_path, "/gunicorn_access.log")
 time_handle = logging.handlers.TimedRotatingFileHandler(accesslog, when="d", backupCount=10, encoding='utf-8')
 gunicorn_access_logger.addHandler(time_handle)

+ 4 - 3
main.py

@@ -1,13 +1,14 @@
 from configure import configure, conf
 import os
+import logging
 
 env_dict = os.environ
 hblog_conf = env_dict.get("hblog_conf")
 if hblog_conf is None:
-    print("执行配置文件: ./etc/conf.json")
+    logging.info("Configure file ./etc/conf.json")
     configure("./etc/conf.json")
 else:
-    print(f"执行配置文件: {hblog_conf}")
+    logging.info(f"Configure file {hblog_conf}")
     configure(hblog_conf)
 
 from view import WebApp
@@ -20,5 +21,5 @@ if conf["server-name"] is not None:
     app.config['SERVER_NAME'] = conf["server-name"]
 
 if __name__ == '__main__':
-    print("已启动服务: 127.0.0.1:8080")
+    logging.info("Server start on 127.0.0.1:8080")
     serve(app, host='0.0.0.0', port="8080")

+ 2 - 2
view/about_me.py

@@ -1,7 +1,6 @@
-from flask import Flask, Blueprint, render_template
+from flask import Flask, Blueprint, render_template, current_app, request
 from typing import Optional
 
-from configure import conf
 from view.base import App
 
 
@@ -11,6 +10,7 @@ app: Optional[Flask] = None
 
 @about_me.route('/')
 def about_me_page():
+    AboutMeApp.print_load_page_log("about me")
     return render_template("about_me/about_me.html")
 
 

+ 10 - 1
view/archive.py

@@ -1,4 +1,4 @@
-from flask import Flask, Blueprint, render_template, abort, redirect, url_for, flash
+from flask import Flask, Blueprint, render_template, abort, redirect, url_for, flash, current_app, request
 from typing import Optional
 from flask_login import login_required, current_user
 from flask_wtf import FlaskForm
@@ -21,6 +21,7 @@ class CreateArchiveForm(FlaskForm):
 @archive.route('/')
 def archive_page():
     archive_list = Archive.get_archive_list()
+    ArchiveApp.print_load_page_log("archive list")
     return render_template("archive/archive.html",
                            archive_list=archive_list,
                            form=CreateArchiveForm(),
@@ -33,14 +34,18 @@ def create_archive_page():
     form = CreateArchiveForm()
     if form.validate_on_submit():
         if not current_user.check_role("WriteBlog"):  # 检查相应的权限
+            ArchiveApp.print_user_not_allow_opt_log("Create archive")
             abort(403)
             return
 
         if Archive(form.name.data, form.describe.data, None).create():
+            ArchiveApp.print_sys_opt_success_log(f"Create archive {form.name.data}")
             flash(f"创建归档 {form.name.data} 成功")
         else:
+            ArchiveApp.print_sys_opt_fail_log(f"Create archive {form.name.data}")
             flash(f"创建归档 {form.name.data} 失败")
         return redirect(url_for("archive.archive_page"))
+    current_app.logger.warning("Create archive with error form.")
     abort(404)
 
 
@@ -48,11 +53,15 @@ def create_archive_page():
 @login_required
 def delete_archive_page(archive_id: int):
     if not current_user.check_role("DeleteBlog"):
+        ArchiveApp.print_user_not_allow_opt_log("Delete archive")
         abort(403)
         return
+
     if Archive(None, None, archive_id).delete():
+        ArchiveApp.print_sys_opt_success_log(f"Delete archive {archive_id}")
         flash("归档删除成功")
     else:
+        ArchiveApp.print_sys_opt_fail_log(f"Delete archive {archive_id}")
         flash("归档删除失败")
     return redirect(url_for("archive.archive_page"))
 

+ 38 - 1
view/auth.py

@@ -1,4 +1,4 @@
-from flask import Flask, Blueprint, render_template, redirect, flash, url_for, request, abort
+from flask import Flask, Blueprint, render_template, redirect, flash, url_for, request, abort, current_app
 from flask_login import login_required, login_user, current_user, logout_user
 from flask_mail import Mail
 from flask_wtf import FlaskForm
@@ -74,12 +74,14 @@ class SetRoleForm(FlaskForm):
 @login_required
 def yours_page():
     msg_count, comment_count, blog_count = current_user.count_info()
+    AuthApp.print_load_page_log("user info")
     return render_template("auth/yours.html", msg_count=msg_count, comment_count=comment_count, blog_count=blog_count)
 
 
 @auth.route('/login', methods=["GET", "POST"])
 def login_page():
     if current_user.is_authenticated:
+        AuthApp.print_user_not_allow_opt_log("login")
         return redirect(url_for("auth.yours_page"))
 
     form = LoginForm()
@@ -91,15 +93,19 @@ def login_page():
             if next_page is None or not next_page.startswith('/'):
                 next_page = url_for('base.index_page')
             flash("登陆成功")
+            AuthApp.print_user_opt_success_log(f"login {form.email.data}")
             return redirect(next_page)
         flash("账号或密码错误")
+        AuthApp.print_user_opt_fail_log(f"login {form.email.data}")
         return redirect(url_for("auth.login_page"))
+    AuthApp.print_load_page_log("user login")
     return render_template("auth/login.html", form=form)
 
 
 @auth.route('/register', methods=["GET", "POST"])
 def register_page():
     if current_user.is_authenticated:
+        AuthApp.print_user_not_allow_opt_log("register")
         return redirect(url_for("auth.yours_page"))
 
     form = RegisterForm()
@@ -108,7 +114,9 @@ def register_page():
         register_url = url_for("auth.confirm_page", token=token, _external=True)
         send_msg("注册确认", mail, form.email.data, "register", register_url=register_url)
         flash("注册提交成功, 请进入邮箱点击确认注册链接")
+        AuthApp.print_import_user_opt_success_log(f"register {form.email.data}")
         return redirect(url_for("base.index_page"))
+    AuthApp.print_load_page_log("user register")
     return render_template("auth/register.html", RegisterForm=form)
 
 
@@ -116,25 +124,32 @@ def register_page():
 def confirm_page():
     token = request.args.get("token", None)
     if token is None:
+        AuthApp.print_user_opt_fail_log(f"Confirm (bad token)")
         abort(404)
         return
 
     token = User.load_token(token)
     if token is None:
+        AuthApp.print_user_opt_fail_log(f"Confirm (bad token)")
         abort(404)
         return
 
     if load_user_by_email(token[0]) is not None:
+        AuthApp.print_user_opt_fail_log(f"Confirm (bad token)")
         abort(404)
         return
 
     User(token[0], token[1], None, None).create()
+    current_app.logger.info(f"{token[0]} confirm success")
+    AuthApp.print_import_user_opt_success_log(f"confirm {token[0]}")
     flash(f"用户{token[0]}认证完成")
     return redirect(url_for("base.index_page"))
 
 
 @auth.route('/logout')
+@login_required
 def logout_page():
+    AuthApp.print_import_user_opt_success_log(f"logout")
     logout_user()
     flash("退出登录成功")
     return redirect(url_for("base.index_page"))
@@ -146,13 +161,17 @@ def change_passwd_page():
     form = ChangePasswdForm()
     if form.validate_on_submit():
         if not current_user.check_passwd(form.old_passwd.data):
+            AuthApp.print_user_opt_fail_log("change passwd (old passwd error)")
             flash("旧密码错误")
             return redirect(url_for("auth.change_passwd_page"))
         if current_user.change_passwd(form.passwd.data):
+            AuthApp.print_user_opt_success_log(f"change passwd")
             flash("密码修改成功")
         else:
+            AuthApp.print_user_opt_error_log(f"change passwd")
             flash("密码修改失败")
         return redirect(url_for("auth.yours_page"))
+    AuthApp.print_load_page_log("user change passwd")
     return render_template("auth/passwd.html", ChangePasswdForm=form)
 
 
@@ -160,6 +179,7 @@ def change_passwd_page():
 @login_required
 def delete_user_page():
     if not current_user.check_role("DeleteUser"):
+        AuthApp.print_user_not_allow_opt_log("delete user")
         abort(403)
         return
 
@@ -167,14 +187,18 @@ def delete_user_page():
     if form.validate_on_submit():
         user = load_user_by_email(form.email.data)
         if user is None:
+            AuthApp.print_sys_opt_fail_log(f"delete user {form.email.data}")
             abort(404)
             return
 
         if user.delete():
+            AuthApp.print_sys_opt_success_log(f"{current_user.email} delete user {form.email.data} success")
             flash("用户删除成功")
         else:
+            AuthApp.print_sys_opt_fail_log(f"{current_user.email} delete user {form.email.data} fail")
             flash("用户删除失败")
         return redirect(url_for("auth.delete_user_page"))
+    AuthApp.print_load_page_log("delete user")
     return render_template("auth/delete.html", DeleteUserForm=form)
 
 
@@ -182,8 +206,11 @@ def delete_user_page():
 @login_required
 def role_page():
     if not current_user.check_role("ConfigureSystem"):
+        AuthApp.print_user_not_allow_opt_log("load role setting")
         abort(403)
         return
+
+    AuthApp.print_load_page_log("role setting")
     return render_template("auth/role.html",
                            CreateRoleForm=CreateRoleForm(),
                            DeleteRoleForm=DeleteRoleForm(),
@@ -196,12 +223,15 @@ def role_create_page():
     form = CreateRoleForm()
     if form.validate_on_submit():
         if not current_user.check_role("ConfigureSystem"):
+            AuthApp.print_user_not_allow_opt_log("create role")
             abort(403)
             return
 
         if User.create_role(form.name.data, form.authority.data.replace(" ", "").split(";")):
+            AuthApp.print_sys_opt_success_log(f"Create role success: {form.name.data}")
             flash("角色创建成功")
         else:
+            AuthApp.print_sys_opt_success_log(f"Create role fail: {form.name.data}")
             flash("角色创建失败")
         return redirect(url_for("auth.role_page"))
 
@@ -215,12 +245,15 @@ def role_delete_page():
     form = DeleteRoleForm()
     if form.validate_on_submit():
         if not current_user.check_role("ConfigureSystem"):
+            AuthApp.print_user_not_allow_opt_log("delete role")
             abort(403)
             return
 
         if User.delete_role(form.name.data):
+            AuthApp.print_sys_opt_success_log(f"Delete role success: {form.name.data}")
             flash("角色删除成功")
         else:
+            AuthApp.print_sys_opt_fail_log(f"Delete role fail: {form.name.data}")
             flash("角色删除失败")
         return redirect(url_for("auth.role_page"))
 
@@ -234,16 +267,20 @@ def role_set_page():
     form = SetRoleForm()
     if form.validate_on_submit():
         if not current_user.check_role("ConfigureSystem"):
+            AuthApp.print_user_not_allow_opt_log("assign user a role")
             abort(403)
             return
 
         user = load_user_by_email(form.email.data)
         if user is not None:
             if user.set_user_role(form.name.data):
+                AuthApp.print_sys_opt_success_log(f"Role assign {form.email.data} -> {form.name.data}")
                 flash("角色设置成功")
             else:
+                AuthApp.print_sys_opt_fail_log(f"Role assign {form.email.data} -> {form.name.data}")
                 flash("角色设置失败")
         else:
+            AuthApp.print_sys_opt_fail_log(f"Role assign (bad email) {form.email.data} -> {form.name.data}")
             flash("邮箱未注册")
         return redirect(url_for("auth.role_page"))
 

+ 74 - 2
view/base.py

@@ -1,8 +1,13 @@
-from flask import Flask, url_for
+import os.path
+
+from flask import Flask, url_for, request, current_app
 from flask_mail import Mail
-from flask_login import LoginManager
+from flask_login import LoginManager, current_user
 from typing import Optional
 
+import sys
+import logging.handlers
+import logging
 from configure import conf
 from core.user import AnonymousUser
 
@@ -25,6 +30,18 @@ class App:
 
         self.mail = Mail(self._app)
 
+        self._app.logger.setLevel(conf["log-level"])
+        if conf["log-home"] is None:
+            if conf["log-home"]:
+                handle = logging.handlers.TimedRotatingFileHandler(
+                    os.path.join(conf["log-home"], f"flask-{os.getpid()}.log"))
+                handle.setFormatter(logging.Formatter(conf["log-format"]))
+                self._app.logger.addHandler(handle)
+        else:
+            handle = logging.StreamHandler(sys.stderr)
+            handle.setFormatter(logging.Formatter(conf["log-format"]))
+            self._app.logger.addHandler(handle)
+
     def get_app(self) -> Flask:
         return self._app
 
@@ -68,3 +85,58 @@ class App:
                           [f"{count - 1}", url_for(url, page=count - 1)],
                           [f"{count}", url_for(url, page=count)]]
         return page_list
+
+    @staticmethod
+    def __get_log_request_info():
+        return (f"user: '{current_user.email}' "
+                f"url: '{request.url}' blueprint: '{request.blueprint}' "
+                f"args: {request.args} form: {request.form} "
+                f"accept_encodings: '{request.accept_encodings}' "
+                f"accept_charsets: '{request.accept_charsets}' "
+                f"accept_mimetypes: '{request.accept_mimetypes}' "
+                f"accept_languages: '{request.accept_languages}'")
+
+    @staticmethod
+    def print_load_page_log(page: str):
+        current_app.logger.debug(
+            f"[{request.method}] Load - '{page}' " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_form_error_log(opt: str):
+        current_app.logger.warning(
+            f"[{request.method}] '{opt}' - Bad form " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_sys_opt_fail_log(opt: str):
+        current_app.logger.error(
+            f"[{request.method}] System {opt} - fail " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_sys_opt_success_log(opt: str):
+        current_app.logger.warning(
+            f"[{request.method}] System {opt} - success " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_user_opt_fail_log(opt: str):
+        current_app.logger.debug(
+            f"[{request.method}] User {opt} - fail " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_user_opt_success_log(opt: str):
+        current_app.logger.debug(
+            f"[{request.method}] User {opt} - success " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_user_opt_error_log(opt: str):
+        current_app.logger.warning(
+            f"[{request.method}] User {opt} - system fail " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_import_user_opt_success_log(opt: str):
+        current_app.logger.info(
+            f"[{request.method}] User {opt} - success " + App.__get_log_request_info())
+
+    @staticmethod
+    def print_user_not_allow_opt_log(opt: str):
+        current_app.logger.info(
+            f"[{request.method}] User '{opt}' - reject " + App.__get_log_request_info())

+ 24 - 2
view/docx.py

@@ -38,12 +38,14 @@ class WriteCommentForm(FlaskForm):
 @docx.route('/<int:page>')
 def docx_page(page: int = 1):
     if page < 1:
+        DocxApp.print_user_opt_fail_log(f"Load docx list with error page({page})")
         abort(404)
         return
 
     blog_list = BlogArticle.get_blog_list(limit=20, offset=(page - 1) * 20)
     max_page = App.get_max_page(BlogArticle.get_blog_count(), 20)
     page_list = App.get_page("docx.docx_page", page, max_page)
+    DocxApp.print_load_page_log(f"docx list (page: {page})")
     return render_template("docx/docx.html",
                            blog_list=blog_list,
                            is_top=DBBit.BIT_1,
@@ -55,12 +57,14 @@ def docx_page(page: int = 1):
 @docx.route('/<int:archive>/<int:page>')
 def archive_page(archive: int, page: int = 1):
     if page < 1:
+        DocxApp.print_user_opt_fail_log(f"Load archive-docx list with error page({page}) archive: {archive}")
         abort(404)
         return
 
     blog_list = BlogArticle.get_blog_list(archive_id=archive, limit=20, offset=(page - 1) * 20)
     max_page = App.get_max_page(BlogArticle.get_blog_count(archive_id=archive), 20)
     page_list = App.get_page("docx.archive_page", page, max_page)
+    DocxApp.print_load_page_log(f"archive-docx list (archive-id: {archive} page: {page})")
     return render_template("docx/docx.html",
                            blog_list=blog_list,
                            is_top=DBBit.BIT_1,
@@ -72,8 +76,10 @@ def archive_page(archive: int, page: int = 1):
 def article_page(blog_id: int):
     article = load_blog_by_id(blog_id)
     if article is None:
+        DocxApp.print_user_opt_fail_log(f"Load article with error id({blog_id})")
         abort(404)
         return
+    DocxApp.print_load_page_log(f"article (id: {blog_id})")
     return render_template("docx/article.html",
                            article=article,
                            archive_list=article.archive,
@@ -86,11 +92,13 @@ def article_page(blog_id: int):
 def article_down_page(blog_id: int):
     article = load_blog_by_id(blog_id)
     if article is None:
+        DocxApp.print_user_opt_fail_log(f"Download article with error id({blog_id})")
         abort(404)
         return
 
     response = make_response(article.context)
     response.headers["Content-Disposition"] = f"attachment; filename={article.title}.html"
+    DocxApp.print_load_page_log(f"download article (id: {blog_id})")
     return response
 
 
@@ -101,16 +109,19 @@ def comment_page(blog: int):
     if form.validate_on_submit():
         auth: User = current_user
         if not auth.check_role("WriteComment"):  # 检查是否具有权限
+            DocxApp.print_user_not_allow_opt_log("comment")
             abort(403)
             return
 
         context = form.context.data
         if Comment(None, blog, auth, context).create():
+            DocxApp.print_user_opt_success_log("comment")
             flash("评论成功")
         else:
+            DocxApp.print_user_opt_error_log("comment")
             flash("评论失败")
-
         return redirect(url_for("docx.article_page", blog_id=blog))
+    DocxApp.print_form_error_log("comment")
     abort(404)
 
 
@@ -121,6 +132,7 @@ def create_docx_page():
     if form.validate_on_submit():
         auth: User = current_user
         if not auth.check_role("WriteBlog"):  # 检查是否具有写入权限
+            DocxApp.print_user_not_allow_opt_log("write blog")
             abort(403)
             return
 
@@ -139,11 +151,13 @@ def create_docx_page():
                 markdown(form.context.data, output_format='html'), tags=allow_tag, strip=True))
 
         if BlogArticle(None, current_user, title, subtitle, context, archive=archive_list).create():
+            DocxApp.print_user_opt_success_log("write blog")
             flash(f"博客 {title} 发表成功")
         else:
+            DocxApp.print_user_opt_fail_log("write blog")
             flash(f"博客 {title} 发表失败")
-
         return redirect(url_for("docx.docx_page", page=1))
+    DocxApp.print_form_error_log("write blog")
     abort(404)
 
 
@@ -151,11 +165,15 @@ def create_docx_page():
 @login_required
 def delete_blog_page(blog_id: int):
     if not current_user.check_role("DeleteBlog"):
+        DocxApp.print_user_not_allow_opt_log("delete blog")
         abort(403)
         return
+
     if BlogArticle(blog_id, None, None, None, None).delete():
+        DocxApp.print_user_opt_success_log("delete blog")
         flash("博文删除成功")
     else:
+        DocxApp.print_user_opt_fail_log("delete blog")
         flash("博文删除失败")
     return redirect(url_for("docx.docx_page", page=1))
 
@@ -164,11 +182,15 @@ def delete_blog_page(blog_id: int):
 @login_required
 def delete_comment_page(comment_id: int):
     if not current_user.check_role("DeleteComment"):
+        DocxApp.print_user_not_allow_opt_log("delete comment")
         abort(403)
         return
+
     if Comment(comment_id, None, None, None).delete():
+        DocxApp.print_user_opt_success_log("delete comment")
         flash("博文评论成功")
     else:
+        DocxApp.print_user_opt_fail_log("delete comment")
         flash("博文评论失败")
     return redirect(url_for("docx.docx_page", page=1))
 

+ 7 - 1
view/index.py

@@ -13,6 +13,7 @@ app: Optional[Flask] = None
 
 @index.route('/')
 def hello_page():
+    IndexApp.print_load_page_log(f"hello")
     return render_template("index/hello.html")
 
 
@@ -20,6 +21,7 @@ def hello_page():
 def index_page():
     blog_list = BlogArticle.get_blog_list(limit=5, offset=0, not_top=True)
     msg_list = load_message_list(limit=6, offset=0, show_secret=False)
+    IndexApp.print_load_page_log(f"index")
     return render_template("index/index.html",
                            blog_list=blog_list,
                            msg_list=msg_list,
@@ -28,21 +30,25 @@ def index_page():
 
 @index.app_errorhandler(404)
 def error_404(e):
+    IndexApp.print_load_page_log(f"404")
     return render_template("index/error.html", error_code="404", error_info=f"你似乎来到一片荒漠:{e}"), 404
 
 
 @index.app_errorhandler(405)
-def error_404(e):
+def error_405(e):
+    IndexApp.print_load_page_log(f"405")
     return render_template("index/error.html", error_code="404", error_info=f"请求错误:{e}"), 405
 
 
 @index.app_errorhandler(403)
 def error_403(e):
+    IndexApp.print_load_page_log(f"403")
     return render_template("index/error.html", error_code="404", error_info=f"权限不足:{e}"), 403
 
 
 @index.app_errorhandler(500)
 def error_500(e):
+    IndexApp.print_load_page_log(f"500")
     return render_template("index/error.html", error_code="404", error_info=f"服务器出问题啦:{e}"), 500
 
 

+ 9 - 1
view/msg.py

@@ -26,6 +26,7 @@ class WriteForm(FlaskForm):
 @msg.route('/<int:page>')
 def msg_page(page: int = 1):
     if page < 1:
+        MsgApp.print_user_opt_fail_log(f"Load msg list with error page({page})")
         abort(404)
         return
 
@@ -33,6 +34,7 @@ def msg_page(page: int = 1):
                                  show_secret=current_user.check_role("ReadSecretMsg"))  # 判断是否可读取私密内容
     max_page = App.get_max_page(Message.get_msg_count(), 20)
     page_list = App.get_page("docx.docx_page", page, max_page)
+    MsgApp.print_load_page_log(f"msg (page: {page})")
     return render_template("msg/msg.html",
                            msg_list=msg_list,
                            page_list=page_list,
@@ -49,16 +51,18 @@ def write_msg_page():
     if form.validate_on_submit():
         auth: User = current_user
         if not auth.check_role("WriteMsg"):  # 检查相应权限
+            MsgApp.print_user_not_allow_opt_log("write msg")
             abort(403)
             return
 
         context = form.context.data
         secret = form.secret.data
         if Message(None, auth, context, secret, None).create():
+            MsgApp.print_user_opt_success_log("write msg")
             flash("留言成功")
         else:
+            MsgApp.print_user_opt_fail_log("write msg")
             flash("留言失败")
-
         return redirect(url_for("msg.msg_page", page=1))
     abort(404)
 
@@ -67,11 +71,15 @@ def write_msg_page():
 @login_required
 def delete_msg_page(msg_id: int):
     if not current_user.check_role("DeleteMsg"):
+        MsgApp.print_user_not_allow_opt_log("delete msg")
         abort(403)
         return
+
     if Message(msg_id, None, None).delete():
+        MsgApp.print_user_opt_success_log("delete msg")
         flash("留言删除成功")
     else:
+        MsgApp.print_user_opt_fail_log("delete msg")
         flash("留言删除失败")
     return redirect(url_for("msg.msg_page", page=1))
 

+ 6 - 1
view/oss.py

@@ -1,4 +1,4 @@
-from flask import Flask, Blueprint, redirect, render_template, request, abort, flash, url_for
+from flask import Flask, Blueprint, redirect, render_template, abort, flash, url_for, request
 from flask_login import login_required, current_user
 from typing import Optional
 from flask_wtf import FlaskForm
@@ -20,12 +20,14 @@ class UploadForm(FlaskForm):
 @oss.before_request
 def check_aliyun():
     if aliyun is None:
+        OSSApp.print_user_opt_fail_log("aliyun not used")
         abort(404)
         return
 
 
 @oss.route('get/<string:name>')
 def get_page(name: str):
+    OSSApp.print_user_opt_success_log(f"get file {name}")
     return redirect(aliyun.shared_obj(name))
 
 
@@ -33,6 +35,7 @@ def get_page(name: str):
 @login_required
 def upload_page():
     if not current_user.check_role("ConfigureSystem"):
+        OSSApp.print_user_not_allow_opt_log("upload file")
         abort(403)
         return
 
@@ -40,8 +43,10 @@ def upload_page():
     if form.validate_on_submit():
         file = request.files["file"]
         aliyun.upload_file(file.filename, file)
+        OSSApp.print_sys_opt_success_log(f"Upload file {file.filename}")
         flash(f"文件 {file.filename} 已上传: {url_for('oss.get_page', name=file.filename, _external=True)}")
         return redirect(url_for("oss.upload_page"))
+    OSSApp.print_load_page_log(f"OSS upload")
     return render_template("oss/upload.html", UploadForm=form)