Introduce an internal log level for debug to simplify Script logging

This commit is contained in:
Jeremy Stretch 2024-02-05 16:37:39 -05:00
parent a6f5e7260b
commit d7bcf3d4cc
3 changed files with 58 additions and 33 deletions

View File

@ -1,3 +1,5 @@
import logging
from django.utils.translation import gettext_lazy as _
from utilities.choices import ButtonColorChoices, ChoiceSet
@ -164,6 +166,7 @@ class JournalEntryKindChoices(ChoiceSet):
class LogLevelChoices(ChoiceSet):
LOG_DEBUG = 'debug'
LOG_DEFAULT = 'default'
LOG_SUCCESS = 'success'
LOG_INFO = 'info'
@ -171,6 +174,7 @@ class LogLevelChoices(ChoiceSet):
LOG_FAILURE = 'failure'
CHOICES = (
(LOG_DEBUG, _('Debug'), 'teal'),
(LOG_DEFAULT, _('Default'), 'gray'),
(LOG_SUCCESS, _('Success'), 'green'),
(LOG_INFO, _('Info'), 'cyan'),
@ -178,6 +182,15 @@ class LogLevelChoices(ChoiceSet):
(LOG_FAILURE, _('Failure'), 'red'),
)
SYSTEM_LEVELS = {
LOG_DEBUG: logging.DEBUG,
LOG_DEFAULT: logging.INFO,
LOG_SUCCESS: logging.INFO,
LOG_INFO: logging.INFO,
LOG_WARNING: logging.WARNING,
LOG_FAILURE: logging.ERROR,
}
class DurationChoices(ChoiceSet):

View File

@ -1,3 +1,4 @@
from .choices import LogLevelChoices
from .scripts import BaseScript
__all__ = (
@ -6,6 +7,15 @@ __all__ = (
class Report(BaseScript):
#
# Legacy logging methods for Reports
#
# There is no generic log() equivalent on BaseScript
def log(self, message):
self._log(message, None, level=LogLevelChoices.LOG_DEFAULT)
def log_success(self, obj=None, message=None):
super().log_success(message, obj)
@ -17,3 +27,7 @@ class Report(BaseScript):
def log_failure(self, obj=None, message=None):
super().log_failure(message, obj)
# Added in v4.0 to avoid confusion with the log_debug() method provided by BaseScript
def log_debug(self, obj=None, message=None):
super().log_debug(message, obj)

View File

@ -286,10 +286,10 @@ class BaseScript:
# Compile test methods and initialize results skeleton
self._logs[''] = {
'success': 0,
'info': 0,
'warning': 0,
'failure': 0,
LogLevelChoices.LOG_SUCCESS: 0,
LogLevelChoices.LOG_INFO: 0,
LogLevelChoices.LOG_WARNING: 0,
LogLevelChoices.LOG_FAILURE: 0,
'log': [],
}
test_methods = []
@ -297,10 +297,10 @@ class BaseScript:
if method.startswith('test_') and callable(getattr(self, method)):
test_methods.append(method)
self._logs[method] = {
'success': 0,
'info': 0,
'warning': 0,
'failure': 0,
LogLevelChoices.LOG_SUCCESS: 0,
LogLevelChoices.LOG_INFO: 0,
LogLevelChoices.LOG_WARNING: 0,
LogLevelChoices.LOG_FAILURE: 0,
'log': [],
}
self.test_methods = test_methods
@ -437,53 +437,51 @@ class BaseScript:
# Logging
def _log(self, message, obj=None, log_level=LogLevelChoices.LOG_DEFAULT, level=logging.INFO):
def _log(self, message, obj=None, level=LogLevelChoices.LOG_DEFAULT):
"""
Log a message from a test method. Do not call this method directly; use one of the log_* wrappers below.
Log a message. Do not call this method directly; use one of the log_* wrappers below.
"""
if log_level not in LogLevelChoices.values():
raise Exception(f"Unknown logging level: {log_level}")
if level not in LogLevelChoices.values():
raise ValueError(f"Invalid logging level: {level}")
if message:
# Record to the script's log
self._logs[self._current_method]['log'].append((
timezone.now().isoformat(),
log_level,
level,
str(obj) if obj else None,
obj.get_absolute_url() if hasattr(obj, 'get_absolute_url') else None,
message,
str(message),
))
if log_level != LogLevelChoices.LOG_DEFAULT:
self._logs[self._current_method][log_level] += 1
# Record to the system log
if obj:
message = f"{obj}: {message}"
self.logger.log(LogLevelChoices.SYSTEM_LEVELS[level], message)
if self._current_method != '':
self._logs[''][log_level] += 1
# Increment the event counter for this level if applicable
if level in self._logs[self._current_method]:
self._logs[self._current_method][level] += 1
if obj:
self.logger.log(level, f"{log_level.capitalize()} | {obj}: {message}")
else:
self.logger.log(level, message) # No syslog equivalent for SUCCESS
def log(self, message):
"""
Log a message which is not associated with a particular object.
"""
self._log(str(message), None, log_level=LogLevelChoices.LOG_DEFAULT, level=logging.INFO)
# For individual test methods, increment the global counter as well
if self._current_method:
self._logs[''][level] += 1
def log_debug(self, message, obj=None):
self._log(str(message), obj, log_level=LogLevelChoices.LOG_DEFAULT, level=logging.DEBUG)
self._log(message, obj, level=LogLevelChoices.LOG_DEBUG)
def log_success(self, message, obj=None):
self._log(str(message), obj, log_level=LogLevelChoices.LOG_SUCCESS, level=logging.INFO)
self._log(message, obj, level=LogLevelChoices.LOG_SUCCESS)
def log_info(self, message, obj=None):
self._log(str(message), obj, log_level=LogLevelChoices.LOG_INFO, level=logging.INFO)
self._log(message, obj, level=LogLevelChoices.LOG_INFO)
def log_warning(self, message, obj=None):
self._log(str(message), obj, log_level=LogLevelChoices.LOG_WARNING, level=logging.WARNING)
self._log(message, obj, level=LogLevelChoices.LOG_WARNING)
def log_failure(self, message, obj=None):
self._log(str(message), obj, log_level=LogLevelChoices.LOG_FAILURE, level=logging.ERROR)
self._log(message, obj, level=LogLevelChoices.LOG_FAILURE)
self._failed = True
# Convenience functions