powertools-lambda-python
powertools-lambda-python copied to clipboard
Allow logging additional keys as a context manager
Use case
The built in logger supports adding additional context using the append_keys
and removing that additional context using the remove_keys
methods, as documented here:
https://docs.powertools.aws.dev/lambda/python/latest/core/logger/#appending-additional-keys
Allow the built in logger to support logging keys as a context manager using the with
keyword.
Solution/User Experience
Just adding an additional method that implements the contextlib
module's contextmanager
decorator as documented here:
https://docs.python.org/3/library/contextlib.html#contextlib.contextmanager
Example:
with logger.with_keys(some_key="some_value"):
# do something
logger.info("Something was done")
# the log output would include the 'some_key' context
# Do some other thing
logger.info("Some other thing was done")
# the log output would not include the 'some_key' context
This would reduce the need to remember to call remove_keys
when specific context no longer wants to be logged.
Alternative solutions
No response
Acknowledgment
- [X] This feature request meets Powertools for AWS Lambda (Python) Tenets
- [X] Should this be considered in other Powertools for AWS Lambda languages? i.e. Java, TypeScript, and .NET
Thanks for opening your first issue here! We'll come back to you as soon as we can. In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link
Thanks @CaptainDriftwood for submitting this, we will discuss it during our next gathering.
Simon and I discussed this a minute ago... got a question @CaptainDriftwood - is your intent to have a given set of keys temporarily added for N log statements? OR add N keys for a given log statement?
This feature would make sense for the former*, but the latter is already possible by passing arbitrary keyword arguments to any log statement
*caveat being that this is not thread-safe (append_keys
), as we don't use contextvars
yet.
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.typing import LambdaContext
logger = Logger()
def lambda_handler(event: dict, context: LambdaContext) -> str:
# these keys will only be available in this log statement, subsequent `logger.info` won't have them
logger.info("Collecting payment", request_id="1123", some_key="some_value")
return "hello world"
@heitorlessa It would be temporarily added for N log statements. I'm not sure how ya'll would get around the thread safety aspect. That is a good point.
gotcha! In this case, until we refactor Logger to use contextvars
to make it thread-safe, a workaround is to implement a _bind
feature which would provide an independent Logger (a deep clone): https://gist.github.com/heitorlessa/95a54e7252f0cb4cf900072fc6f30606
Updating to something like this from your earlier example:
with logger.with_keys(some_key="some_value") as _logger: # new logger with some_key="some_value" appended
# do something
_logger.info("Something was done")
# the log output would include the 'some_key' context
# Do some other thing
logger.info("Some other thing was done")
# the log output would not include the 'some_key' context
Would this work for you? or would you prefer to wait for a refactor to use contextvars
so the original snippet would stay true (maybe second half of the year)?
Edit: add question.
@heitorlessa Can this be done without the contextvars
? I'd also like to give the thread-local feature a try but I think I would require some help from your side.
@heitorlessa Apologies for the delayed response. I would prefer to wait for a refactor to use contextvars
so the original snippet I provided could be used.
I'm also interested in this feature. For example I know it from loguru in Python or zerolog in Go.
context_logger = logger.bind(ip="192.168.0.1", user="someone")
context_logger.info("Contextualize your logger easily")