Setup a python logging configuration with dictConfig
Logging configuration can be defined on different ways like a dict, ini file, yaml or json somethimes is more flexible to do it on code with python, all depends on the use case.
This small example show how to setup the logging configuration using dictConfig
method and how to add an user defined object to the logging filter.
import os
import logging
import socket
from flask import Flask
from logging.config import dictConfig
class ContextFilter(logging.Filter):
hostname = socket.gethostname()
def filter(self, record):
record.hostname = ContextFilter.hostname
return True
logging_configuration = dict(
version=1,
disable_existing_loggers=False,
formatters={
"default": {"format": "[%(hostname)s %(asctime)s] %(levelname)s in %(module)s: %(message)s"},
},
filters={"hostname_filter": {"()": ContextFilter}},
handlers={
"console": {
"class": "logging.StreamHandler",
"formatter": "default",
"filters": ["hostname_filter"],
}
},
root={"handlers": ["console"], "level": os.getenv("LOG_LEVEL", "INFO")},
)
dictConfig(logging_configuration)
app = Flask(__name__)
logger = logging.getLogger(__name__)
@app.route("/")
def home():
logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical error message")
return "Hello World"
if __name__ == "__main__":
app.run()
The filter hostname_filter
use the special key "()"
which means that user-defined instantiation is wanted. ContextFilter
subclass logging.Filter
and overrides the filter
method so when key hostname
is found it will get his value from the ContextFilter
class using socket.gethostname()
and the application output will show: