In every programming language at some point, you'll need to use the logger to debug your running application.
Here is a table with errors logged according to the selected level:
If you want to test the above list, create a file with the following content and execute it:
#!/usr/bin/env python
import logging
logging.basicConfig(filename='example.log', level=logging.ERROR)
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.debug('debug')
logging.critical('critical message')
To see the messages added in log file, run:
cat example.log
The availble error levels are the following:
logging.CRITICAL = 50
logging.FATAL = CRITICAL
logging.ERROR = 40
logging.WARNING = 30
logging.WARN = WARNING
logging.INFO = 20
logging.DEBUG = 10
logging.NOTSET = 0
If you want more control over the log messages, use the following script as starting point:
You will need to run pip install jsonlogformatter
before running the script
#!/usr/bin/env python
import os
import logging
import json_log_formatter
class CustomJsonFormatter(json_log_formatter.JSONFormatter):
def json_record(self, message: str, extra: dict, record: logging.LogRecord):
return {
'message': record.msg,
'level': record.levelname,
'time': record.created,
'pathname': record.pathname,
'lineno': record.lineno,
'args': record.args,
# 'record': record,
}
class ApplicationLogger:
application_name: str
environment: str
LOGFILE_FORMAT = '{0}-{1}.log'
ENV_LOG_LEVEL = {
'prod': logging.WARNING,
'dev': logging.DEBUG,
'stg': logging.DEBUG,
}
def _set_format(self):
return CustomJsonFormatter()
# return logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
def get_logger(self):
return self.logger
def __init__(self, application_name, environment='dev'):
self.application_name = application_name
self.environment = environment
self.logger = logging.getLogger(self.application_name)
self.logger.setLevel(logging.DEBUG)
formatter = self._set_format()
handler = logging.FileHandler(self.LOGFILE_FORMAT.format(self.application_name, self.environment))
handler.setLevel(self.ENV_LOG_LEVEL.get(self.environment, logging.DEBUG))
handler.setFormatter(formatter)
self.logger.addHandler(handler)
if bool(os.getenv('DEBUG')) is True:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG)
stream_handler.setFormatter(formatter)
self.logger.addHandler(stream_handler)
class MyApplication:
def __init__(self, log):
self.log = log
def run(self):
self.log.info('Start my application')
self._custom_logic()
def _custom_logic(self):
self.log.info('Apply custom logic')
if __name__ == '__main__':
logger = ApplicationLogger('my-app', 'dev').get_logger()
myapp = MyApplication(logger)
myapp.run()
If you create a file with the above code and execute it, then you'll see in the terminal two messages in json format and the same messages will be saved in the log file my-app-dev.log
.
DEBUG=1 python myfile.py
If you don't append DEBUG
env variable, then you'll see the messages only in the my-app-dev.log
file.
If you want the messages to be in plain text, you can change that in method setformat
from ApplicationLogger
class.
Furthermore, you can use a different formatter for the CLI output if you want. Feel free to change the behaviour as you want