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")