#!/usr/bin/env python3 """LOGGER """ # Standard library imports import logging # https://docs.python.org/3/library/logging.handlers.html#module-logging.handlers from logging.handlers import SMTPHandler, TimedRotatingFileHandler import sys # Third party imports # None # Local application imports # None logger = None def get_console_handler(): # Console should print ALL messages (starting from lower level DEBUG) c_handler = logging.StreamHandler(sys.stdout) c_handler.setLevel(logging.DEBUG) c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s') c_handler.setFormatter(c_format) return c_handler def get_file_handler(): # Log File should contain ONLY messages starting from level WARNING (ERROR ?) #f_handler = logging.FileHandler('file.log') f_handler = TimedRotatingFileHandler("file.log", when='midnight') f_handler.setLevel(logging.WARNING) # Create formatter and add it to handler #f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') f_format = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s : %(lineno)s - %(message)s') f_handler.setFormatter(f_format) return f_handler def get_db_handler(): # DB should contain ONLY messages starting from level ERROR # TODO: pass def get_email_handler(): # Email should be sent ONLY for messages starting from level CRITICAL # http://sametmax.com/envoi-dun-email-par-logging-en-cas-de-plantage-dun-script-python-ou-comment-faire-bouffer-uxe9-a-smtphandler/ # TODO: a ameliorer avec article ci-dessus pour UNICODE m_handler = SMTPHandler( # Host et port ('SMTP.GMAIL.COM', 587), # From "MOI@GMAIL.COM", # To (liste) ["QUELQU.UN@QUELQUE.PART"], # Sujet du message "Erreur critique dans module MMM", # pour l'authentification credentials = ("MONEMAIL@GMAIL.COM", "MONSUPERPASSWORD"), secure = () ) m_handler.setLevel(logging.WARNING) m_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') m_handler.setFormatter(m_format) return m_handler def get_logger(logger_name): global logger # Basic configuration ''' #logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG, filename='client.log', filemode='a', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logging.debug("Client instanciated") ''' # Advanced configuration # https://docs.python.org/3/library/logging.html#logging.getLogger #logger = logging.getLogger(__name__) logger = logging.getLogger(logger_name) # If not set, default level is NOTSET (all messages are logged) # The defined levels, in order of increasing severity : DEBUG, INFO, WARNING, ERROR, CRITICAL logger.setLevel(logging.DEBUG) # better to have too much log than not enough # Create and add handlers to the logger logger.addHandler(get_console_handler()) logger.addHandler(get_file_handler()) # TODO: ##logger.addHandler(db_handler) ##logger.addHandler(m_handler) # with this pattern, it's rarely necessary to propagate the error up to parent ##logger.propagate = False return logger # Shortcuts for logger: #def log_d(msg:str): logger.debug(msg) def log_d(msg:str, *args, **kwargs): logger.debug(msg, *args, **kwargs) def log_i(msg:str, *args, **kwargs): logger.info(msg, *args, **kwargs) def log_w(msg:str, *args, **kwargs): logger.warning(msg, *args, **kwargs) def log_e(msg:str, *args, **kwargs): logger.error(msg, *args, **kwargs) def log_c(msg:str, *args, **kwargs): logger.critical(msg, *args, **kwargs) if __name__ == "__main__": my_logger = get_logger("my_module_name") my_logger.debug("a debug message")