From 09add21a1a7755ad67ee7e9e0717b1b9be6d8317 Mon Sep 17 00:00:00 2001
From: Athanasius <github@miggy.org>
Date: Tue, 8 Sep 2020 10:03:16 +0100
Subject: [PATCH] Logging: DEBUG always to rotated files, configured level to
 stdout/err

* EDMCLogging.Logger.get_streamhandler() method to get the
  logger_channel so prefs.py can call setLevel() on it.
* The top-level Logger level is always DEBUG.
* The RotatingFileHandler level is always DEBUG.
* The StreamHandler level is as configured by the user.
* EDMCLogging now creates a singleton of EDMCLogging.Logger and its
  associated Logger.
* plug.py tweaked to only import EDMCLogging where it's needed for
  getting/creating plugin loggers, else `import logging`.
---
 EDMCLogging.py       | 21 +++++++++++++++++++--
 EDMarketConnector.py |  7 +------
 plug.py              |  3 ++-
 prefs.py             |  3 ++-
 4 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/EDMCLogging.py b/EDMCLogging.py
index 8458ac88..4208dc28 100644
--- a/EDMCLogging.py
+++ b/EDMCLogging.py
@@ -65,7 +65,9 @@ class Logger:
         """
         self.logger = logging.getLogger(logger_name)
         # Configure the logging.Logger
-        self.logger.setLevel(loglevel)
+        # This needs to always be DEBUG in order to let DEBUG level messages
+        # through to check the *handler* levels.
+        self.logger.setLevel(logging.DEBUG)
 
         # Set up filter for adding class name
         self.logger_filter = EDMCContextFilter()
@@ -73,7 +75,8 @@ class Logger:
 
         # Our basic channel handling stdout
         self.logger_channel = logging.StreamHandler()
-        # Do *NOT* set here, want logger's level to work: self.logger_channel.setLevel(loglevel)
+        # This should be affected by the user configured log level
+        self.logger_channel.setLevel(loglevel)
 
         self.logger_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(module)s.%(qualname)s:%(lineno)d: %(message)s')  # noqa: E501
         self.logger_formatter.default_time_format = '%Y-%m-%d %H:%M:%S'
@@ -111,6 +114,13 @@ class Logger:
         """
         return self.logger
 
+    def get_streamhandler(self) -> logging.Handler:
+        """
+        Obtain the self.logger_channel StreamHandler instance.
+        :return: logging.StreamHandler
+        """
+        return self.logger_channel
+
 
 def get_plugin_logger(name: str, loglevel: int = _default_loglevel) -> logging.Logger:
     """
@@ -315,3 +325,10 @@ class EDMCContextFilter(logging.Filter):
                     module_name = f'plugins.{name_path}.{module_name}'
 
         return module_name
+
+# Singleton
+loglevel = config.get('loglevel')
+if not loglevel:
+    loglevel = logging.INFO
+edmclogger = Logger(appname, loglevel=loglevel)
+logger = edmclogger.get_logger()
diff --git a/EDMarketConnector.py b/EDMarketConnector.py
index 55541345..d79f1c8a 100755
--- a/EDMarketConnector.py
+++ b/EDMarketConnector.py
@@ -13,8 +13,6 @@ import html
 from time import time, localtime, strftime
 import webbrowser
 
-import EDMCLogging
-import logging
 from config import appname, applongname, appversion, appversion_nobuild, copyright, config
 
 if getattr(sys, 'frozen', False):
@@ -1031,10 +1029,7 @@ if __name__ == "__main__":
 
     enforce_single_instance()
 
-    loglevel = config.get('loglevel')
-    if not loglevel:
-        loglevel = logging.INFO
-    logger = EDMCLogging.Logger(appname, loglevel=loglevel).get_logger()
+    from EDMCLogging import logger
     logger.info('Startup')
 
     # TODO: unittests in place of these
diff --git a/plug.py b/plug.py
index 0a0a3f8a..51d73531 100644
--- a/plug.py
+++ b/plug.py
@@ -15,7 +15,7 @@ import tkinter as tk
 import myNotebook as nb  # noqa: N813
 
 from config import config, appname
-import EDMCLogging
+import logging
 
 logger = logging.getLogger(appname)
 
@@ -202,6 +202,7 @@ def load_plugins(master):
 
                 # Create a logger for this 'found' plugin.  Must be before the
                 # load.py is loaded.
+                import EDMCLogging
                 plugin_logger = EDMCLogging.get_plugin_logger(f'{appname}.{name}')
 
                 found.append(Plugin(name, os.path.join(config.plugin_dir, name, 'load.py'), plugin_logger))
diff --git a/prefs.py b/prefs.py
index 700c52c0..5af25814 100644
--- a/prefs.py
+++ b/prefs.py
@@ -18,6 +18,7 @@ from theme import theme
 import plug
 import logging
 logger = logging.getLogger(appname)
+from EDMCLogging import edmclogger
 
 ###########################################################################
 # Versioned preferences, so we know whether to set an 'on' default on
@@ -621,7 +622,7 @@ class PreferencesDialog(tk.Toplevel):
         config.set('system_provider', self.system_provider.get())
         config.set('station_provider', self.station_provider.get())
         config.set('loglevel', self.select_loglevel.get())
-        logger.setLevel(self.select_loglevel.get())
+        edmclogger.get_streamhandler().setLevel(self.select_loglevel.get())
 
         lang_codes = { v: k for k, v in self.languages.items() }	# Codes by name
         config.set('language', lang_codes.get(self.lang.get()) or '')