Source code for wolk.logger_factory

"""LoggerFactory Module."""
#   Copyright 2020 WolkAbout Technology s.r.o.
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
import logging
from typing import List
from typing import Optional


[docs]class LoggerFactory: """Factory for issuing ready to use loggers in other modules.""" def __init__(self, level=logging.INFO, console=True, log_file=None): # type: ignore """ Create a factory that will give loggers through calls to get_logger(). :param level: Set the desired logging level :type level: int or None :param console: Should the log messages be outputted to the console :type console: bool or None :param log_file: Name of the log file to output to :type log_file: str or None """ self.level = level self.device_key = None self.console = console self.log_file = log_file self.loggers: List[logging.Logger] = []
[docs] def set_device_key(self, device_key: str) -> None: """ Set device key. :param device_key: Device key :type device_key: str """ self.device_key = device_key
[docs] def get_logger( self, name: str, level: Optional[int] = None ) -> logging.Logger: """ Return a ready to use logger instance. :param name: Name of the logger :type name: str :param level: Override the log level :type level: int or None :returns: Logger instance :rtype: logger """ logger = logging.getLogger(name) if level is not None: logger.setLevel(level) else: logger.setLevel(self.level) if self.device_key is not None: formatter = logging.Formatter( "%(asctime)s - '" + str(self.device_key) + "' - %(levelname)s [%(filename)s:%(lineno)s" + " - %(funcName)s()] - %(message)s" ) else: formatter = logging.Formatter( "%(asctime)s - %(levelname)s [%(filename)s:%(lineno)s" + " - %(funcName)s()] - %(message)s" ) if self.console: console_handler = logging.StreamHandler() if level is not None: console_handler.setLevel(level) else: console_handler.setLevel(self.level) console_handler.setFormatter(formatter) logger.addHandler(console_handler) if self.log_file is not None: file_handler = logging.FileHandler(self.log_file) if level is not None: file_handler.setLevel(level) else: file_handler.setLevel(self.level) file_handler.setFormatter(formatter) logger.addHandler(file_handler) self.loggers.append(logger) return logger
# Logging levels available: NOTSET, INFO, DEBUG logger_factory = LoggerFactory(level=logging.INFO) LEVELS = { "debug": logging.DEBUG, "info": logging.INFO, "warning": logging.WARNING, "error": logging.ERROR, "critical": logging.CRITICAL, "notset": logging.NOTSET, }
[docs]def logging_config(level: str, log_file: Optional[str] = None) -> None: """ Set desired log level and designate a log file. :param level: Available levels : debug, info, notset :type level: str :param log_file: path to log file :type log_file: str or None """ if log_file is not None: logger_factory.log_file = log_file if level not in LEVELS: print(f"Invalid level '{level}'") return if LEVELS[level] == logger_factory.level: return logger_factory.level = LEVELS[level] for logger in logger_factory.loggers: logger.setLevel(logger_factory.level) for handler in logger.handlers: handler.setLevel(logger_factory.level)