diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py index 3dae687e7e6..e8340dd2b13 100644 --- a/aws_lambda_powertools/logging/logger.py +++ b/aws_lambda_powertools/logging/logger.py @@ -242,10 +242,6 @@ def __init__( buffer_config: LoggerBufferConfig | None = None, **kwargs, ) -> None: - - # Used in case of sampling - self.initial_log_level = self._determine_log_level(level) - self.service = resolve_env_var_choice( choice=service, env=os.getenv(constants.SERVICE_NAME_ENV, "service_undefined"), @@ -285,6 +281,9 @@ def __init__( if self._buffer_config: self._buffer_cache = LoggerBufferCache(max_size_bytes=self._buffer_config.max_bytes) + # Used in case of sampling + self.initial_log_level = self._determine_log_level(level) + self._init_logger( formatter_options=formatter_options, log_level=level, @@ -1047,6 +1046,20 @@ def _determine_log_level(self, level: str | int | None) -> str | int: stacklevel=2, ) + # Check if buffer level is less verbose than ALC + if ( + hasattr(self, "_buffer_config") + and self._buffer_config + and logging.getLevelName(lambda_log_level) + > logging.getLevelName(self._buffer_config.buffer_at_verbosity) + ): + warnings.warn( + "Advanced Logging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. " + "Buffered logs will be filtered by ALC", + PowertoolsUserWarning, + stacklevel=2, + ) + # AWS Lambda Advanced Logging Controls takes precedence over Powertools log level and we use this if lambda_log_level: return lambda_log_level @@ -1133,6 +1146,7 @@ def _add_log_record_to_buffer( Handles special first invocation buffering and migration of log records between different tracer contexts. """ + # Determine tracer ID, defaulting to first invoke marker tracer_id = get_tracer_id() @@ -1180,6 +1194,7 @@ def flush_buffer(self) -> None: Any exceptions from underlying logging or buffer mechanisms will be propagated to caller """ + tracer_id = get_tracer_id() # Flushing log without a tracer id? Return @@ -1190,6 +1205,21 @@ def flush_buffer(self) -> None: buffer = self._buffer_cache.get(tracer_id) if not buffer: return + + if not self._buffer_config: + return + + # Check ALC level against buffer level + lambda_log_level = self._get_aws_lambda_log_level() + if lambda_log_level: + # Check if buffer level is less verbose than ALC + if (logging.getLevelName(lambda_log_level) > logging.getLevelName(self._buffer_config.buffer_at_verbosity)): + warnings.warn( + "Advanced Logging Controls (ALC) Log Level is less verbose than Log Buffering Log Level. " + "Some logs might be missing", + PowertoolsUserWarning, + stacklevel=2, + ) # Process log records for log_line in buffer: diff --git a/tests/functional/logger/required_dependencies/test_powertools_logger_buffer.py b/tests/functional/logger/required_dependencies/test_powertools_logger_buffer.py index 3c149d6dfed..7b02a35551d 100644 --- a/tests/functional/logger/required_dependencies/test_powertools_logger_buffer.py +++ b/tests/functional/logger/required_dependencies/test_powertools_logger_buffer.py @@ -525,3 +525,25 @@ def handler(event, context): # THEN Verify buffer for the original trace ID is cleared assert not logger._buffer_cache.get("1-67c39786-5908a82a246fb67f3089263f") + + +def test_warning_when_alc_less_verbose_than_buffer(stdout, monkeypatch): + # GIVEN Lambda ALC set to INFO + monkeypatch.setenv("AWS_LAMBDA_LOG_LEVEL", "INFO") + # Set initial trace ID for first Lambda invocation + monkeypatch.setenv(constants.XRAY_TRACE_ID_ENV, "1-67c39786-5908a82a246fb67f3089263f") + + # WHEN creating a logger with DEBUG buffer level + # THEN a warning should be emitted + with pytest.warns(PowertoolsUserWarning, match="Advanced Logging Controls*"): + logger = Logger(service="test", level="DEBUG", buffer_config=LoggerBufferConfig(buffer_at_verbosity="DEBUG")) + + # AND logging a debug message + logger.debug("This is a debug") + + # AND flushing buffer + # THEN another warning should be emitted about ALC and buffer level mismatch + with pytest.warns(PowertoolsUserWarning, match="Advanced Logging Controls*"): + logger.flush_buffer() + +