-
Notifications
You must be signed in to change notification settings - Fork 455
Description
Use case
Sometimes you want to trace a @classmethod
. In my case I have an ORM-like (https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) library that provides some get
, put
, query
, etc. class methods in a base class. I want tracing for all subclasses. Something like:
class Table:
@classmethod
@tracer.capture_method # Unclear which should nest innermost.
def get(cls, id: str):
db.get(table_name=cls.table_name, id=id)
table_name: str
class Users:
table_name = "users"
user = Users.get(123)
This doesn't work at the moment (fails with an error about get
not having __module__
defined IIRC, at least if you nest @classmethod
innermost).
Solution/User Experience
Either extend capture_method
to cover @classmethod
s or add another decorator.
Ideally, as far as I'm concerned, we actually want to use the actual class (cls
) in the sub-segment name. So in the example above "## user_module.Users.get"
. This provides more information in the span name than using Table
. You could extend the same argument to the existing behavior of capture_method
for instance methods. Although changing it there would be a breaking change (although probably benign).
Alternative solutions
Currently I've written my own, limited workaround:
_P = ParamSpec('_P')
_R_co = TypeVar('_R_co', covariant=True)
_Class = TypeVar('_Class', bound=type)
# Tracer.capture_method does not work for classmethods, so we need our own
# version.
def decorate_sync_classmethod(
func: Callable[Concatenate[_Class, _P], _R_co],
) -> Callable[Concatenate[_Class, _P], _R_co]:
'''Equivalent to `@Tracer.capture_method`, but for classmethods.
Only works on sync (i.e. not async) classmethods.
'''
@functools.wraps(func)
def wrapper(cls: _Class, *args: _P.args, **kwargs: _P.kwargs) -> _R_co:
method_name = f'{cls.__module__}.{cls.__qualname__}.{func.__name__}'
with _tracer.provider.in_subsegment(name=f"## {method_name}"):
return func(cls, *args, **kwargs)
return wrapper
Acknowledgment
- This feature request meets Lambda Powertools Tenets
- Should this be considered in other Lambda Powertools languages? i.e. Java, TypeScript
Metadata
Metadata
Assignees
Labels
Type
Projects
Status