mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-06-07 19:03:23 +03:00
Logging: Make correct loggers for 'found' plugins
* Log messages propagate up Parent.Child chains, so we don't need a channel on the plugin logger. * But it still needs the filter to define qualname and class for formatting.
This commit is contained in:
parent
3dab0e9d91
commit
898ff9fbb2
@ -35,6 +35,8 @@ from typing import Tuple
|
|||||||
#
|
#
|
||||||
# 14. Call from *package*
|
# 14. Call from *package*
|
||||||
|
|
||||||
|
_default_loglevel = logging.DEBUG
|
||||||
|
|
||||||
|
|
||||||
class Logger:
|
class Logger:
|
||||||
"""
|
"""
|
||||||
@ -47,7 +49,7 @@ class Logger:
|
|||||||
Users of this class should then call getLogger() to get the
|
Users of this class should then call getLogger() to get the
|
||||||
logging.Logger instance.
|
logging.Logger instance.
|
||||||
"""
|
"""
|
||||||
def __init__(self, logger_name: str, loglevel: int = logging.DEBUG):
|
def __init__(self, logger_name: str, loglevel: int = _default_loglevel):
|
||||||
"""
|
"""
|
||||||
Set up a `logging.Logger` with our preferred configuration.
|
Set up a `logging.Logger` with our preferred configuration.
|
||||||
This includes using an EDMCContextFilter to add 'class' and 'qualname'
|
This includes using an EDMCContextFilter to add 'class' and 'qualname'
|
||||||
@ -78,6 +80,33 @@ class Logger:
|
|||||||
return self.logger
|
return self.logger
|
||||||
|
|
||||||
|
|
||||||
|
def get_plugin_logger(name: str, loglevel: int = _default_loglevel) -> logging.Logger:
|
||||||
|
"""
|
||||||
|
'Found' plugins need their own logger to call out where the logging is
|
||||||
|
coming from, but we don't need to set up *everything* for them.
|
||||||
|
|
||||||
|
The name will be '{config.appname}.{plugin.name}', e.g.
|
||||||
|
'EDMarketConnector.miggytest'. This means that any logging sent through
|
||||||
|
there *also* goes to the channels defined in the 'EDMarketConnector'
|
||||||
|
logger, so we can let that take care of the formatting.
|
||||||
|
|
||||||
|
If we add our own channel then the output gets duplicated (assuming same
|
||||||
|
logLevel set).
|
||||||
|
|
||||||
|
However we do need to attach our filter to this still. That's not at
|
||||||
|
the channel level.
|
||||||
|
:param name: Name of this Logger.
|
||||||
|
:param loglevel: Optional logLevel for this Logger.
|
||||||
|
:return: logging.Logger instance, all set up.
|
||||||
|
"""
|
||||||
|
plugin_logger = logging.getLogger(name)
|
||||||
|
plugin_logger.setLevel(loglevel)
|
||||||
|
|
||||||
|
plugin_logger.addFilter(EDMCContextFilter())
|
||||||
|
|
||||||
|
return plugin_logger
|
||||||
|
|
||||||
|
|
||||||
class EDMCContextFilter(logging.Filter):
|
class EDMCContextFilter(logging.Filter):
|
||||||
"""
|
"""
|
||||||
logging.Filter sub-class to place extra attributes of the calling site
|
logging.Filter sub-class to place extra attributes of the calling site
|
||||||
|
16
plug.py
16
plug.py
@ -8,12 +8,14 @@ import importlib
|
|||||||
import sys
|
import sys
|
||||||
import operator
|
import operator
|
||||||
import threading # noqa: F401 - We don't use it, but plugins might
|
import threading # noqa: F401 - We don't use it, but plugins might
|
||||||
|
from typing import Optional
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
|
||||||
import myNotebook as nb # noqa: N813
|
import myNotebook as nb # noqa: N813
|
||||||
|
|
||||||
from config import config, appname
|
from config import config, appname
|
||||||
|
import EDMCLogging
|
||||||
|
|
||||||
logger = logging.getLogger(appname)
|
logger = logging.getLogger(appname)
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ last_error = {
|
|||||||
|
|
||||||
class Plugin(object):
|
class Plugin(object):
|
||||||
|
|
||||||
def __init__(self, name, loadfile):
|
def __init__(self, name: str, loadfile: str, plugin_logger: Optional[logging.Logger]):
|
||||||
"""
|
"""
|
||||||
Load a single plugin
|
Load a single plugin
|
||||||
:param name: module name
|
:param name: module name
|
||||||
@ -90,6 +92,7 @@ class Plugin(object):
|
|||||||
self.name = name # Display name.
|
self.name = name # Display name.
|
||||||
self.folder = name # basename of plugin folder. None for internal plugins.
|
self.folder = name # basename of plugin folder. None for internal plugins.
|
||||||
self.module = None # None for disabled plugins.
|
self.module = None # None for disabled plugins.
|
||||||
|
self.logger = plugin_logger
|
||||||
|
|
||||||
if loadfile:
|
if loadfile:
|
||||||
logger.info(f'loading plugin "{name.replace(".", "_")}" from "{loadfile}"')
|
logger.info(f'loading plugin "{name.replace(".", "_")}" from "{loadfile}"')
|
||||||
@ -173,7 +176,7 @@ def load_plugins(master):
|
|||||||
for name in sorted(os.listdir(config.internal_plugin_dir)):
|
for name in sorted(os.listdir(config.internal_plugin_dir)):
|
||||||
if name.endswith('.py') and not name[0] in ['.', '_']:
|
if name.endswith('.py') and not name[0] in ['.', '_']:
|
||||||
try:
|
try:
|
||||||
plugin = Plugin(name[:-3], os.path.join(config.internal_plugin_dir, name))
|
plugin = Plugin(name[:-3], os.path.join(config.internal_plugin_dir, name), logger)
|
||||||
plugin.folder = None # Suppress listing in Plugins prefs tab
|
plugin.folder = None # Suppress listing in Plugins prefs tab
|
||||||
internal.append(plugin)
|
internal.append(plugin)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -191,12 +194,17 @@ def load_plugins(master):
|
|||||||
pass
|
pass
|
||||||
elif name.endswith('.disabled'):
|
elif name.endswith('.disabled'):
|
||||||
name, discard = name.rsplit('.', 1)
|
name, discard = name.rsplit('.', 1)
|
||||||
found.append(Plugin(name, None))
|
found.append(Plugin(name, None, logger))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
# Add plugin's folder to load path in case plugin has internal package dependencies
|
# Add plugin's folder to load path in case plugin has internal package dependencies
|
||||||
sys.path.append(os.path.join(config.plugin_dir, name))
|
sys.path.append(os.path.join(config.plugin_dir, name))
|
||||||
found.append(Plugin(name, os.path.join(config.plugin_dir, name, 'load.py')))
|
|
||||||
|
# Create a logger for this 'found' plugin. Must be before the
|
||||||
|
# load.py is loaded.
|
||||||
|
plugin_logger = EDMCLogging.get_plugin_logger(f'{appname}.{name}')
|
||||||
|
|
||||||
|
found.append(Plugin(name, os.path.join(config.plugin_dir, name, 'load.py'), plugin_logger))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f'Failure loading found Plugin "{name}"')
|
logger.exception(f'Failure loading found Plugin "{name}"')
|
||||||
pass
|
pass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user