In my opinion, this is the best approach for the majority of cases.
Configuration via an INI file
Create a filename logging.ini in the project root directory as below:
[loggers] keys=root [logger_root] level=DEBUG handlers=screen,file [formatters] keys=simple,verbose [formatter_simple] format=%(asctime)s [%(levelname)s] %(name)s: %(message)s [formatter_verbose] format=[%(asctime)s] %(levelname)s [%(filename)s %(name)s %(funcName)s (%(lineno)d)]: %(message)s [handlers] keys=file,screen [handler_file] class=handlers.TimedRotatingFileHandler interval=midnight backupCount=5 formatter=verbose level=WARNING args=('debug.log',) [handler_screen] class=StreamHandler formatter=simple level=DEBUG args=(sys.stdout,)
Then configure it as below:
import logging from logging.config import fileConfig fileConfig('logging.ini') logger = logging.getLogger('dev') name = "stackoverflow" logger.info(f"Hello {name}!") logger.critical('This message should go to the log file.') logger.error('So should this.') logger.warning('And this, too.') logger.debug('Bye!')
If you run the script, the sysout will be:
2021-01-31 03:40:10,241 [INFO] dev: Hello stackoverflow! 2021-01-31 03:40:10,242 [CRITICAL] dev: This message should go to the log file. 2021-01-31 03:40:10,243 [ERROR] dev: So should this. 2021-01-31 03:40:10,243 [WARNING] dev: And this, too. 2021-01-31 03:40:10,243 [DEBUG] dev: Bye!
And debug.log file should contain:
[2021-01-31 03:40:10,242] CRITICAL [my_loger.py dev <module> (12)]: This message should go to the log file. [2021-01-31 03:40:10,243] ERROR [my_loger.py dev <module> (13)]: So should this. [2021-01-31 03:40:10,243] WARNING [my_loger.py dev <module> (14)]: And this, too.
All done.