aws-powertools / powertools-lambda-python

A developer toolkit to implement Serverless best practices and increase developer velocity.
https://docs.powertools.aws.dev/lambda/python/latest/
MIT No Attribution
2.86k stars 393 forks source link

Bug: Child logger output does not reflect 'location' argument #5412

Open danieljandey opened 6 days ago

danieljandey commented 6 days ago

Logger allows you to either change the format or suppress the following keys at initialization: location, timestamp, xray_trace_id.

https://docs.powertools.aws.dev/lambda/python/latest/core/logger/#overriding-log-records

Code provided are just examples. In real-world new loggers are being defined in classes. The 'service_name' needs to stay the same for all the loggers (Through the environment variable) as the Lambda context needs to be included in all loggers (which will be defined at the entrypoint / above 'lambda_handler')

Documentation example code: https://docs.powertools.aws.dev/lambda/python/2.21.0/core/logger/#set_correlation_id-method

from aws_lambda_powertools import Logger
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext

logger = Logger()

@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
def lambda_handler(event: dict, context: LambdaContext) -> str:
    pass

Expected Behaviour

Expected Output:

See 'location' key:

{"level":"INFO","location":"Test1","message":"Test1","timestamp":"2024-10-21 05:38:47,710+0000","service":"payment"}
{"level":"INFO","location":"Test2","message":"Test2","timestamp":"2024-10-21 05:38:47,710+0000","service":"payment"}

Current Behaviour

Actual Output:

See 'location' key:

{"level":"INFO","location":"Test1","message":"Test1","timestamp":"2024-10-21 05:38:47,710+0000","service":"payment"}
{"level":"INFO","location":"Test1","message":"Test2","timestamp":"2024-10-21 05:38:47,710+0000","service":"payment"}

Code snippet

from aws_lambda_powertools import Logger

logger = Logger(
    service="payment",
    location="Test1"
)

logger.info("Test1")

logger = Logger(
    service="payment",
    child=True,
    location="Test2"
)

logger.info("Test2")

Possible Solution

Unsure - need to fork and package locally, but am looking at the code:

https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/logging/logger.py#L295C1-L297C19

 def _init_logger(
        self,
        formatter_options: dict | None = None,
        log_level: str | int | None = None,
        **kwargs,
    ) -> None:
        """Configures new logger"""

        # Skip configuration if it's a child logger or a pre-configured logger
        # to prevent the following:
        #   a) multiple handlers being attached
        #   b) different sampling mechanisms
        #   c) multiple messages from being logged as handlers can be duplicated
        is_logger_preconfigured = getattr(self._logger, LOGGER_ATTRIBUTE_PRECONFIGURED, False)
        if self.child or is_logger_preconfigured:
            return

Steps to Reproduce

See code snippet above

Powertools for AWS Lambda (Python) version

latest

AWS Lambda function runtime

3.12

Packaging format used

PyPi

Debugging logs

No response

boring-cyborg[bot] commented 6 days ago

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

leandrodamascena commented 5 days ago

Hey @danieljandey thanks for opening this issue! I'll take a look this week and come back here with some update.