Skip to content

Commit 91affa4

Browse files
committed
docs: bring your own formatter feat
1 parent bb180bd commit 91affa4

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

aws_lambda_powertools/logging/formatter.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class BasePowertoolsFormatter(logging.Formatter, metaclass=ABCMeta):
4141
def append_keys(self, **additional_keys):
4242
raise NotImplementedError()
4343

44-
@abstractmethod
4544
def remove_keys(self, keys: Iterable[str]):
4645
raise NotImplementedError()
4746

docs/core/logger.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ You can enrich your structured logs with key Lambda context information via `inj
7171

7272
@logger.inject_lambda_context
7373
def handler(event, context):
74-
logger.info("Collecting payment")
74+
logger.info("Collecting payment")
7575

7676
# You can log entire objects too
7777
logger.info({
@@ -742,6 +742,65 @@ By default, Logger uses StreamHandler and logs to standard output. You can overr
742742
logger.info("Collecting payment")
743743
```
744744

745+
#### Bring your own formatter
746+
747+
By default, Logger uses a custom Formatter that persists its custom structure between non-cold start invocations. There could be scenarios where the existing feature set isn't sufficient to your formatting needs.
748+
749+
For this, you can subclass `BasePowertoolsFormatter`, implement `append_keys` method, and override `format` standard logging method. This ensures the current feature set of Logger like injecting Lambda context and sampling will continue to work.
750+
751+
!!! info
752+
You might need to implement `remove_keys` method if you make use of the feature too.
753+
754+
=== "collect.py"
755+
756+
```python hl_lines="2 4 7 12 16 27"
757+
from aws_lambda_powertools import Logger
758+
from aws_lambda_powertools.logging.formatter import BasePowertoolsFormatter
759+
760+
class CustomFormatter(BasePowertoolsFormatter):
761+
custom_format = {} # will hold our structured keys
762+
763+
def append_keys(self, **additional_keys):
764+
# also used by `inject_lambda_context` decorator
765+
self.custom_format.update(additional_keys)
766+
767+
# Optional unless you make use of this Logger feature
768+
def remove_keys(self, keys: Iterable[str]):
769+
for key in keys:
770+
self.custom_format.pop(key, None)
771+
772+
def format(self, record: logging.LogRecord) -> str: # noqa: A003
773+
"""Format logging record as structured JSON str"""
774+
return json.dumps(
775+
{
776+
"event": super().format(record),
777+
"timestamp": self.formatTime(record),
778+
"my_default_key": "test",
779+
**self.custom_format,
780+
}
781+
)
782+
783+
logger = Logger(service="payment", logger_formatter=CustomFormatter())
784+
785+
@logger.inject_lambda_context
786+
def handler(event, context):
787+
logger.info("Collecting payment")
788+
```
789+
=== "Example CloudWatch Logs excerpt"
790+
791+
```json hl_lines="2-4"
792+
{
793+
"event": "Collecting payment",
794+
"timestamp": "2021-05-03 11:47:12,494",
795+
"my_default_key": "test",
796+
"cold_start": true,
797+
"lambda_function_name": "test",
798+
"lambda_function_memory_size": 128,
799+
"lambda_function_arn": "arn:aws:lambda:eu-west-1:12345678910:function:test",
800+
"lambda_request_id": "52fdfc07-2182-154f-163f-5f0f9a621d72"
801+
}
802+
```
803+
745804
## Built-in Correlation ID expressions
746805

747806
You can use any of the following built-in JMESPath expressions as part of [inject_lambda_context decorator](#setting-a-correlation-id).

0 commit comments

Comments
 (0)