diff --git a/CHANGELOG.md b/CHANGELOG.md index 655762a5611..61385f19246 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.2] - 2020-08-16 +### Fixed +- **Docs**: Clarify confusion on Tracer reuse and `auto_patch=False` statement +- **Logger**: Autocomplete for log statements in PyCharm + ## [1.1.1] - 2020-08-14 ### Fixed - **Logger**: Regression on `Logger` level not accepting `int` i.e. `Logger(level=logging.INFO)` diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py index b248055aacf..54c21e88528 100644 --- a/aws_lambda_powertools/logging/logger.py +++ b/aws_lambda_powertools/logging/logger.py @@ -34,7 +34,11 @@ def _is_cold_start() -> bool: return cold_start -class Logger: +# PyCharm does not support autocomplete via getattr +# so we need to return to subclassing removed in #97 +# All methods/properties continue to be proxied to inner logger +# https://github.com/awslabs/aws-lambda-powertools-python/issues/107 +class Logger(logging.Logger): # lgtm [py/missing-call-to-init] """Creates and setups a logger to format statements in JSON. Includes service name and any additional key=value into logs @@ -187,7 +191,8 @@ def _configure_sampling(self): self.log_level = logging.DEBUG except ValueError: raise InvalidLoggerSamplingRateError( - f"Expected a float value ranging 0 to 1, but received {self.sampling_rate} instead. Please review POWERTOOLS_LOGGER_SAMPLE_RATE environment variable." # noqa E501 + f"Expected a float value ranging 0 to 1, but received {self.sampling_rate} instead." + f"Please review POWERTOOLS_LOGGER_SAMPLE_RATE environment variable." ) def inject_lambda_context(self, lambda_handler: Callable[[Dict, Any], Any] = None, log_event: bool = False): diff --git a/docs/content/core/tracer.mdx b/docs/content/core/tracer.mdx index ba489b0c965..17b1b540f0b 100644 --- a/docs/content/core/tracer.mdx +++ b/docs/content/core/tracer.mdx @@ -199,6 +199,11 @@ async def collect_payment(charge_id): Tracer keeps a copy of its configuration after the first initialization. This is useful for scenarios where you want to use Tracer in more than one location across your code base. +<Note type="warning"> + When reusing Tracer in Lambda Layers, or in multiple modules, <strong>do not set <code>auto_patch=False</code></strong>, because import order matters. + <br/><br/>This can result in the first Tracer config being inherited by new instances, and their modules not being patched. +</Note><br/> + ```python:title=lambda_handler.py # handler.py from aws_lambda_powertools import Tracer @@ -214,8 +219,8 @@ def handler(event, context): ```python:title=another_file.py from aws_lambda_powertools import Tracer # highlight-start -# new instance using existing configuration with auto patching overriden -tracer = Tracer(auto_patch=False) +# new instance using existing configuration +tracer = Tracer(service="payment") # highlight-end ``` diff --git a/pyproject.toml b/pyproject.toml index ea087088993..9b4f5ba34e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "1.1.1" +version = "1.1.2" description = "Python utilities for AWS Lambda functions including but not limited to tracing, logging and custom metric" authors = ["Amazon Web Services"] classifiers=[ diff --git a/tests/functional/test_logger.py b/tests/functional/test_logger.py index 083220ccf8c..7b0c870ee07 100644 --- a/tests/functional/test_logger.py +++ b/tests/functional/test_logger.py @@ -1,3 +1,4 @@ +import inspect import io import json import logging @@ -295,7 +296,7 @@ def test_logger_children_propagate_changes(stdout): assert child.parent.name == "order" -def test_logger_child_not_set_returns_same_logger(stdout): +def test_logger_child_not_set_returns_same_logger(): # GIVEN two Loggers are initialized with the same service name # WHEN child param isn't set logger_one = Logger(service="something") @@ -308,7 +309,7 @@ def test_logger_child_not_set_returns_same_logger(stdout): assert logger_one.name is logger_two.name -def test_logger_level_case_insensitive(stdout): +def test_logger_level_case_insensitive(): # GIVEN a Loggers is initialized # WHEN log level is set as "info" instead of "INFO" logger = Logger(level="info") @@ -344,3 +345,17 @@ def test_logger_level_env_var_as_int(monkeypatch): monkeypatch.setenv("LOG_LEVEL", 50) with pytest.raises(ValueError, match="Unknown level: '50'"): Logger() + + +def test_logger_record_caller_location(stdout): + # GIVEN Logger is initialized + logger = Logger(stream=stdout) + + # WHEN log statement is run + logger.info("log") + + # THEN 'location' field should have + # the correct caller resolution + caller_fn_name = inspect.currentframe().f_code.co_name + log = capture_logging_output(stdout) + assert caller_fn_name in log["location"]