Logging
Logging is a very important part of any application. It allows you to track the
code execution and to debug the application. Python has a built-in logging
module that allows you to log messages to the console, to a file, or to a remote
server. In contrast to the print function, the logging module is more
complete, allowing you to configure the log level, the log format, and the log
destination.
Logging is based in handlers. A handler is an object that receives the log
messages and decides what to do with them. The logging module has several
built-in handlers, such as StreamHandler, FileHandler, RotatingFileHandler
or TimedRotatingFileHandler. But you can create your own handler by inherit
the Handler class. Notifiers is a 3pp
library that provides with extra handlers with the ability to send notifications
to different services.
Any handler can have different configurations, such as the log level or the log
format. The log level is used to filter the log messages. The log format is used
to format the log messages. You can use the built-in log formats or create your
own format by using the Formatter class. Also, a logger can have filters to
filter the log messages before they are sent to the handlers. This way you can
have more control over the log messages, like modifying or discarding them.
Best practices
- Set different log levels for different environments. For example, you may set
DEBUGlevel in development andERRORlevel in production. - Set a specific format for the log messages, including the timestamp or the log level. Using a standard format makes it easier to read the log messages.
- Use the
extraparameter to pass the data to the log message. - Use pipelines
|to separate the different parts of the log message. It can be useful to filter the log messages, or even to parse them. - To include variables in your log message aside from
extra, don't useformatorf-stringin the log call. Instead use the%s, likelogger.info('Variable: %s', value). - Use
logging.exceptionto log an exception message and the stack trace. - Set the different logger instance you are going to use with
logging.getLogger. This way you can configure the logger in one place and use it in different modules.
logging library
This is the built-in Python logging library. It is very flexible and allows you to configure the log level, the log format, and the log destination.
Each logger has a name, and the loggers are organized in a tree-like structure. The root logger is the top-level logger, and all other loggers are children of the root logger.
src.intermediate.logging.default_logging(level)
Method to show default logging configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
int
|
level to set in logging |
required |
Source code in src/intermediate/logging/logging.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
src.intermediate.logging.custom_logging_format(format, datefmt)
Method to show logging configuration format.
Other arguments worthy to mention are: filename: using the path as log file with FileHandler. filemode: specifies the mode to open the log file.
Source code in src/intermediate/logging/logging.py
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |
src.intermediate.logging.CustomFilter
Bases: Filter
Custom logging filter to mask sensitive information in log records.
Source code in src/intermediate/logging/filtering.py
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
src.intermediate.logging.CustomFilter.filter(record)
Override filter method to mask sensitive information.
You can mask sensitive data in record attributes. Also, you can mask record msg or arguments, but only by regex/exact match..
Source code in src/intermediate/logging/filtering.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | |
src.intermediate.logging.CustomFilter.mask_email(match_obj)
Mask email address, showing only first character before @.
Source code in src/intermediate/logging/filtering.py
46 47 48 49 50 | |
src.intermediate.logging.CustomFilter.mask_password(match_obj)
Mask password completely.
Source code in src/intermediate/logging/filtering.py
42 43 44 | |
loguru library
Loguru is a third-party library that simplifies the logging configuration to the bare minimum, such as log level and log format. But you can also can configure much more easily, such as:
- color customization.
- log rotation, retention and compression.
- custom log levels.
- lazy evaluation of log messages.
src.intermediate.logging.default_loguru()
Method to show default loguru configuration.
Source code in src/intermediate/logging/logging.py
47 48 49 50 51 52 53 | |
src.intermediate.logging.custom_loguru_format_and_level(format, level)
Method to show loguru custom configuration.
Add custom configuration to loguru, such as format and level. Sink is the first argument, representing how/where to log. It can be sys.*, or a log file path or a loggingHandler.
More information in the official loguru documentation: https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.add
Source code in src/intermediate/logging/logging.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | |