pcschreiber1's picture
Set up basic logging with structlog.
e029800
import logging
import structlog
from logging.handlers import RotatingFileHandler
# Configure standard logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", # for log aggregation, limit to message
)
# Set up file handler with log rotation
file_handler = RotatingFileHandler('logs/root.log', maxBytes=10*1024*1024, backupCount=3)
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter('%(message)s'))
logging.getLogger().addHandler(file_handler)
# rendering with structlog
# from: https://www.structlog.org/en/stable/standard-library.html#rendering-within-structlog
structlog.configure(
processors=[
# If log level is too low, abort pipeline and throw away log entry.
structlog.stdlib.filter_by_level,
# Add the name of the logger to event dict.
structlog.stdlib.add_logger_name,
# Add log level to event dict.
structlog.stdlib.add_log_level,
# Perform %-style formatting.
structlog.stdlib.PositionalArgumentsFormatter(),
# Add a timestamp in ISO 8601 format.
structlog.processors.TimeStamper(fmt="iso"),
# If the "stack_info" key in the event dict is true, remove it and
# render the current stack trace in the "stack" key.
structlog.processors.StackInfoRenderer(),
# If the "exc_info" key in the event dict is either true or a
# sys.exc_info() tuple, remove "exc_info" and render the exception
# with traceback into the "exception" key.
structlog.processors.format_exc_info,
# If some value is in bytes, decode it to a Unicode str.
structlog.processors.UnicodeDecoder(),
# Add callsite parameters.
structlog.processors.CallsiteParameterAdder(
{
structlog.processors.CallsiteParameter.FILENAME,
structlog.processors.CallsiteParameter.FUNC_NAME,
structlog.processors.CallsiteParameter.LINENO,
}
),
# Render the final event dict as JSON.
structlog.processors.JSONRenderer()
],
# `wrapper_class` is the bound logger that you get back from
# get_logger(). This one imitates the API of `logging.Logger`.
wrapper_class=structlog.stdlib.BoundLogger,
# `logger_factory` is used to create wrapped loggers that are used for
# OUTPUT. This one returns a `logging.Logger`. The final value (a JSON
# string) from the final processor (`JSONRenderer`) will be passed to
# the method of the same name as that you've called on the bound logger.
logger_factory=structlog.stdlib.LoggerFactory(),
# Effectively freeze configuration after creating the first bound
# logger.
cache_logger_on_first_use=True,
)