From f49b84d6b1186ead443ff41a0d557101acef926a Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Sun, 24 Oct 2021 18:56:21 -0400 Subject: [PATCH 01/22] Add FileHandler class I needed to implement this class for keeping logs on an SD card I was already needed for file storage, I thought it might be a good addition to the library as a LoggingHandler --- adafruit_logging.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/adafruit_logging.py b/adafruit_logging.py index a095315..627acad 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -91,6 +91,32 @@ def emit(self, level, msg): print(self.format(level, msg)) +class FileHandler(LoggingHandler): + '''File handler for working with log files off of the microcontroller (like + an SD card) + + :param filepath: The filepath to the log file + :param overwrite: Whether the log should be overwritten (True) \ + or appended (False); default is to append + ''' + + def __init__(self, filepath: str, overwrite: bool = False): + self._filepath = filepath + if overwrite: + log_file = open(self._filepath, 'w') + log_file.close() + + def emit(self, level: int, msg: str): + '''Append a formatted message to the log + + :param level: The level of the message + :param msg: The message to log + ''' + + with open(self._filepath, 'a') as log_file: + log_file.write(self.format(level, msg) + "\n") + + # The level module-global variables get created when loaded # pylint:disable=undefined-variable From 1e061cf550e0a16e903d42b7e612ac416d49df9b Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:35:24 -0400 Subject: [PATCH 02/22] Ran pre-commit --- adafruit_logging.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 627acad..2ee989c 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -92,28 +92,28 @@ def emit(self, level, msg): class FileHandler(LoggingHandler): - '''File handler for working with log files off of the microcontroller (like + """File handler for working with log files off of the microcontroller (like an SD card) - + :param filepath: The filepath to the log file :param overwrite: Whether the log should be overwritten (True) \ or appended (False); default is to append - ''' + """ def __init__(self, filepath: str, overwrite: bool = False): self._filepath = filepath if overwrite: - log_file = open(self._filepath, 'w') + log_file = open(self._filepath, "w") log_file.close() def emit(self, level: int, msg: str): - '''Append a formatted message to the log - + """Append a formatted message to the log + :param level: The level of the message :param msg: The message to log - ''' + """ - with open(self._filepath, 'a') as log_file: + with open(self._filepath, "a") as log_file: log_file.write(self.format(level, msg) + "\n") From 135ed8752dba7956514b60c809a30b85b2eb30e6 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Mon, 25 Oct 2021 20:50:23 -0400 Subject: [PATCH 03/22] Fix lint --- adafruit_logging.py | 544 ++++++++++++++++++++++---------------------- 1 file changed, 272 insertions(+), 272 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 2ee989c..6f4be8d 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -1,272 +1,272 @@ -# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -""" -`adafruit_logging` -================================================================================ - -Logging module for CircuitPython - - -* Author(s): Dave Astels - -Implementation Notes --------------------- - -**Hardware:** - - -**Software and Dependencies:** - -* Adafruit CircuitPython firmware for the supported boards: - https://github.com/adafruit/circuitpython/releases - -""" -# pylint:disable=redefined-outer-name,consider-using-enumerate,no-self-use -# pylint:disable=invalid-name - -import time - -__version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Logger.git" - - -LEVELS = [ - (00, "NOTSET"), - (10, "DEBUG"), - (20, "INFO"), - (30, "WARNING"), - (40, "ERROR"), - (50, "CRITICAL"), -] - -for value, name in LEVELS: - globals()[name] = value - - -def level_for(value): - """Convert a numberic level to the most appropriate name. - - :param value: a numeric level - - """ - for i in range(len(LEVELS)): - if value == LEVELS[i][0]: - return LEVELS[i][1] - if value < LEVELS[i][0]: - return LEVELS[i - 1][1] - return LEVELS[0][1] - - -class LoggingHandler: - """Abstract logging message handler.""" - - def format(self, level, msg): - """Generate a timestamped message. - - :param level: the logging level - :param msg: the message to log - - """ - return "{0}: {1} - {2}".format(time.monotonic(), level_for(level), msg) - - def emit(self, level, msg): - """Send a message where it should go. - Place holder for subclass implementations. - """ - raise NotImplementedError() - - -class PrintHandler(LoggingHandler): - """Send logging messages to the console by using print.""" - - def emit(self, level, msg): - """Send a message to teh console. - - :param level: the logging level - :param msg: the message to log - - """ - print(self.format(level, msg)) - - -class FileHandler(LoggingHandler): - """File handler for working with log files off of the microcontroller (like - an SD card) - - :param filepath: The filepath to the log file - :param overwrite: Whether the log should be overwritten (True) \ - or appended (False); default is to append - """ - - def __init__(self, filepath: str, overwrite: bool = False): - self._filepath = filepath - if overwrite: - log_file = open(self._filepath, "w") - log_file.close() - - def emit(self, level: int, msg: str): - """Append a formatted message to the log - - :param level: The level of the message - :param msg: The message to log - """ - - with open(self._filepath, "a") as log_file: - log_file.write(self.format(level, msg) + "\n") - - -# The level module-global variables get created when loaded -# pylint:disable=undefined-variable - -logger_cache = dict() -null_logger = None - -# pylint:disable=global-statement -def getLogger(name): - """Create or retrieve a logger by name. - - :param name: the name of the logger to create/retrieve None will cause the - NullLogger instance to be returned. - - """ - global null_logger - if not name or name == "": - if not null_logger: - null_logger = NullLogger() - return null_logger - - if name not in logger_cache: - logger_cache[name] = Logger() - return logger_cache[name] - - -# pylint:enable=global-statement - - -class Logger: - """Provide a logging api.""" - - def __init__(self): - """Create an instance.""" - self._level = NOTSET - self._handler = PrintHandler() - - def setLevel(self, value): - """Set the logging cuttoff level. - - :param value: the lowest level to output - - """ - self._level = value - - def getEffectiveLevel(self): - """Get the effective level for this logger. - - :return: the lowest level to output - - """ - return self._level - - def addHandler(self, hldr): - """Sets the handler of this logger to the specified handler. - *NOTE* this is slightly different from the CPython equivalent which adds - the handler rather than replaceing it. - - :param hldr: the handler - - """ - self._handler = hldr - - def log(self, level, format_string, *args): - """Log a message. - - :param level: the priority level at which to log - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - if level >= self._level: - self._handler.emit(level, format_string % args) - - def debug(self, format_string, *args): - """Log a debug message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(DEBUG, format_string, *args) - - def info(self, format_string, *args): - """Log a info message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(INFO, format_string, *args) - - def warning(self, format_string, *args): - """Log a warning message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(WARNING, format_string, *args) - - def error(self, format_string, *args): - """Log a error message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(ERROR, format_string, *args) - - def critical(self, format_string, *args): - """Log a critical message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(CRITICAL, format_string, *args) - - -class NullLogger: - """Provide an empty logger. - This can be used in place of a real logger to more efficiently disable logging.""" - - def __init__(self): - """Dummy implementation.""" - - def setLevel(self, value): - """Dummy implementation.""" - - def getEffectiveLevel(self): - """Dummy implementation.""" - return NOTSET - - def addHandler(self, hldr): - """Dummy implementation.""" - - def log(self, level, format_string, *args): - """Dummy implementation.""" - - def debug(self, format_string, *args): - """Dummy implementation.""" - - def info(self, format_string, *args): - """Dummy implementation.""" - - def warning(self, format_string, *args): - """Dummy implementation.""" - - def error(self, format_string, *args): - """Dummy implementation.""" - - def critical(self, format_string, *args): - """Dummy implementation.""" +# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +`adafruit_logging` +================================================================================ + +Logging module for CircuitPython + + +* Author(s): Dave Astels + +Implementation Notes +-------------------- + +**Hardware:** + + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases + +""" +# pylint:disable=redefined-outer-name,consider-using-enumerate,no-self-use +# pylint:disable=invalid-name + +import time + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Logger.git" + + +LEVELS = [ + (00, "NOTSET"), + (10, "DEBUG"), + (20, "INFO"), + (30, "WARNING"), + (40, "ERROR"), + (50, "CRITICAL"), +] + +for value, name in LEVELS: + globals()[name] = value + + +def level_for(value): + """Convert a numberic level to the most appropriate name. + + :param value: a numeric level + + """ + for i in range(len(LEVELS)): + if value == LEVELS[i][0]: + return LEVELS[i][1] + if value < LEVELS[i][0]: + return LEVELS[i - 1][1] + return LEVELS[0][1] + + +class LoggingHandler: + """Abstract logging message handler.""" + + def format(self, level, msg): + """Generate a timestamped message. + + :param level: the logging level + :param msg: the message to log + + """ + return "{0}: {1} - {2}".format(time.monotonic(), level_for(level), msg) + + def emit(self, level, msg): + """Send a message where it should go. + Place holder for subclass implementations. + """ + raise NotImplementedError() + + +class PrintHandler(LoggingHandler): + """Send logging messages to the console by using print.""" + + def emit(self, level, msg): + """Send a message to teh console. + + :param level: the logging level + :param msg: the message to log + + """ + print(self.format(level, msg)) + + +class FileHandler(LoggingHandler): + """File handler for working with log files off of the microcontroller (like + an SD card) + + :param filepath: The filepath to the log file + :param overwrite: Whether the log should be overwritten (True) \ + or appended (False); default is to append + """ + + def __init__(self, filepath: str, overwrite: bool = False): + self._filepath = filepath + if overwrite: + log_file = open(self._filepath, "w", encoding="utf-8") + log_file.close() + + def emit(self, level: int, msg: str): + """Append a formatted message to the log + + :param level: The level of the message + :param msg: The message to log + """ + + with open(self._filepath, "a", encoding="utf-8") as log_file: + log_file.write(self.format(level, msg) + "\n") + + +# The level module-global variables get created when loaded +# pylint:disable=undefined-variable + +logger_cache = dict() +null_logger = None + +# pylint:disable=global-statement +def getLogger(name): + """Create or retrieve a logger by name. + + :param name: the name of the logger to create/retrieve None will cause the + NullLogger instance to be returned. + + """ + global null_logger + if not name or name == "": + if not null_logger: + null_logger = NullLogger() + return null_logger + + if name not in logger_cache: + logger_cache[name] = Logger() + return logger_cache[name] + + +# pylint:enable=global-statement + + +class Logger: + """Provide a logging api.""" + + def __init__(self): + """Create an instance.""" + self._level = NOTSET + self._handler = PrintHandler() + + def setLevel(self, value): + """Set the logging cuttoff level. + + :param value: the lowest level to output + + """ + self._level = value + + def getEffectiveLevel(self): + """Get the effective level for this logger. + + :return: the lowest level to output + + """ + return self._level + + def addHandler(self, hldr): + """Sets the handler of this logger to the specified handler. + *NOTE* this is slightly different from the CPython equivalent which adds + the handler rather than replaceing it. + + :param hldr: the handler + + """ + self._handler = hldr + + def log(self, level, format_string, *args): + """Log a message. + + :param level: the priority level at which to log + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + if level >= self._level: + self._handler.emit(level, format_string % args) + + def debug(self, format_string, *args): + """Log a debug message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(DEBUG, format_string, *args) + + def info(self, format_string, *args): + """Log a info message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(INFO, format_string, *args) + + def warning(self, format_string, *args): + """Log a warning message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(WARNING, format_string, *args) + + def error(self, format_string, *args): + """Log a error message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(ERROR, format_string, *args) + + def critical(self, format_string, *args): + """Log a critical message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(CRITICAL, format_string, *args) + + +class NullLogger: + """Provide an empty logger. + This can be used in place of a real logger to more efficiently disable logging.""" + + def __init__(self): + """Dummy implementation.""" + + def setLevel(self, value): + """Dummy implementation.""" + + def getEffectiveLevel(self): + """Dummy implementation.""" + return NOTSET + + def addHandler(self, hldr): + """Dummy implementation.""" + + def log(self, level, format_string, *args): + """Dummy implementation.""" + + def debug(self, format_string, *args): + """Dummy implementation.""" + + def info(self, format_string, *args): + """Dummy implementation.""" + + def warning(self, format_string, *args): + """Dummy implementation.""" + + def error(self, format_string, *args): + """Dummy implementation.""" + + def critical(self, format_string, *args): + """Dummy implementation.""" From fe1e0756f145957cd0a77fc16b095128a51ad4da Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Mon, 25 Oct 2021 21:00:45 -0400 Subject: [PATCH 04/22] Fix lint --- adafruit_logging.py | 436 ++++++++++++++++++++++---------------------- 1 file changed, 218 insertions(+), 218 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 6f4be8d..559c55b 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -52,221 +52,221 @@ def level_for(value): """ for i in range(len(LEVELS)): - if value == LEVELS[i][0]: - return LEVELS[i][1] - if value < LEVELS[i][0]: - return LEVELS[i - 1][1] - return LEVELS[0][1] - - -class LoggingHandler: - """Abstract logging message handler.""" - - def format(self, level, msg): - """Generate a timestamped message. - - :param level: the logging level - :param msg: the message to log - - """ - return "{0}: {1} - {2}".format(time.monotonic(), level_for(level), msg) - - def emit(self, level, msg): - """Send a message where it should go. - Place holder for subclass implementations. - """ - raise NotImplementedError() - - -class PrintHandler(LoggingHandler): - """Send logging messages to the console by using print.""" - - def emit(self, level, msg): - """Send a message to teh console. - - :param level: the logging level - :param msg: the message to log - - """ - print(self.format(level, msg)) - - -class FileHandler(LoggingHandler): - """File handler for working with log files off of the microcontroller (like - an SD card) - - :param filepath: The filepath to the log file - :param overwrite: Whether the log should be overwritten (True) \ - or appended (False); default is to append - """ - - def __init__(self, filepath: str, overwrite: bool = False): - self._filepath = filepath - if overwrite: - log_file = open(self._filepath, "w", encoding="utf-8") - log_file.close() - - def emit(self, level: int, msg: str): - """Append a formatted message to the log - - :param level: The level of the message - :param msg: The message to log - """ - - with open(self._filepath, "a", encoding="utf-8") as log_file: - log_file.write(self.format(level, msg) + "\n") - - -# The level module-global variables get created when loaded -# pylint:disable=undefined-variable - -logger_cache = dict() -null_logger = None - -# pylint:disable=global-statement -def getLogger(name): - """Create or retrieve a logger by name. - - :param name: the name of the logger to create/retrieve None will cause the - NullLogger instance to be returned. - - """ - global null_logger - if not name or name == "": - if not null_logger: - null_logger = NullLogger() - return null_logger - - if name not in logger_cache: - logger_cache[name] = Logger() - return logger_cache[name] - - -# pylint:enable=global-statement - - -class Logger: - """Provide a logging api.""" - - def __init__(self): - """Create an instance.""" - self._level = NOTSET - self._handler = PrintHandler() - - def setLevel(self, value): - """Set the logging cuttoff level. - - :param value: the lowest level to output - - """ - self._level = value - - def getEffectiveLevel(self): - """Get the effective level for this logger. - - :return: the lowest level to output - - """ - return self._level - - def addHandler(self, hldr): - """Sets the handler of this logger to the specified handler. - *NOTE* this is slightly different from the CPython equivalent which adds - the handler rather than replaceing it. - - :param hldr: the handler - - """ - self._handler = hldr - - def log(self, level, format_string, *args): - """Log a message. - - :param level: the priority level at which to log - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - if level >= self._level: - self._handler.emit(level, format_string % args) - - def debug(self, format_string, *args): - """Log a debug message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(DEBUG, format_string, *args) - - def info(self, format_string, *args): - """Log a info message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(INFO, format_string, *args) - - def warning(self, format_string, *args): - """Log a warning message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(WARNING, format_string, *args) - - def error(self, format_string, *args): - """Log a error message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(ERROR, format_string, *args) - - def critical(self, format_string, *args): - """Log a critical message. - - :param format_string: the core message string with embedded formatting directives - :param args: arguments to ``format_string.format()``, can be empty - - """ - self.log(CRITICAL, format_string, *args) - - -class NullLogger: - """Provide an empty logger. - This can be used in place of a real logger to more efficiently disable logging.""" - - def __init__(self): - """Dummy implementation.""" - - def setLevel(self, value): - """Dummy implementation.""" - - def getEffectiveLevel(self): - """Dummy implementation.""" - return NOTSET - - def addHandler(self, hldr): - """Dummy implementation.""" - - def log(self, level, format_string, *args): - """Dummy implementation.""" - - def debug(self, format_string, *args): - """Dummy implementation.""" - - def info(self, format_string, *args): - """Dummy implementation.""" - - def warning(self, format_string, *args): - """Dummy implementation.""" - - def error(self, format_string, *args): - """Dummy implementation.""" - - def critical(self, format_string, *args): - """Dummy implementation.""" + if value == LEVELS[i][0]: + return LEVELS[i][1] + if value < LEVELS[i][0]: + return LEVELS[i - 1][1] + return LEVELS[0][1] + + +class LoggingHandler: + """Abstract logging message handler.""" + + def format(self, level, msg): + """Generate a timestamped message. + + :param level: the logging level + :param msg: the message to log + + """ + return "{0}: {1} - {2}".format(time.monotonic(), level_for(level), msg) + + def emit(self, level, msg): + """Send a message where it should go. + Place holder for subclass implementations. + """ + raise NotImplementedError() + + +class PrintHandler(LoggingHandler): + """Send logging messages to the console by using print.""" + + def emit(self, level, msg): + """Send a message to teh console. + + :param level: the logging level + :param msg: the message to log + + """ + print(self.format(level, msg)) + + +class FileHandler(LoggingHandler): + """File handler for working with log files off of the microcontroller (like + an SD card) + + :param filepath: The filepath to the log file + :param overwrite: Whether the log should be overwritten (True) \ + or appended (False); default is to append + """ + + def __init__(self, filepath: str, overwrite: bool = False): + self._filepath = filepath + if overwrite: + log_file = open(self._filepath, "w", encoding="utf-8") + log_file.close() + + def emit(self, level: int, msg: str): + """Append a formatted message to the log + + :param level: The level of the message + :param msg: The message to log + """ + + with open(self._filepath, "a", encoding="utf-8") as log_file: + log_file.write(self.format(level, msg) + "\n") + + +# The level module-global variables get created when loaded +# pylint:disable=undefined-variable + +logger_cache = dict() +null_logger = None + +# pylint:disable=global-statement +def getLogger(name): + """Create or retrieve a logger by name. + + :param name: the name of the logger to create/retrieve None will cause the + NullLogger instance to be returned. + + """ + global null_logger + if not name or name == "": + if not null_logger: + null_logger = NullLogger() + return null_logger + + if name not in logger_cache: + logger_cache[name] = Logger() + return logger_cache[name] + + +# pylint:enable=global-statement + + +class Logger: + """Provide a logging api.""" + + def __init__(self): + """Create an instance.""" + self._level = NOTSET + self._handler = PrintHandler() + + def setLevel(self, value): + """Set the logging cuttoff level. + + :param value: the lowest level to output + + """ + self._level = value + + def getEffectiveLevel(self): + """Get the effective level for this logger. + + :return: the lowest level to output + + """ + return self._level + + def addHandler(self, hldr): + """Sets the handler of this logger to the specified handler. + *NOTE* this is slightly different from the CPython equivalent which adds + the handler rather than replaceing it. + + :param hldr: the handler + + """ + self._handler = hldr + + def log(self, level, format_string, *args): + """Log a message. + + :param level: the priority level at which to log + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + if level >= self._level: + self._handler.emit(level, format_string % args) + + def debug(self, format_string, *args): + """Log a debug message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(DEBUG, format_string, *args) + + def info(self, format_string, *args): + """Log a info message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(INFO, format_string, *args) + + def warning(self, format_string, *args): + """Log a warning message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(WARNING, format_string, *args) + + def error(self, format_string, *args): + """Log a error message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(ERROR, format_string, *args) + + def critical(self, format_string, *args): + """Log a critical message. + + :param format_string: the core message string with embedded formatting directives + :param args: arguments to ``format_string.format()``, can be empty + + """ + self.log(CRITICAL, format_string, *args) + + +class NullLogger: + """Provide an empty logger. + This can be used in place of a real logger to more efficiently disable logging.""" + + def __init__(self): + """Dummy implementation.""" + + def setLevel(self, value): + """Dummy implementation.""" + + def getEffectiveLevel(self): + """Dummy implementation.""" + return NOTSET + + def addHandler(self, hldr): + """Dummy implementation.""" + + def log(self, level, format_string, *args): + """Dummy implementation.""" + + def debug(self, format_string, *args): + """Dummy implementation.""" + + def info(self, format_string, *args): + """Dummy implementation.""" + + def warning(self, format_string, *args): + """Dummy implementation.""" + + def error(self, format_string, *args): + """Dummy implementation.""" + + def critical(self, format_string, *args): + """Dummy implementation.""" From a8e4e64a5fac6fa3c5ec3f2c012afcbf63aca9a3 Mon Sep 17 00:00:00 2001 From: tekktrik <89490472+tekktrik@users.noreply.github.com> Date: Mon, 25 Oct 2021 21:02:24 -0400 Subject: [PATCH 05/22] Finalize fixing CRLF to LF --- adafruit_logging.py | 108 ++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 559c55b..a1eb5de 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -1,57 +1,57 @@ -# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -""" -`adafruit_logging` -================================================================================ - -Logging module for CircuitPython - - -* Author(s): Dave Astels - -Implementation Notes --------------------- - -**Hardware:** - - -**Software and Dependencies:** - -* Adafruit CircuitPython firmware for the supported boards: - https://github.com/adafruit/circuitpython/releases - -""" -# pylint:disable=redefined-outer-name,consider-using-enumerate,no-self-use -# pylint:disable=invalid-name - -import time - -__version__ = "0.0.0-auto.0" -__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Logger.git" - - -LEVELS = [ - (00, "NOTSET"), - (10, "DEBUG"), - (20, "INFO"), - (30, "WARNING"), - (40, "ERROR"), - (50, "CRITICAL"), -] - -for value, name in LEVELS: - globals()[name] = value - - -def level_for(value): - """Convert a numberic level to the most appropriate name. - - :param value: a numeric level - - """ - for i in range(len(LEVELS)): +# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +`adafruit_logging` +================================================================================ + +Logging module for CircuitPython + + +* Author(s): Dave Astels + +Implementation Notes +-------------------- + +**Hardware:** + + +**Software and Dependencies:** + +* Adafruit CircuitPython firmware for the supported boards: + https://github.com/adafruit/circuitpython/releases + +""" +# pylint:disable=redefined-outer-name,consider-using-enumerate,no-self-use +# pylint:disable=invalid-name + +import time + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Logger.git" + + +LEVELS = [ + (00, "NOTSET"), + (10, "DEBUG"), + (20, "INFO"), + (30, "WARNING"), + (40, "ERROR"), + (50, "CRITICAL"), +] + +for value, name in LEVELS: + globals()[name] = value + + +def level_for(value): + """Convert a numberic level to the most appropriate name. + + :param value: a numeric level + + """ + for i in range(len(LEVELS)): if value == LEVELS[i][0]: return LEVELS[i][1] if value < LEVELS[i][0]: From aa87bd6c458d3a0e426f6296a7d3c9f1ba1c8ffd Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 26 Oct 2021 15:28:35 -0400 Subject: [PATCH 06/22] Changed functionality to better represent CPython's functionality This makes the logging a little less safe, but the arguments and functionality now match expected behavior --- adafruit_logging.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index a1eb5de..4b54b1d 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -100,11 +100,12 @@ class FileHandler(LoggingHandler): or appended (False); default is to append """ - def __init__(self, filepath: str, overwrite: bool = False): - self._filepath = filepath - if overwrite: - log_file = open(self._filepath, "w", encoding="utf-8") - log_file.close() + def __init__(self, filepath: str, mode: str = 'a'): + self.logfile = open(filepath, mode, encoding="utf-8") + + def close(self): + """Closes the file""" + self.logfile.close() def emit(self, level: int, msg: str): """Append a formatted message to the log @@ -113,8 +114,7 @@ def emit(self, level: int, msg: str): :param msg: The message to log """ - with open(self._filepath, "a", encoding="utf-8") as log_file: - log_file.write(self.format(level, msg) + "\n") + self.logfile.write(self.format(level, msg) + "\n") # The level module-global variables get created when loaded From 42fe85ad16fff3dbd7ce33011fa29b32f68d4190 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 26 Oct 2021 15:30:39 -0400 Subject: [PATCH 07/22] Updated per results of pre-commit --- adafruit_logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 4b54b1d..a314f79 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -100,7 +100,7 @@ class FileHandler(LoggingHandler): or appended (False); default is to append """ - def __init__(self, filepath: str, mode: str = 'a'): + def __init__(self, filepath: str, mode: str = "a"): self.logfile = open(filepath, mode, encoding="utf-8") def close(self): From 030bf6baf317018285ed87a763bdb24c7b744024 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Tue, 26 Oct 2021 16:48:48 -0400 Subject: [PATCH 08/22] Updated docstring for FileHandler --- adafruit_logging.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index a314f79..ea22233 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -96,8 +96,7 @@ class FileHandler(LoggingHandler): an SD card) :param filepath: The filepath to the log file - :param overwrite: Whether the log should be overwritten (True) \ - or appended (False); default is to append + :param mode: Whether to write ('w') or append ('a'); default is to append """ def __init__(self, filepath: str, mode: str = "a"): From 891a242a897777c3691a551d985aeb373a7929cd Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Wed, 27 Oct 2021 22:43:38 -0400 Subject: [PATCH 09/22] Create example for FileHandler using an SD card Modified from how I use it in my own code --- examples/logging_filehandler.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 examples/logging_filehandler.py diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py new file mode 100644 index 0000000..1a46c01 --- /dev/null +++ b/examples/logging_filehandler.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2021 Alec Delaney +# SPDX-License-Identifier: MIT + +import board +import sdcardio +import storage +import adafruit_logging as logging + +# Initialize SD card +spi = board.SPI() +sdcard = sdcardio.SDCard(spi, board.D10) +vfs = storage.VfsFat(sdcard) +storage.mount(vfs, '/sd') + +# Initialize log functionality +log_filepath = "/sd/testlog.log" +logger = logging.getLogger("testlog") +file_handler = logging.FileHandler(log_filepath) +logger.addHandler(file_handler) +logger.setLevel(logging.INFO) + +logger.info("Logger initialized!") +logger.debug("You can even add debug statements to the log!") \ No newline at end of file From db969d94ede9adaa9aed1e951a6c3ac14769374a Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Wed, 27 Oct 2021 22:49:54 -0400 Subject: [PATCH 10/22] Update example to avoid directly initializing SD card --- examples/logging_filehandler.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index 1a46c01..6102f88 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -6,13 +6,7 @@ import storage import adafruit_logging as logging -# Initialize SD card -spi = board.SPI() -sdcard = sdcardio.SDCard(spi, board.D10) -vfs = storage.VfsFat(sdcard) -storage.mount(vfs, '/sd') - -# Initialize log functionality +# Initialize log functionality on a writable medium, like an SD card log_filepath = "/sd/testlog.log" logger = logging.getLogger("testlog") file_handler = logging.FileHandler(log_filepath) From 57973bc9a801fa64abdf4c9a89dd7c0caf538d33 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Wed, 27 Oct 2021 22:50:31 -0400 Subject: [PATCH 11/22] Remove unused imports --- examples/logging_filehandler.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index 6102f88..eb8c59d 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -2,8 +2,6 @@ # SPDX-License-Identifier: MIT import board -import sdcardio -import storage import adafruit_logging as logging # Initialize log functionality on a writable medium, like an SD card From d82a56a4099e4b9c92cbb119ae6d07e9363124d0 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Wed, 27 Oct 2021 22:50:53 -0400 Subject: [PATCH 12/22] Remove board import --- examples/logging_filehandler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index eb8c59d..d76850b 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -1,7 +1,6 @@ # SPDX-FileCopyrightText: 2021 Alec Delaney # SPDX-License-Identifier: MIT -import board import adafruit_logging as logging # Initialize log functionality on a writable medium, like an SD card From 7735275e9a45da008cf62be7e4ab3936a260dfeb Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Wed, 27 Oct 2021 22:51:07 -0400 Subject: [PATCH 13/22] Update logging_filehandler.py --- examples/logging_filehandler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index d76850b..4c59278 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -11,4 +11,4 @@ logger.setLevel(logging.INFO) logger.info("Logger initialized!") -logger.debug("You can even add debug statements to the log!") \ No newline at end of file +logger.debug("You can even add debug statements to the log!") From 5782c51e0b7c612ca7460dfe68967a57e5072106 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 10:33:05 -0400 Subject: [PATCH 14/22] Changed double quotes to singe quotes --- adafruit_logging.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index ea22233..7dde911 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -99,8 +99,8 @@ class FileHandler(LoggingHandler): :param mode: Whether to write ('w') or append ('a'); default is to append """ - def __init__(self, filepath: str, mode: str = "a"): - self.logfile = open(filepath, mode, encoding="utf-8") + def __init__(self, filepath: str, mode: str = 'a'): + self.logfile = open(filepath, mode, encoding='utf-8') def close(self): """Closes the file""" From c0f29d7a094a1dcadb108a8d9eb76b33f1fc37af Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 10:33:35 -0400 Subject: [PATCH 15/22] Added format method for adding newlines Separated from emit method --- adafruit_logging.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 7dde911..6b90a29 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -106,14 +106,21 @@ def close(self): """Closes the file""" self.logfile.close() - def emit(self, level: int, msg: str): - """Append a formatted message to the log + def format(self, level: int, msg: str): + """Generate a string to log + + :param level: The level of the message + :param msg: The message to format + """ + return super(FileHandler, self).format(level, msg) + '\r\n' + def emit(self, level: int, msg: str): + """Generate the message and write it to the UART. + :param level: The level of the message :param msg: The message to log """ - - self.logfile.write(self.format(level, msg) + "\n") + self.logfile.write(self.format(level, msg)) # The level module-global variables get created when loaded From 0c8a6a3a690903fd3238ecbcc425522902f740ae Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 10:33:53 -0400 Subject: [PATCH 16/22] Updated example to initialize SD card --- examples/logging_filehandler.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index 4c59278..f6cf2d6 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -1,9 +1,24 @@ # SPDX-FileCopyrightText: 2021 Alec Delaney # SPDX-License-Identifier: MIT +import board +import busio +from digitalio import DigitalInOut +import storage +import adafruit_sdcard import adafruit_logging as logging -# Initialize log functionality on a writable medium, like an SD card +# Get chip select pin depending on the board, this one is for the Feather M4 Express +sd_cs = board.D10 + +# Set up an SD card to write to +spi = busio.SPI(board.SCK, board.MOSI, board.MISO) +cs = DigitalInOut(sd_cs) +sdcard = adafruit_sdcard.SDCard(spi, cs) +vfs = storage.VfsFat(sdcard) +storage.mount(vfs, "/sd") + +# Initialize log functionality log_filepath = "/sd/testlog.log" logger = logging.getLogger("testlog") file_handler = logging.FileHandler(log_filepath) From 0b72f5173679cbfb77014674e7415a84b00b16c8 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 10:35:17 -0400 Subject: [PATCH 17/22] Updated formatting from black, using Python 3 style super() --- adafruit_logging.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/adafruit_logging.py b/adafruit_logging.py index 6b90a29..c28f00d 100644 --- a/adafruit_logging.py +++ b/adafruit_logging.py @@ -99,8 +99,8 @@ class FileHandler(LoggingHandler): :param mode: Whether to write ('w') or append ('a'); default is to append """ - def __init__(self, filepath: str, mode: str = 'a'): - self.logfile = open(filepath, mode, encoding='utf-8') + def __init__(self, filepath: str, mode: str = "a"): + self.logfile = open(filepath, mode, encoding="utf-8") def close(self): """Closes the file""" @@ -108,15 +108,15 @@ def close(self): def format(self, level: int, msg: str): """Generate a string to log - + :param level: The level of the message :param msg: The message to format """ - return super(FileHandler, self).format(level, msg) + '\r\n' + return super().format(level, msg) + "\r\n" def emit(self, level: int, msg: str): """Generate the message and write it to the UART. - + :param level: The level of the message :param msg: The message to log """ From 49b1224180fd9fcf6e88ff3d53a6079700e1df3d Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 11:49:37 -0400 Subject: [PATCH 18/22] Move adafruit_logging.py to adafruit_logging/__init__.py --- adafruit_logging.py => adafruit_logging/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename adafruit_logging.py => adafruit_logging/__init__.py (100%) diff --git a/adafruit_logging.py b/adafruit_logging/__init__.py similarity index 100% rename from adafruit_logging.py rename to adafruit_logging/__init__.py From ecc450dbb0bc7c38e0790a8e2af8800e3a20cdee Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 11:52:16 -0400 Subject: [PATCH 19/22] Move FileHandler to extensions.py --- adafruit_logging/__init__.py | 32 -------------------------------- adafruit_logging/extensions.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 32 deletions(-) create mode 100644 adafruit_logging/extensions.py diff --git a/adafruit_logging/__init__.py b/adafruit_logging/__init__.py index c28f00d..a095315 100644 --- a/adafruit_logging/__init__.py +++ b/adafruit_logging/__init__.py @@ -91,38 +91,6 @@ def emit(self, level, msg): print(self.format(level, msg)) -class FileHandler(LoggingHandler): - """File handler for working with log files off of the microcontroller (like - an SD card) - - :param filepath: The filepath to the log file - :param mode: Whether to write ('w') or append ('a'); default is to append - """ - - def __init__(self, filepath: str, mode: str = "a"): - self.logfile = open(filepath, mode, encoding="utf-8") - - def close(self): - """Closes the file""" - self.logfile.close() - - def format(self, level: int, msg: str): - """Generate a string to log - - :param level: The level of the message - :param msg: The message to format - """ - return super().format(level, msg) + "\r\n" - - def emit(self, level: int, msg: str): - """Generate the message and write it to the UART. - - :param level: The level of the message - :param msg: The message to log - """ - self.logfile.write(self.format(level, msg)) - - # The level module-global variables get created when loaded # pylint:disable=undefined-variable diff --git a/adafruit_logging/extensions.py b/adafruit_logging/extensions.py new file mode 100644 index 0000000..e153ca7 --- /dev/null +++ b/adafruit_logging/extensions.py @@ -0,0 +1,32 @@ +from . import LoggingHandler + +class FileHandler(LoggingHandler): + """File handler for working with log files off of the microcontroller (like + an SD card) + + :param filepath: The filepath to the log file + :param mode: Whether to write ('w') or append ('a'); default is to append + """ + + def __init__(self, filepath: str, mode: str = "a"): + self.logfile = open(filepath, mode, encoding="utf-8") + + def close(self): + """Closes the file""" + self.logfile.close() + + def format(self, level: int, msg: str): + """Generate a string to log + + :param level: The level of the message + :param msg: The message to format + """ + return super().format(level, msg) + "\r\n" + + def emit(self, level: int, msg: str): + """Generate the message and write it to the UART. + + :param level: The level of the message + :param msg: The message to log + """ + self.logfile.write(self.format(level, msg)) \ No newline at end of file From 4b2af64613224e7da693484c8d6a52e34ef94ebb Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 11:53:23 -0400 Subject: [PATCH 20/22] Updated FileHandler example to match new structure --- examples/logging_filehandler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/logging_filehandler.py b/examples/logging_filehandler.py index f6cf2d6..37e5de6 100644 --- a/examples/logging_filehandler.py +++ b/examples/logging_filehandler.py @@ -7,6 +7,7 @@ import storage import adafruit_sdcard import adafruit_logging as logging +from adafruit_logging.extensions import FileHandler # Get chip select pin depending on the board, this one is for the Feather M4 Express sd_cs = board.D10 @@ -21,7 +22,7 @@ # Initialize log functionality log_filepath = "/sd/testlog.log" logger = logging.getLogger("testlog") -file_handler = logging.FileHandler(log_filepath) +file_handler = FileHandler(log_filepath) logger.addHandler(file_handler) logger.setLevel(logging.INFO) From 2c3bafdcbc1651a1bf04115ab0ffd86d2b7cfd2f Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 12:01:03 -0400 Subject: [PATCH 21/22] Updated formatting per black --- adafruit_logging/extensions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/adafruit_logging/extensions.py b/adafruit_logging/extensions.py index e153ca7..53391ee 100644 --- a/adafruit_logging/extensions.py +++ b/adafruit_logging/extensions.py @@ -1,5 +1,6 @@ from . import LoggingHandler + class FileHandler(LoggingHandler): """File handler for working with log files off of the microcontroller (like an SD card) @@ -29,4 +30,4 @@ def emit(self, level: int, msg: str): :param level: The level of the message :param msg: The message to log """ - self.logfile.write(self.format(level, msg)) \ No newline at end of file + self.logfile.write(self.format(level, msg)) From 7e9924b008f6035e68004641346db58a9ab30ab5 Mon Sep 17 00:00:00 2001 From: Alec Delaney Date: Thu, 28 Oct 2021 12:01:39 -0400 Subject: [PATCH 22/22] Add license and module docstring --- adafruit_logging/extensions.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/adafruit_logging/extensions.py b/adafruit_logging/extensions.py index 53391ee..92b35b9 100644 --- a/adafruit_logging/extensions.py +++ b/adafruit_logging/extensions.py @@ -1,3 +1,16 @@ +# SPDX-FileCopyrightText: 2021 Alec Delaney for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +`extensions` +==================================================== + +CircuitPython logging extension for logging to files + +* Author(s): Alec Delaney +""" + from . import LoggingHandler