How to configure root logger + custom logger without duplicate log entries
Question:
I want to configure the root logger and my project’s custom logger separately. Here’s my current logging configuration:
logging.config.dictConfig(
{
"version": 1,
"root": {
"handlers": ["stdout"],
"level": "WARNING",
},
"loggers": {
"my_project_name": {
"handlers": ["stdout"],
"level": "DEBUG",
}
},
"handlers": {
"stdout": {
"formatter": "fancy" if sys.stdout.isatty() else "normal",
"class": "logging.StreamHandler",
"level": "DEBUG",
},
},
"formatters": {
"normal": {
"format": "%(asctime)s [%(levelname)s] (%(name)s): %(msg)s",
"datefmt": "%Y-%m-%d %H:%M:%S.%f",
},
"fancy": {
"format": "TODO",
"datefmt": "%Y-%m-%d %H:%M:%S.%f",
}
},
}
)
Basically, I want warnings and errors to be logged for the root logger (i.e. all loggers), but I want to control the log level for all loggers in my project separately.
What I end up with in the above configuration is that any log messages from my project is printed to the terminal twice, since they are handled by both the custom logger config and the root logger.
Is there a nice way to achieve this? (i.e. configuring the project’s loggers and the root logger separately)
Answers:
Set the propagate
flag to False
for all loggers one level below the root that have their own handlers (e.g. my_project_name
) and where you don’t want the root handlers to handle the event. Those events won’t go up to the root logger’s handlers if propagate
is False
. See here for the documentation on the propagate
setting.
I want to configure the root logger and my project’s custom logger separately. Here’s my current logging configuration:
logging.config.dictConfig(
{
"version": 1,
"root": {
"handlers": ["stdout"],
"level": "WARNING",
},
"loggers": {
"my_project_name": {
"handlers": ["stdout"],
"level": "DEBUG",
}
},
"handlers": {
"stdout": {
"formatter": "fancy" if sys.stdout.isatty() else "normal",
"class": "logging.StreamHandler",
"level": "DEBUG",
},
},
"formatters": {
"normal": {
"format": "%(asctime)s [%(levelname)s] (%(name)s): %(msg)s",
"datefmt": "%Y-%m-%d %H:%M:%S.%f",
},
"fancy": {
"format": "TODO",
"datefmt": "%Y-%m-%d %H:%M:%S.%f",
}
},
}
)
Basically, I want warnings and errors to be logged for the root logger (i.e. all loggers), but I want to control the log level for all loggers in my project separately.
What I end up with in the above configuration is that any log messages from my project is printed to the terminal twice, since they are handled by both the custom logger config and the root logger.
Is there a nice way to achieve this? (i.e. configuring the project’s loggers and the root logger separately)
Set the propagate
flag to False
for all loggers one level below the root that have their own handlers (e.g. my_project_name
) and where you don’t want the root handlers to handle the event. Those events won’t go up to the root logger’s handlers if propagate
is False
. See here for the documentation on the propagate
setting.