Skip to content

Preserving original callsite parameters in wrapped function or method #778

@bsless

Description

@bsless

Hello, thank you for creating structlog :)
I'm looking for guidance on how I should work with a combination of CallsiteParameterAdder, filtering_bound_logger and wrapping a function or method.
What I tried to do was log function entry and exit, and I saw there has been some past discussion on the subject (#241 ) and a solution for using stdlib logger (#537), but I'm using structlog's logger.

A minimal example would be

def my_decorator(f):
    qname = f.__qualname__
    @functools.wraps(f)
    def wrapper(*args, **kwds):
        get_logger().info('hi', q_name=qname)
        return f(*args, **kwds)
    return wrapper

class A:
    @my_decorator
    def foo(self):
        print('woof!')

a = A()
a.foo()

And

            {
                structlog.processors.CallsiteParameter.FILENAME,
                structlog.processors.CallsiteParameter.MODULE,
                structlog.processors.CallsiteParameter.QUAL_NAME,
                structlog.processors.CallsiteParameter.LINENO,
            },

All of these parameters are printed "correctly" from inside the wrapper, but are not very helpful

2025-12-11T20:37:47.298452Z [info     ] hi                             filename=logger.py lineno=371 module=logger q_name=A.foo qual_name=my_decorator.<locals>.wrapper
woof!

What I want to achieve but not sure if possible is to use the frame information of the wrapped function.
Without manipulating the stack levels, which the builtin logger does not currently support iirc, the only very silly workaround I can some up with is adding a flag to CallsiteParameterAdder telling it not to override the fields in event_dict if they're already in it, and letting the user bind them however they'd like.

What do you think

Thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions