Skip to content

Make stdlib.ProcessorFormatter more compatible with logging.Formatter #705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
LSerranoPEReN opened this issue Mar 5, 2025 · 0 comments

Comments

@LSerranoPEReN
Copy link

LSerranoPEReN commented Mar 5, 2025

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:

  1. structlog.stdlib.ProcessorFormatter inherit logging.Formatter but 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.
  2. structlog.stdlib.ProcessorFormatter use positional arguments with default values and not keyword-only arguments. As a consequence, to forward standard logging.Formatter *args, one must copy all structlog.stdlib.ProcessorFormatter default values.
  3. The last case will not work anyway, since ProcessorFormatter calls the init method of logging.Formatter with super().__init__(*args, fmt=fmt, **kwargs), and since fmt is the first positional argument of logging.Formatter, trying to forward any *args will crash as fmt will 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant