-
-
Notifications
You must be signed in to change notification settings - Fork 256
Open
Labels
Description
Hi,
I wanted to use StructlogFormatter within logging, with logging configuration loaded at runtime with a json file config.
I ended up doing a small wrapper to make structlog.stdlib.ProcessorFormatter compatible with standard logging.Formatter:
class StructlogFormatterWrapper(structlog.stdlib.ProcessorFormatter):
def __init__(self, fmt=None, datefmt=None, style='%', validate=True, **kwargs):
super().__init__(
None,
[
structlog.processors.add_log_level,
structlog.stdlib.add_logger_name,
structlog.processors.TimeStamper(fmt="%Y-%m-%dT%H:%M:%S", utc=False),
structlog.processors.StackInfoRenderer(),
structlog.processors.CallsiteParameterAdder(),
structlog.dev.ConsoleRenderer()
],
[structlog.stdlib.ExtraAdder()],
False,
False,
None,
False,
True,
fmt=fmt, # will be popped by structlog ProcessorFormatter,
datefmt=datefmt,
style=style,
validate=validate,
**kwargs,
)This wrapper is not very pretty due to issues that, I think, are related to the current implementation and definition of ProcessorFormatter:
structlog.stdlib.ProcessorFormatterinheritlogging.Formatterbut does not respect the positional arguments of its parent class for the init method. This makes a wrapper necessary since logging configuration from file tries to initialize formatter with positional arguments.structlog.stdlib.ProcessorFormatteruse positional arguments with default values and not keyword-only arguments. As a consequence, to forward standardlogging.Formatter*args, one must copy allstructlog.stdlib.ProcessorFormatterdefault values.- The last case will not work anyway, since
ProcessorFormattercalls the init method oflogging.Formatterwithsuper().__init__(*args, fmt=fmt, **kwargs), and sincefmtis the first positional argument oflogging.Formatter, trying to forward any*argswill crash asfmtwill be provided twice (once as a positional arg and once as a keyword).
I think either StructlogFormatter should be changed, since it does not respect the signature of the parent class or an alternative class should be provided to make this kind of wrapper less cumbersome and more resilient to structlog internal code changes.