Repository: aws-powertools/powertools-lambda-python

Issue:
Feature request: Log warning message if Advanced Logging Controls log level is less verbose than Logger level
### Use case

Original Issue: [TS/3821](https://github.com/aws-powertools/powertools-lambda-typescript/issues/3821)

When Log Buffering is enabled, we should add a warning message if the logger's level is more verbose than the Advanced Logging Controls setting. This will alert users when their log messages are not being printed due to mismatched log levels.

### Solution/User Experience

Check if log buffering is enabled
Compare logger level with Advanced Logging Controls setting
If logger level is more verbose, warn the user

### Alternative solutions

```markdown
N/A
```

### Acknowledgment

- [x] This feature request meets [Powertools for AWS Lambda (Python) Tenets](https://docs.powertools.aws.dev/lambda/python/latest/#tenets)
- [x] Should this be considered in other Powertools for AWS Lambda languages? i.e. [Java](https://github.com/aws-powertools/powertools-lambda-java/), [TypeScript](https://github.com/aws-powertools/powertools-lambda-typescript/), and [.NET](https://github.com/aws-powertools/powertools-lambda-dotnet/)

Hints from issue comments:
@github-actions: ### ⚠️COMMENT VISIBILITY WARNING⚠️
This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a [team member](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/MAINTAINERS.md#current-maintainers) or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.@github-actions: This is now released under [3.11.0](https://github.com/aws-powertools/powertools-lambda-python/releases/tag/v3.11.0) version!

Solution patch:
diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py
index 3dae687e7..e8340dd2b 100644
--- a/aws_lambda_powertools/logging/logger.py
+++ b/aws_lambda_powertools/logging/logger.py
@@ -242,10 +242,6 @@ class Logger:
         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 @@ class Logger:
         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 @@ class Logger:
                     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 @@ class Logger:
         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 @@ class Logger:
         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 @@ class Logger:
         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:


Test patch:
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 3c149d6df..7b02a3555 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 test_logger_buffer_is_cleared_between_lambda_invocations_without_decoration(
 
     # 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()
+
+