Browse Source

Merge pull request #327 from justanr/Improve-Logging

Improve logging
Peter Justin 7 years ago
parent
commit
8d4ea6b2ea

+ 4 - 0
flaskbb/__init__.py

@@ -10,4 +10,8 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 __version__ = '1.0'  # noqa
 __version__ = '1.0'  # noqa
+import logging
+
+logger = logging.getLogger(__name__)
+
 from flaskbb.app import create_app  # noqa
 from flaskbb.app import create_app  # noqa

+ 55 - 34
flaskbb/app.py

@@ -10,6 +10,7 @@
 """
 """
 import os
 import os
 import logging
 import logging
+import logging.config
 import time
 import time
 from functools import partial
 from functools import partial
 
 
@@ -58,6 +59,9 @@ from flaskbb.plugins.utils import remove_zombie_plugins_from_db, template_hook
 from flaskbb.plugins import spec
 from flaskbb.plugins import spec
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 def create_app(config=None):
 def create_app(config=None):
     """Creates the app.
     """Creates the app.
 
 
@@ -69,6 +73,7 @@ def create_app(config=None):
     """
     """
     app = Flask("flaskbb")
     app = Flask("flaskbb")
     configure_app(app, config)
     configure_app(app, config)
+    configure_logging(app)
     configure_celery_app(app, celery)
     configure_celery_app(app, celery)
     configure_extensions(app)
     configure_extensions(app)
     load_plugins(app)
     load_plugins(app)
@@ -79,7 +84,6 @@ def create_app(config=None):
     configure_errorhandlers(app)
     configure_errorhandlers(app)
     configure_migrations(app)
     configure_migrations(app)
     configure_translations(app)
     configure_translations(app)
-    configure_logging(app)
 
 
     app.pluggy.hook.flaskbb_additional_setup(app=app, pluggy=app.pluggy)
     app.pluggy.hook.flaskbb_additional_setup(app=app, pluggy=app.pluggy)
 
 
@@ -324,31 +328,60 @@ def configure_translations(app):
 
 
 def configure_logging(app):
 def configure_logging(app):
     """Configures logging."""
     """Configures logging."""
+    if app.config.get('USE_DEFAULT_LOGGING'):
+        configure_default_logging(app)
+
+    if app.config.get('LOG_CONF_FILE'):
+        logging.config.fileConfig(
+            app.config['LOG_CONF_FILE'], disable_existing_loggers=False
+        )
+
+    if app.config["SQLALCHEMY_ECHO"]:
+        # Ref: http://stackoverflow.com/a/8428546
+        @event.listens_for(Engine, "before_cursor_execute")
+        def before_cursor_execute(
+                conn, cursor, statement, parameters, context, executemany
+        ):
+            conn.info.setdefault('query_start_time', []).append(time.time())
+
+        @event.listens_for(Engine, "after_cursor_execute")
+        def after_cursor_execute(
+                conn, cursor, statement, parameters, context, executemany
+        ):
+            total = time.time() - conn.info['query_start_time'].pop(-1)
+            app.logger.debug("Total Time: %f", total)
+
 
 
-    logs_folder = os.path.join(app.root_path, os.pardir, "logs")
+def configure_default_logging(app):
     from logging.handlers import SMTPHandler
     from logging.handlers import SMTPHandler
+
+    logs_folder = app.config.get('LOG_PATH')
+
+    if logs_folder is None:
+        logs_folder = os.path.join(app.root_path, os.pardir, "logs")
+
+    default_log_format = '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
+
     formatter = logging.Formatter(
     formatter = logging.Formatter(
-        '%(asctime)s %(levelname)s: %(message)s '
-        '[in %(pathname)s:%(lineno)d]')
+        app.config.get('LOG_FORMAT') or default_log_format
+    )
 
 
     info_log = os.path.join(logs_folder, app.config['INFO_LOG'])
     info_log = os.path.join(logs_folder, app.config['INFO_LOG'])
 
 
     info_file_handler = logging.handlers.RotatingFileHandler(
     info_file_handler = logging.handlers.RotatingFileHandler(
-        info_log,
-        maxBytes=100000,
-        backupCount=10
+        info_log, maxBytes=100000, backupCount=10
     )
     )
 
 
-    info_file_handler.setLevel(logging.INFO)
+    log_level = app.config.get('LOG_LEVEL') or logging.INFO
+
+    info_file_handler.setLevel(log_level)
     info_file_handler.setFormatter(formatter)
     info_file_handler.setFormatter(formatter)
     app.logger.addHandler(info_file_handler)
     app.logger.addHandler(info_file_handler)
 
 
     error_log = os.path.join(logs_folder, app.config['ERROR_LOG'])
     error_log = os.path.join(logs_folder, app.config['ERROR_LOG'])
 
 
     error_file_handler = logging.handlers.RotatingFileHandler(
     error_file_handler = logging.handlers.RotatingFileHandler(
-        error_log,
-        maxBytes=100000,
-        backupCount=10
+        error_log, maxBytes=100000, backupCount=10
     )
     )
 
 
     error_file_handler.setLevel(logging.ERROR)
     error_file_handler.setLevel(logging.ERROR)
@@ -356,31 +389,19 @@ def configure_logging(app):
     app.logger.addHandler(error_file_handler)
     app.logger.addHandler(error_file_handler)
 
 
     if app.config["SEND_LOGS"]:
     if app.config["SEND_LOGS"]:
-        mail_handler = \
-            SMTPHandler(
-                app.config['MAIL_SERVER'],
-                app.config['MAIL_DEFAULT_SENDER'],
-                app.config['ADMINS'],
-                'application error, no admins specified',
-                (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
-            )
-
-        mail_handler.setLevel(logging.ERROR)
-        mail_handler.setFormatter(formatter)
-        app.logger.addHandler(mail_handler)
+        configure_mail_logs(app)
 
 
-    if app.config["SQLALCHEMY_ECHO"]:
-        # Ref: http://stackoverflow.com/a/8428546
-        @event.listens_for(Engine, "before_cursor_execute")
-        def before_cursor_execute(conn, cursor, statement,
-                                  parameters, context, executemany):
-            conn.info.setdefault('query_start_time', []).append(time.time())
 
 
-        @event.listens_for(Engine, "after_cursor_execute")
-        def after_cursor_execute(conn, cursor, statement,
-                                 parameters, context, executemany):
-            total = time.time() - conn.info['query_start_time'].pop(-1)
-            app.logger.debug("Total Time: %f", total)
+def configure_mail_logs(app):
+    mail_handler = SMTPHandler(
+        app.config['MAIL_SERVER'], app.config['MAIL_DEFAULT_SENDER'],
+        app.config['ADMINS'], 'application error, no admins specified',
+        (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
+    )
+
+    mail_handler.setLevel(logging.ERROR)
+    mail_handler.setFormatter(formatter)
+    app.logger.addHandler(mail_handler)
 
 
 
 
 def load_plugins(app):
 def load_plugins(app):

+ 3 - 0
flaskbb/auth/__init__.py

@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)

+ 5 - 0
flaskbb/auth/forms.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask_wtf import FlaskForm
 from flask_wtf import FlaskForm
 from wtforms import (StringField, PasswordField, BooleanField, HiddenField,
 from wtforms import (StringField, PasswordField, BooleanField, HiddenField,
                      SubmitField, SelectField)
                      SubmitField, SelectField)
@@ -20,6 +21,10 @@ from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.helpers import time_utcnow
 from flaskbb.utils.helpers import time_utcnow
 from flaskbb.utils.fields import RecaptchaField
 from flaskbb.utils.fields import RecaptchaField
 
 
+
+logger = logging.getLogger(__name__)
+
+
 USERNAME_RE = r'^[\w.+-]+$'
 USERNAME_RE = r'^[\w.+-]+$'
 is_valid_username = regexp(
 is_valid_username = regexp(
     USERNAME_RE, message=_("You can only use letters, numbers or dashes.")
     USERNAME_RE, message=_("You can only use letters, numbers or dashes.")

+ 5 - 0
flaskbb/auth/views.py

@@ -10,6 +10,7 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 from datetime import datetime
 from datetime import datetime
+import logging
 
 
 from flask import Blueprint, flash, g, redirect, request, url_for
 from flask import Blueprint, flash, g, redirect, request, url_for
 from flask.views import MethodView
 from flask.views import MethodView
@@ -33,6 +34,10 @@ from flaskbb.utils.helpers import (anonymous_required, enforce_recaptcha,
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.tokens import get_token_status
 from flaskbb.utils.tokens import get_token_status
 
 
+
+logger = logging.getLogger(__name__)
+
+
 auth = Blueprint("auth", __name__)
 auth = Blueprint("auth", __name__)
 
 
 
 

+ 10 - 1
flaskbb/cli/main.py

@@ -504,7 +504,8 @@ def generate_config(development, output, force):
         "mail_admin_address": "admin@yourdomain",
         "mail_admin_address": "admin@yourdomain",
         "secret_key": binascii.hexlify(os.urandom(24)).decode(),
         "secret_key": binascii.hexlify(os.urandom(24)).decode(),
         "csrf_secret_key": binascii.hexlify(os.urandom(24)).decode(),
         "csrf_secret_key": binascii.hexlify(os.urandom(24)).decode(),
-        "timestamp": datetime.utcnow().strftime("%A, %d. %B %Y at %H:%M")
+        "timestamp": datetime.utcnow().strftime("%A, %d. %B %Y at %H:%M"),
+        "log_config_path": "",
     }
     }
 
 
     if not force:
     if not force:
@@ -615,6 +616,14 @@ def generate_config(development, output, force):
         click.style("Mail Admin Email", fg="magenta"),
         click.style("Mail Admin Email", fg="magenta"),
         default=default_conf.get("mail_admin_address"))
         default=default_conf.get("mail_admin_address"))
 
 
+    click.secho("Optional filepath to load a logging configuration file from. "
+                "See the Python logging documentation for more detail.\n"
+                "\thttps://docs.python.org/library/logging.config.html#logging-config-fileformat",
+                fg="cyan")
+    default_conf["log_config_path"] =click.prompt(
+        click.style("Logging Config Path", fg="magenta"),
+        default=default_conf.get("log_config_path"))
+
     write_config(default_conf, config_template, config_path)
     write_config(default_conf, config_template, config_path)
 
 
     # Finished
     # Finished

+ 1 - 0
flaskbb/configs/config.cfg.template

@@ -154,6 +154,7 @@ ADMINS = ["{{ mail_admin_address }}"]
 # If SEND_LOGS is set to True, the admins (see the mail configuration) will
 # If SEND_LOGS is set to True, the admins (see the mail configuration) will
 # recieve the error logs per email.
 # recieve the error logs per email.
 SEND_LOGS = False
 SEND_LOGS = False
+LOG_CONF_FILE = {{ log_config_path }}
 
 
 
 
 # FlaskBB Settings
 # FlaskBB Settings

+ 37 - 2
flaskbb/configs/default.py

@@ -47,15 +47,48 @@ class DefaultConfig(object):
     # This only affects the url generation with 'url_for'.
     # This only affects the url generation with 'url_for'.
     PREFERRED_URL_SCHEME = "http"
     PREFERRED_URL_SCHEME = "http"
 
 
+    # Logging Settings
+    # ------------------------------
+    # This config section will deal with the logging settings
+    # for FlaskBB, adjust as needed.
+
+    # Logging Config Path
+    # see https://docs.python.org/library/logging.config.html#logging.config.fileConfig
+    # for more details. Should either be None or a path to a file
+    # If this is set to a path, consider setting USE_DEFAULT_LOGGING to False
+    # otherwise there may be interactions between the log configuration file
+    # and the default logging setting.
+    #
+    # If set to a file path, this should be an absolute file path
+    LOG_CONF_FILE = None
+
+    # When set to True this will enable the default
+    # FlaskBB logging configuration which uses the settings
+    # below to determine logging
+    USE_DEFAULT_LOGGING = True
+
+    # Log format FlaskBB will use
+    LOG_FORMAT = '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
+
+    # Log level FlaskBB will use
+    LOG_LEVEL = "INFO"
+
     # If SEND_LOGS is set to True, the admins (see the mail configuration) will
     # If SEND_LOGS is set to True, the admins (see the mail configuration) will
     # recieve the error logs per email.
     # recieve the error logs per email.
     SEND_LOGS = False
     SEND_LOGS = False
 
 
-    # The filename for the info and error logs. The logfiles are stored at
-    # flaskbb/logs
+    # Path to store the INFO and ERROR logs
+    # If None this defaults to flaskbb/logs
+    #
+    # If set to a file path, this should be an absolute path
+    LOG_PATH = None
+
+    # The filename for the info and error logs. The logfiles are stored
+    # at the path specified in LOG_PATH
     INFO_LOG = "info.log"
     INFO_LOG = "info.log"
     ERROR_LOG = "error.log"
     ERROR_LOG = "error.log"
 
 
+
     # Database
     # Database
     # ------------------------------
     # ------------------------------
     # For PostgresSQL:
     # For PostgresSQL:
@@ -191,6 +224,8 @@ class DefaultConfig(object):
     MESSAGE_URL_PREFIX = "/message"
     MESSAGE_URL_PREFIX = "/message"
     AUTH_URL_PREFIX = "/auth"
     AUTH_URL_PREFIX = "/auth"
     ADMIN_URL_PREFIX = "/admin"
     ADMIN_URL_PREFIX = "/admin"
+
+
     # Remove dead plugins - useful if you want to migrate your instance
     # Remove dead plugins - useful if you want to migrate your instance
     # somewhere else and forgot to reinstall the plugins.
     # somewhere else and forgot to reinstall the plugins.
     # If set to `False` it will NOT remove plugins that are NOT installed on
     # If set to `False` it will NOT remove plugins that are NOT installed on

+ 4 - 0
flaskbb/email.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask import render_template
 from flask import render_template
 from flask_mail import Message
 from flask_mail import Message
 from flask_babelplus import lazy_gettext as _
 from flask_babelplus import lazy_gettext as _
@@ -16,6 +17,9 @@ from flaskbb.extensions import mail, celery
 from flaskbb.utils.tokens import make_token
 from flaskbb.utils.tokens import make_token
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 @celery.task
 @celery.task
 def send_reset_token(user):
 def send_reset_token(user):
     """Sends the reset token to the user's email address.
     """Sends the reset token to the user's email address.

+ 3 - 0
flaskbb/forum/__init__.py

@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)

+ 4 - 0
flaskbb/forum/forms.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask_wtf import FlaskForm
 from flask_wtf import FlaskForm
 from wtforms import (TextAreaField, StringField, SelectMultipleField,
 from wtforms import (TextAreaField, StringField, SelectMultipleField,
                      BooleanField, SubmitField)
                      BooleanField, SubmitField)
@@ -18,6 +19,9 @@ from flaskbb.forum.models import Topic, Post, Report, Forum
 from flaskbb.user.models import User
 from flaskbb.user.models import User
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 class QuickreplyForm(FlaskForm):
 class QuickreplyForm(FlaskForm):
     content = TextAreaField(_("Quick reply"), validators=[
     content = TextAreaField(_("Quick reply"), validators=[
         DataRequired(message=_("You cannot post a reply without content."))])
         DataRequired(message=_("You cannot post a reply without content."))])

+ 4 - 0
flaskbb/forum/models.py

@@ -9,6 +9,7 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 from datetime import timedelta
 from datetime import timedelta
+import logging
 
 
 from flask import abort, url_for
 from flask import abort, url_for
 from sqlalchemy.orm import aliased
 from sqlalchemy.orm import aliased
@@ -21,6 +22,9 @@ from flaskbb.utils.helpers import (get_categories_and_forums, get_forums,
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 moderators = db.Table(
 moderators = db.Table(
     'moderators',
     'moderators',
     db.Column('user_id', db.Integer(), db.ForeignKey('users.id'),
     db.Column('user_id', db.Integer(), db.ForeignKey('users.id'),

+ 5 - 1
flaskbb/forum/views.py

@@ -9,6 +9,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 '''
 '''
+import logging
 import math
 import math
 
 
 from flask import (Blueprint, abort, current_app, flash, redirect, request,
 from flask import (Blueprint, abort, current_app, flash, redirect, request,
@@ -35,7 +36,10 @@ from flaskbb.utils.requirements import (CanAccessForum, CanAccessTopic,
                                         IsAtleastModeratorInForum)
                                         IsAtleastModeratorInForum)
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 
 
-forum = Blueprint('forum', __name__)
+logger = logging.getLogger(__name__)
+
+
+forum = Blueprint("forum", __name__)
 
 
 
 
 class ForumIndex(MethodView):
 class ForumIndex(MethodView):

+ 3 - 0
flaskbb/management/__init__.py

@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)

+ 4 - 0
flaskbb/management/forms.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask_wtf import FlaskForm
 from flask_wtf import FlaskForm
 from wtforms import (BooleanField, HiddenField, IntegerField, PasswordField,
 from wtforms import (BooleanField, HiddenField, IntegerField, PasswordField,
                      SelectField, StringField, SubmitField, TextAreaField)
                      SelectField, StringField, SubmitField, TextAreaField)
@@ -26,6 +27,9 @@ from flaskbb.utils.requirements import IsAtleastModerator
 from flask_allows import Permission
 from flask_allows import Permission
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 USERNAME_RE = r'^[\w.+-]+$'
 USERNAME_RE = r'^[\w.+-]+$'
 is_username = regexp(USERNAME_RE,
 is_username = regexp(USERNAME_RE,
                      message=_("You can only use letters, numbers or dashes."))
                      message=_("You can only use letters, numbers or dashes."))

+ 10 - 3
flaskbb/management/models.py

@@ -8,10 +8,17 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
-from flaskbb._compat import iteritems
-from flaskbb.extensions import db, cache
+import logging
+
+from flask_wtf import FlaskForm
+from flaskbb._compat import iteritems, text_type
+from flaskbb.extensions import cache, db
 from flaskbb.utils.database import CRUDMixin
 from flaskbb.utils.database import CRUDMixin
-from flaskbb.utils.forms import generate_settings_form, SettingValueType
+from flaskbb.utils.forms import SettingValueType, generate_settings_form
+from wtforms import (BooleanField, FloatField, IntegerField, SelectField,
+                     SelectMultipleField, TextField, validators)
+
+logger = logging.getLogger(__name__)
 
 
 
 
 class SettingsGroup(db.Model, CRUDMixin):
 class SettingsGroup(db.Model, CRUDMixin):

+ 4 - 0
flaskbb/management/views.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 import sys
 import sys
 
 
 from celery import __version__ as celery_version
 from celery import __version__ as celery_version
@@ -37,6 +38,9 @@ from flaskbb.utils.requirements import (CanBanUser, CanEditUser, IsAdmin,
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.forms import populate_settings_dict, populate_settings_form
 from flaskbb.utils.forms import populate_settings_dict, populate_settings_form
 
 
+logger = logging.getLogger(__name__)
+
+
 management = Blueprint("management", __name__)
 management = Blueprint("management", __name__)
 
 
 
 

+ 3 - 0
flaskbb/message/__init__.py

@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)

+ 4 - 0
flaskbb/message/forms.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask_login import current_user
 from flask_login import current_user
 from flask_wtf import FlaskForm
 from flask_wtf import FlaskForm
 from wtforms import StringField, TextAreaField, ValidationError, SubmitField
 from wtforms import StringField, TextAreaField, ValidationError, SubmitField
@@ -18,6 +19,9 @@ from flaskbb.user.models import User
 from flaskbb.message.models import Conversation, Message
 from flaskbb.message.models import Conversation, Message
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 class ConversationForm(FlaskForm):
 class ConversationForm(FlaskForm):
     to_user = StringField(_("Recipient"), validators=[
     to_user = StringField(_("Recipient"), validators=[
         DataRequired(message=_("A valid username is required."))])
         DataRequired(message=_("A valid username is required."))])

+ 4 - 0
flaskbb/message/models.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from sqlalchemy_utils import UUIDType
 from sqlalchemy_utils import UUIDType
 
 
 from flaskbb.extensions import db
 from flaskbb.extensions import db
@@ -15,6 +16,9 @@ from flaskbb.utils.helpers import time_utcnow
 from flaskbb.utils.database import CRUDMixin, UTCDateTime
 from flaskbb.utils.database import CRUDMixin, UTCDateTime
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 class Conversation(db.Model, CRUDMixin):
 class Conversation(db.Model, CRUDMixin):
     __tablename__ = "conversations"
     __tablename__ = "conversations"
 
 

+ 4 - 0
flaskbb/message/views.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 import uuid
 import uuid
 from functools import wraps
 from functools import wraps
 
 
@@ -24,6 +25,9 @@ from flaskbb.utils.helpers import (format_quote, register_view,
                                    render_template, time_utcnow)
                                    render_template, time_utcnow)
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 
 
+
+logger = logging.getLogger(__name__)
+
 message = Blueprint("message", __name__)
 message = Blueprint("message", __name__)
 
 
 
 

+ 11 - 0
flaskbb/plugins/manager.py

@@ -8,12 +8,16 @@
     :copyright: 2017, the FlaskBB Team
     :copyright: 2017, the FlaskBB Team
     :license: BSD, see LICENSE for more details
     :license: BSD, see LICENSE for more details
 """
 """
+import logging
+
 from pkg_resources import (DistributionNotFound, VersionConflict,
 from pkg_resources import (DistributionNotFound, VersionConflict,
                            iter_entry_points)
                            iter_entry_points)
 
 
 import pluggy
 import pluggy
 from flaskbb.utils.helpers import parse_pkg_metadata
 from flaskbb.utils.helpers import parse_pkg_metadata
 
 
+logger = logging.getLogger(__name__)
+
 
 
 class FlaskBBPluginManager(pluggy.PluginManager):
 class FlaskBBPluginManager(pluggy.PluginManager):
     """Overwrites :class:`pluggy.PluginManager` to add FlaskBB
     """Overwrites :class:`pluggy.PluginManager` to add FlaskBB
@@ -30,6 +34,7 @@ class FlaskBBPluginManager(pluggy.PluginManager):
     def load_setuptools_entrypoints(self, entrypoint_name):
     def load_setuptools_entrypoints(self, entrypoint_name):
         """Load modules from querying the specified setuptools entrypoint name.
         """Load modules from querying the specified setuptools entrypoint name.
         Return the number of loaded plugins. """
         Return the number of loaded plugins. """
+        logger.info("Loading plugins under entrypoint {}".format(entrypoint_name))
         for ep in iter_entry_points(entrypoint_name):
         for ep in iter_entry_points(entrypoint_name):
             if self.get_plugin(ep.name):
             if self.get_plugin(ep.name):
                 continue
                 continue
@@ -43,6 +48,7 @@ class FlaskBBPluginManager(pluggy.PluginManager):
             try:
             try:
                 plugin = ep.load()
                 plugin = ep.load()
             except DistributionNotFound:
             except DistributionNotFound:
+                logger.warn("Could not load plugin {}. Passing.".format(ep.name))
                 continue
                 continue
             except VersionConflict as e:
             except VersionConflict as e:
                 raise pluggy.PluginValidationError(
                 raise pluggy.PluginValidationError(
@@ -51,6 +57,11 @@ class FlaskBBPluginManager(pluggy.PluginManager):
             self.register(plugin, name=ep.name)
             self.register(plugin, name=ep.name)
             self._plugin_distinfo.append((plugin, ep.dist))
             self._plugin_distinfo.append((plugin, ep.dist))
             self._plugin_metadata[ep.name] = parse_pkg_metadata(ep.dist.key)
             self._plugin_metadata[ep.name] = parse_pkg_metadata(ep.dist.key)
+            logger.info("Loaded plugin: {}".format(ep.name))
+        logger.info("Loaded {} plugins for entrypoint {}".format(
+            len(self._plugin_distinfo),
+            entrypoint_name
+        ))
         return len(self._plugin_distinfo)
         return len(self._plugin_distinfo)
 
 
     def get_metadata(self, name):
     def get_metadata(self, name):

+ 3 - 0
flaskbb/user/__init__.py

@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)

+ 4 - 0
flaskbb/user/forms.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask_login import current_user
 from flask_login import current_user
 from flask_wtf import FlaskForm
 from flask_wtf import FlaskForm
 from wtforms import (StringField, PasswordField, TextAreaField, SelectField,
 from wtforms import (StringField, PasswordField, TextAreaField, SelectField,
@@ -22,6 +23,9 @@ from flaskbb.utils.fields import BirthdayField
 from flaskbb.utils.helpers import check_image
 from flaskbb.utils.helpers import check_image
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 class GeneralSettingsForm(FlaskForm):
 class GeneralSettingsForm(FlaskForm):
     # The choices for those fields will be generated in the user view
     # The choices for those fields will be generated in the user view
     # because we cannot access the current_app outside of the context
     # because we cannot access the current_app outside of the context

+ 4 - 0
flaskbb/user/models.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from werkzeug.security import generate_password_hash, check_password_hash
 from werkzeug.security import generate_password_hash, check_password_hash
 from flask import url_for
 from flask import url_for
 from flask_login import UserMixin, AnonymousUserMixin
 from flask_login import UserMixin, AnonymousUserMixin
@@ -22,6 +23,9 @@ from flaskbb.forum.models import (Post, Topic, Forum, topictracker, TopicsRead,
 from flaskbb.message.models import Conversation
 from flaskbb.message.models import Conversation
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 groups_users = db.Table(
 groups_users = db.Table(
     'groups_users',
     'groups_users',
     db.Column('user_id', db.Integer, db.ForeignKey('users.id'),
     db.Column('user_id', db.Integer, db.ForeignKey('users.id'),

+ 4 - 0
flaskbb/user/views.py

@@ -9,6 +9,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask import Blueprint, flash, request
 from flask import Blueprint, flash, request
 from flask.views import MethodView
 from flask.views import MethodView
 from flask_babelplus import gettext as _
 from flask_babelplus import gettext as _
@@ -21,6 +22,9 @@ from flaskbb.utils.helpers import (get_available_languages,
                                    get_available_themes, register_view,
                                    get_available_themes, register_view,
                                    render_template)
                                    render_template)
 
 
+logger = logging.getLogger(__name__)
+
+
 user = Blueprint("user", __name__)
 user = Blueprint("user", __name__)
 
 
 
 

+ 3 - 0
flaskbb/utils/__init__.py

@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger(__name__)

+ 4 - 0
flaskbb/utils/database.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2015 by the FlaskBB Team.
     :copyright: (c) 2015 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 import pytz
 import pytz
 from flask_login import current_user
 from flask_login import current_user
 from flask_sqlalchemy import BaseQuery
 from flask_sqlalchemy import BaseQuery
@@ -15,6 +16,9 @@ from sqlalchemy.ext.declarative import declared_attr
 from flaskbb.extensions import db
 from flaskbb.extensions import db
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 def make_comparable(cls):
 def make_comparable(cls):
 
 
     def __eq__(self, other):
     def __eq__(self, other):

+ 5 - 0
flaskbb/utils/fields.py

@@ -11,6 +11,7 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 from datetime import datetime
 from datetime import datetime
+import logging
 try:
 try:
     import urllib2 as http
     import urllib2 as http
 except ImportError:
 except ImportError:
@@ -26,6 +27,10 @@ from wtforms.widgets.core import Select, HTMLString, html_params
 from flaskbb._compat import to_bytes, to_unicode
 from flaskbb._compat import to_bytes, to_unicode
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 
 
+
+logger = logging.getLogger(__name__)
+
+
 JSONEncoder = json.JSONEncoder
 JSONEncoder = json.JSONEncoder
 
 
 RECAPTCHA_SCRIPT = u'https://www.google.com/recaptcha/api.js'
 RECAPTCHA_SCRIPT = u'https://www.google.com/recaptcha/api.js'

+ 4 - 0
flaskbb/utils/helpers.py

@@ -9,7 +9,9 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 import ast
 import ast
+import glob
 import itertools
 import itertools
+import logging
 import operator
 import operator
 import os
 import os
 import re
 import re
@@ -39,6 +41,8 @@ from PIL import ImageFile
 from pytz import UTC
 from pytz import UTC
 from werkzeug.local import LocalProxy
 from werkzeug.local import LocalProxy
 
 
+logger = logging.getLogger(__name__)
+
 _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
 _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
 
 
 
 

+ 4 - 0
flaskbb/utils/markup.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2016 by the FlaskBB Team.
     :copyright: (c) 2016 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 import os
 import os
 import re
 import re
 
 
@@ -20,6 +21,9 @@ from pygments.formatters import HtmlFormatter
 from pygments.util import ClassNotFound
 from pygments.util import ClassNotFound
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 _re_emoji = re.compile(r':([a-z0-9\+\-_]+):', re.I)
 _re_emoji = re.compile(r':([a-z0-9\+\-_]+):', re.I)
 _re_user = re.compile(r'@(\w+)', re.I)
 _re_user = re.compile(r'@(\w+)', re.I)
 
 

+ 7 - 4
flaskbb/utils/populate.py

@@ -9,14 +9,17 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 from __future__ import unicode_literals
 from __future__ import unicode_literals
+
 import collections
 import collections
+import logging
 
 
+from flaskbb.extensions import alembic, db
+from flaskbb.forum.models import Category, Forum, Post, Topic
+from flaskbb.management.models import Setting, SettingsGroup
+from flaskbb.user.models import Group, User
 from sqlalchemy_utils.functions import create_database, database_exists
 from sqlalchemy_utils.functions import create_database, database_exists
 
 
-from flaskbb.management.models import Setting, SettingsGroup
-from flaskbb.user.models import User, Group
-from flaskbb.forum.models import Post, Topic, Forum, Category
-from flaskbb.extensions import alembic, db
+logger = logging.getLogger(__name__)
 
 
 
 
 def delete_settings_from_fixture(fixture):
 def delete_settings_from_fixture(fixture):

+ 4 - 0
flaskbb/utils/requirements.py

@@ -7,12 +7,16 @@
     :copyright: (c) 2015 by the FlaskBB Team.
     :copyright: (c) 2015 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details
     :license: BSD, see LICENSE for more details
 """
 """
+import logging
+
 from flask_allows import And, Or, Requirement
 from flask_allows import And, Or, Requirement
 
 
 from flaskbb.exceptions import FlaskBBError
 from flaskbb.exceptions import FlaskBBError
 from flaskbb.forum.locals import current_forum, current_post, current_topic
 from flaskbb.forum.locals import current_forum, current_post, current_topic
 from flaskbb.forum.models import Forum, Post, Topic
 from flaskbb.forum.models import Forum, Post, Topic
 
 
+logger = logging.getLogger(__name__)
+
 
 
 class Has(Requirement):
 class Has(Requirement):
     def __init__(self, permission):
     def __init__(self, permission):

+ 4 - 0
flaskbb/utils/search.py

@@ -9,6 +9,7 @@
     :copyright: (c) 2016 by the FlaskBB Team.
     :copyright: (c) 2016 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 import whoosh
 import whoosh
 from flask_whooshee import AbstractWhoosheer
 from flask_whooshee import AbstractWhoosheer
 
 
@@ -17,6 +18,9 @@ from flaskbb.forum.models import Forum, Topic, Post
 from flaskbb.user.models import User
 from flaskbb.user.models import User
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 class PostWhoosheer(AbstractWhoosheer):
 class PostWhoosheer(AbstractWhoosheer):
     models = [Post]
     models = [Post]
 
 

+ 4 - 0
flaskbb/utils/tokens.py

@@ -9,6 +9,7 @@
     :copyright: (c) 2014 by the FlaskBB Team.
     :copyright: (c) 2014 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 from flask import current_app
 from flask import current_app
 from itsdangerous import (TimedJSONWebSignatureSerializer, SignatureExpired,
 from itsdangerous import (TimedJSONWebSignatureSerializer, SignatureExpired,
                           BadSignature)
                           BadSignature)
@@ -16,6 +17,9 @@ from itsdangerous import (TimedJSONWebSignatureSerializer, SignatureExpired,
 from flaskbb.user.models import User
 from flaskbb.user.models import User
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 def make_token(user, operation, expire=3600):
 def make_token(user, operation, expire=3600):
     """Generates a JSON Web Signature (JWS).
     """Generates a JSON Web Signature (JWS).
     See `RFC 7515 <https://tools.ietf.org/html/rfc7515>` if you want to know
     See `RFC 7515 <https://tools.ietf.org/html/rfc7515>` if you want to know

+ 4 - 0
flaskbb/utils/translations.py

@@ -8,6 +8,7 @@
     :copyright: (c) 2016 by the FlaskBB Team.
     :copyright: (c) 2016 by the FlaskBB Team.
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
+import logging
 import os
 import os
 import subprocess
 import subprocess
 
 
@@ -17,6 +18,9 @@ from flask import current_app
 from flask_babelplus import Domain, get_locale
 from flask_babelplus import Domain, get_locale
 
 
 
 
+logger = logging.getLogger(__name__)
+
+
 class FlaskBBDomain(Domain):
 class FlaskBBDomain(Domain):
     def __init__(self, app):
     def __init__(self, app):
         self.app = app
         self.app = app