Skip to content

feat(logger): add method to return currently configured keys #4033

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
7 changes: 7 additions & 0 deletions aws_lambda_powertools/logging/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ class BasePowertoolsFormatter(logging.Formatter, metaclass=ABCMeta):
def append_keys(self, **additional_keys) -> None:
raise NotImplementedError()

@abstractmethod
def current_keys(self) -> Dict[str, Any]:
raise NotImplementedError()

def remove_keys(self, keys: Iterable[str]) -> None:
raise NotImplementedError()

Expand Down Expand Up @@ -231,6 +235,9 @@ def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None) -
def append_keys(self, **additional_keys) -> None:
self.log_format.update(additional_keys)

def current_keys(self) -> Dict[str, Any]:
return self.log_format

def remove_keys(self, keys: Iterable[str]) -> None:
for key in keys:
self.log_format.pop(key, None)
Expand Down
3 changes: 3 additions & 0 deletions aws_lambda_powertools/logging/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,9 @@ def debug(
def append_keys(self, **additional_keys: object) -> None:
self.registered_formatter.append_keys(**additional_keys)

def current_keys(self) -> Dict[str, Any]:
return self.registered_formatter.current_keys()

def remove_keys(self, keys: Iterable[str]) -> None:
self.registered_formatter.remove_keys(keys)

Expand Down
2 changes: 1 addition & 1 deletion docs/core/logger.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ The `log` argument is the final log record containing [our standard keys](#stand
For exceptional cases where you want to completely replace our formatter logic, you can subclass `BasePowertoolsFormatter`.

???+ warning
You will need to implement `append_keys`, `clear_state`, override `format`, and optionally `remove_keys` to keep the same feature set Powertools for AWS Lambda (Python) Logger provides. This also means keeping state of logging keys added.
You will need to implement `append_keys`, `current_keys`, `clear_state`, override `format`, and optionally `remove_keys` to keep the same feature set Powertools for AWS Lambda (Python) Logger provides. This also means keeping state of logging keys added.

=== "bring_your_own_formatter_from_scratch.py"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
import logging
from typing import Iterable, List, Optional
from typing import Any, Dict, Iterable, List, Optional

from aws_lambda_powertools import Logger
from aws_lambda_powertools.logging.formatter import BasePowertoolsFormatter
Expand All @@ -16,6 +16,9 @@ def append_keys(self, **additional_keys):
# also used by `inject_lambda_context` decorator
self.log_format.update(additional_keys)

def current_keys(self) -> Dict[str, Any]:
return self.log_format

def remove_keys(self, keys: Iterable[str]):
for key in keys:
self.log_format.pop(key, None)
Expand Down
19 changes: 17 additions & 2 deletions tests/functional/test_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
import string
import sys
import warnings
from ast import Dict
from collections import namedtuple
from datetime import datetime, timezone
from typing import Any, Callable, Iterable, List, Optional, Union
from typing import Any, Callable, Dict, Iterable, List, Optional, Union

import pytest

Expand Down Expand Up @@ -606,13 +605,29 @@ def test_logger_append_remove_keys(stdout, service_name):
assert (extra_keys.items() <= keys_removed_log.items()) is False


def test_logger_append_and_show_current_keys(stdout, service_name):
# GIVEN a Logger is initialized
logger = Logger(service=service_name, stream=stdout)
extra_keys = {"request_id": "id", "context": "value"}

# WHEN keys are updated
logger.append_keys(**extra_keys)

# THEN appended keys must be present in logger
assert "request_id" in logger.current_keys()
assert "context" in logger.current_keys()


def test_logger_custom_formatter(stdout, service_name, lambda_context):
class CustomFormatter(BasePowertoolsFormatter):
custom_format = {}

def append_keys(self, **additional_keys):
self.custom_format.update(additional_keys)

def current_keys(self) -> Dict[str, Any]:
return self.custom_format

def remove_keys(self, keys: Iterable[str]):
for key in keys:
self.custom_format.pop(key, None)
Expand Down