Skip to content

Commit 2ddfde9

Browse files
Small changes
1 parent 0b79f69 commit 2ddfde9

File tree

6 files changed

+40
-28
lines changed

6 files changed

+40
-28
lines changed

aws_lambda_powertools/logging/formatter.py

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22

33
import inspect
4-
import sys
54
import json
65
import logging
76
import os
@@ -11,11 +10,8 @@
1110
from datetime import datetime, timezone
1211
from functools import partial
1312
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
14-
from ..shared.functions import (
15-
resolve_truthy_env_var_choice
16-
)
1713

18-
from aws_lambda_powertools.logging.types import LogRecord
14+
from aws_lambda_powertools.logging.types import LogRecord, LogStackTrace
1915
from aws_lambda_powertools.shared import constants
2016
from aws_lambda_powertools.shared.functions import powertools_dev_is_set
2117

@@ -161,39 +157,21 @@ def __init__(
161157
def serialize(self, log: LogRecord) -> str:
162158
"""Serialize structured log dict to JSON str"""
163159
return self.json_serializer(log)
164-
165-
def serialize_traceback(self, log_record: logging.LogRecord) -> list:
166-
exception_info = {
167-
"type": log_record.exc_info[0].__name__,
168-
"value": log_record.exc_info[1],
169-
"module": log_record.exc_info[1].__class__.__module__,
170-
"frames": []
171-
}
172-
173-
exception_info["frames"] = [{
174-
"file": fs.filename,
175-
"line": fs.lineno,
176-
"function": fs.name,
177-
"statement": fs.line
178-
} for fs in traceback.extract_tb(log_record.exc_info[2])]
179-
180-
return exception_info
181160

182161
def format(self, record: logging.LogRecord) -> str: # noqa: A003
183162
"""Format logging record as structured JSON str"""
184163
formatted_log = self._extract_log_keys(log_record=record)
185164
formatted_log["message"] = self._extract_log_message(log_record=record)
186165

187-
if self.serialize_stacktrace:
188-
# Generate the traceback from the traceback library
189-
formatted_log["stack_trace"] = self.serialize_traceback(log_record=record)
190-
191166
# exception and exception_name fields can be added as extra key
192167
# in any log level, we try to extract and use them first
193168
extracted_exception, extracted_exception_name = self._extract_log_exception(log_record=record)
194169
formatted_log["record"] = record
195170
formatted_log["exception"] = formatted_log.get("exception", extracted_exception)
196171
formatted_log["exception_name"] = formatted_log.get("exception_name", extracted_exception_name)
172+
if self.serialize_stacktrace:
173+
# Generate the traceback from the traceback library
174+
formatted_log["stack_trace"] = self._serialize_stacktrace(log_record=record)
197175
formatted_log["xray_trace_id"] = self._get_latest_trace_id()
198176
formatted_log = self._strip_none_records(records=formatted_log)
199177

@@ -304,6 +282,24 @@ def _extract_log_message(self, log_record: logging.LogRecord) -> Union[Dict[str,
304282

305283
return message
306284

285+
def _serialize_stacktrace(self, log_record: logging.LogRecord) -> LogStackTrace | None:
286+
if log_record.exc_info:
287+
exception_info: LogStackTrace = {
288+
"type": log_record.exc_info[0].__name__, # type: ignore
289+
"value": log_record.exc_info[1], # type: ignore
290+
"module": log_record.exc_info[1].__class__.__module__,
291+
"frames": [],
292+
}
293+
294+
exception_info["frames"] = [
295+
{"file": fs.filename, "line": fs.lineno, "function": fs.name, "statement": fs.line}
296+
for fs in traceback.extract_tb(log_record.exc_info[2])
297+
]
298+
299+
return exception_info
300+
301+
return None
302+
307303
def _extract_log_exception(self, log_record: logging.LogRecord) -> Union[Tuple[str, str], Tuple[None, None]]:
308304
"""Format traceback information, if available
309305

aws_lambda_powertools/logging/logger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def __init__(
254254
"log_record_order": log_record_order,
255255
"utc": utc,
256256
"use_rfc3339": use_rfc3339,
257-
"serialize_stacktrace": serialize_stacktrace
257+
"serialize_stacktrace": serialize_stacktrace,
258258
}
259259

260260
self._init_logger(formatter_options=formatter_options, log_level=level, **kwargs)

aws_lambda_powertools/logging/types.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from aws_lambda_powertools.shared.types import NotRequired, TypeAlias, TypedDict
66

77
LogRecord: TypeAlias = Union[Dict[str, Any], "PowertoolsLogRecord"]
8+
LogStackTrace: TypeAlias = Union[Dict[str, Any], "PowertoolsStackTrace"]
89

910

1011
class PowertoolsLogRecord(TypedDict):
@@ -33,3 +34,11 @@ class PowertoolsLogRecord(TypedDict):
3334
# Fields from logger.exception
3435
exception_name: NotRequired[str]
3536
exception: NotRequired[str]
37+
stack_trace: NotRequired[Dict[str, Any]]
38+
39+
40+
class PowertoolsStackTrace(TypedDict):
41+
type: str
42+
value: str
43+
module: str
44+
frames: List[Dict[str, Any]]

docs/contributing/documentation/rfcs.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: Writing Request For Comment (RFC)
33
description: Contributing RFCs to Powertools for AWS Lambda (Python)
44
---
55

6+
<!-- markdownlint-disable MD043 -->
7+
68
## TBW
79

810
Something great will come.

examples/logger/src/logging_stacktrace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import requests
22

33
from aws_lambda_powertools import Logger
4-
from aws_lambda_powertools.utilities.typing import LambdaContext
54
from aws_lambda_powertools.logging.formatter import LambdaPowertoolsFormatter
5+
from aws_lambda_powertools.utilities.typing import LambdaContext
66

77
ENDPOINT = "http://httpbin.org/status/500"
88
logger = Logger(logger_formatter=LambdaPowertoolsFormatter(serialize_stacktrace=True))

tests/functional/test_logger.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ def test_stream_defaults_to_stdout(service_name, capsys):
960960
log = json.loads(capsys.readouterr().out.strip())
961961
assert log["message"] == msg
962962

963+
963964
def test_logger_logs_stack_trace_without_parameter(stdout):
964965
logger = Logger(stream=stdout)
965966

@@ -971,6 +972,7 @@ def test_logger_logs_stack_trace_without_parameter(stdout):
971972
log = capture_logging_output(stdout)
972973
assert "stack_trace" in log
973974

975+
974976
def test_logger_logs_stack_trace_with_parameter(stdout):
975977
logger = Logger(stream=stdout, logger_formatter=LambdaPowertoolsFormatter(serialize_stacktrace=True))
976978

@@ -982,6 +984,7 @@ def test_logger_logs_stack_trace_with_parameter(stdout):
982984
log = capture_logging_output(stdout)
983985
assert "stack_trace" in log
984986

987+
985988
def test_logger_logs_no_stack_trace_with_parameter_false(stdout):
986989
logger = Logger(stream=stdout, logger_formatter=LambdaPowertoolsFormatter(serialize_stacktrace=False))
987990

@@ -993,6 +996,7 @@ def test_logger_logs_no_stack_trace_with_parameter_false(stdout):
993996
log = capture_logging_output(stdout)
994997
assert "stack_trace" not in log
995998

999+
9961000
def test_logger_logs_stack_trace_with_logger_parameter(stdout):
9971001
logger = Logger(stream=stdout, serialize_stacktrace=True)
9981002

@@ -1004,6 +1008,7 @@ def test_logger_logs_stack_trace_with_logger_parameter(stdout):
10041008
log = capture_logging_output(stdout)
10051009
assert "stack_trace" in log.keys()
10061010

1011+
10071012
def test_logger_logs_no_stack_trace_with_logger_parameter_false(stdout):
10081013
logger = Logger(stream=stdout, serialize_stacktrace=False)
10091014

0 commit comments

Comments
 (0)