diff --git a/aws_lambda_powertools/logging/formatter.py b/aws_lambda_powertools/logging/formatter.py
index cfda64bc8e6..0140d057f0d 100644
--- a/aws_lambda_powertools/logging/formatter.py
+++ b/aws_lambda_powertools/logging/formatter.py
@@ -126,6 +126,24 @@ def _extract_log_exception(self, log_record: logging.LogRecord) -> Optional[str]
return None
+ def _extract_log_exception_name(self, log_record: logging.LogRecord) -> Optional[str]:
+ """Extract the exception name, if available
+
+ Parameters
+ ----------
+ log_record : logging.LogRecord
+ Log record to extract exception name from
+
+ Returns
+ -------
+ log_record: Optional[str]
+ Log record with exception name
+ """
+ if log_record.exc_info:
+ return log_record.exc_info[0].__name__
+
+ return None
+
def _extract_log_keys(self, log_record: logging.LogRecord) -> Dict:
"""Extract and parse custom and reserved log keys
@@ -164,6 +182,7 @@ def _extract_log_keys(self, log_record: logging.LogRecord) -> Dict:
def format(self, record): # noqa: A003
formatted_log = self._extract_log_keys(log_record=record)
formatted_log["message"] = self._extract_log_message(log_record=record)
+ formatted_log["exception_name"] = self._extract_log_exception_name(log_record=record)
formatted_log["exception"] = self._extract_log_exception(log_record=record)
formatted_log.update({"xray_trace_id": self._get_latest_trace_id()}) # fetch latest Trace ID, if any
diff --git a/docs/core/logger.md b/docs/core/logger.md
index 0e8cca2700c..2c5c347eadf 100644
--- a/docs/core/logger.md
+++ b/docs/core/logger.md
@@ -451,7 +451,7 @@ You can also change the order of the following log record keys via the `log_reco
#### Logging exceptions
-When logging exceptions, Logger will add a new key named `exception`, and will serialize the full traceback as a string.
+When logging exceptions, Logger will add new keys named `exception_name` and `exception` with the full traceback as a string.
=== "logging_an_exception.py"
@@ -475,6 +475,7 @@ When logging exceptions, Logger will add a new key named `exception`, and will s
"timestamp": "2020-08-28 18:11:38,886",
"service": "service_undefined",
"sampling_rate": 0.0,
+ "exception_name":"ValueError",
"exception": "Traceback (most recent call last):\n File \"\", line 2, in \nValueError: something went wrong"
}
```
diff --git a/tests/functional/test_logger.py b/tests/functional/test_logger.py
index 4e1ab245141..2b4c7cf187e 100644
--- a/tests/functional/test_logger.py
+++ b/tests/functional/test_logger.py
@@ -422,3 +422,18 @@ def test_logger_log_twice_when_log_filter_isnt_present_and_root_logger_is_setup(
# since child's log records propagated to root logger should be rejected
logs = list(stdout.getvalue().strip().split("\n"))
assert len(logs) == 4
+
+
+def test_logger_exception_extract_exception_name(stdout, service_name):
+ # GIVEN Logger is initialized
+ logger = Logger(service=service_name, stream=stdout)
+
+ # WHEN calling a logger.exception with a ValueError
+ try:
+ raise ValueError("something went wrong")
+ except Exception:
+ logger.exception("Received an exception")
+
+ # THEN we expect a "exception_name" to be "ValueError"
+ log = capture_logging_output(stdout)
+ assert "ValueError" == log["exception_name"]