Skip to content

Commit 6b8be5d

Browse files
committed
fix: remove root logger handler set by Lambda #115
1 parent 6b66e0b commit 6b8be5d

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
## [1.1.3] - 2020-08-18
10+
### Fixed
11+
- **Logger**: Logs emitted twice, structured and unstructured, due to Lambda configuring the root handler
12+
913
## [1.1.2] - 2020-08-16
1014
### Fixed
1115
- **Docs**: Clarify confusion on Tracer reuse and `auto_patch=False` statement

aws_lambda_powertools/logging/logger.py

+7
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ def _get_caller_filename(self):
168168
def _init_logger(self, **kwargs):
169169
"""Configures new logger"""
170170

171+
# Lambda by default configures the root logger handler
172+
# therefore, we need to remove it to prevent messages being logged twice
173+
# when customers use our Logger
174+
logger.debug("Removing Lambda root handler whether it exists")
175+
root_logger = logging.getLogger()
176+
root_logger.handlers.clear()
177+
171178
# Skip configuration if it's a child logger to prevent
172179
# multiple handlers being attached as well as different sampling mechanisms
173180
# and multiple messages from being logged as handlers can be duplicated

tests/functional/test_logger.py

+17
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,20 @@ def test_logger_record_caller_location(stdout):
359359
caller_fn_name = inspect.currentframe().f_code.co_name
360360
log = capture_logging_output(stdout)
361361
assert caller_fn_name in log["location"]
362+
363+
364+
def test_logger_do_not_log_twice(stdout):
365+
# GIVEN Lambda configures the root logger with a handler
366+
logging.basicConfig(format="%(asctime)-15s %(clientip)s %(user)-8s %(message)s", level="INFO")
367+
root_logger = logging.getLogger()
368+
root_logger.addHandler(logging.StreamHandler(stream=stdout))
369+
370+
# WHEN we create a new Logger
371+
logger = Logger(stream=stdout)
372+
logger.info("hello")
373+
374+
# THEN it should fail to unpack because root logger handler
375+
# should be removed as part of our Logger initialization
376+
assert not root_logger.handlers
377+
with pytest.raises(ValueError, match=r".*expected 2, got 1.*"):
378+
[log_one, log_two] = stdout.getvalue().strip().split("\n")

0 commit comments

Comments
 (0)