Skip to content
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

Add options to encode stack information into an array #39

Merged
merged 12 commits into from
Feb 4, 2025
26 changes: 26 additions & 0 deletions src/pythonjsonlogger/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ def __init__(
reserved_attrs: Optional[Sequence[str]] = None,
timestamp: Union[bool, str] = False,
defaults: Optional[Dict[str, Any]] = None,
exc_info_as_array: bool = False,
stack_info_as_array: bool = False,
) -> None:
"""
Args:
Expand All @@ -177,6 +179,8 @@ def __init__(
outputting the json log record. If string is passed, timestamp will be added
to log record using string as key. If True boolean is passed, timestamp key
will be "timestamp". Defaults to False/off.
exc_info_as_array: break the exc_info into a list of lines based on line breaks.
stack_info_as_array: break the stack_info into a list of lines based on line breaks.

*Changed in 3.1*:

Expand Down Expand Up @@ -219,6 +223,8 @@ def __init__(
self._skip_fields = set(self._required_fields)
self._skip_fields.update(self.reserved_attrs)
self.defaults = defaults if defaults is not None else {}
self.exc_info_as_array = exc_info_as_array
self.stack_info_as_array = stack_info_as_array
return

def format(self, record: logging.LogRecord) -> str:
Expand Down Expand Up @@ -368,3 +374,23 @@ def process_log_record(self, log_record: LogRecord) -> LogRecord:
log_record: incoming data
"""
return log_record

def formatException(self, ei) -> Union[str, list[str]]:
"""Format and return the specified exception information.

If exc_info_as_array is set to True, This method returns an array of strings.
"""
exception_info_str = super().formatException(ei)
return exception_info_str.splitlines() if self.exc_info_as_array else exception_info_str

def formatStack(self, stack_info) -> Union[str, list[str]]:
"""Format and return the specified stack information.

If stack_info_as_array is set to True, This method returns an array of strings.
"""
stack_info_str = super().formatStack(stack_info)
return (
stack_info_str.splitlines()
if self.stack_info_as_array
else stack_info_str.formatStack(stack_info)
)
49 changes: 49 additions & 0 deletions tests/test_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,55 @@ def custom_default(obj):
return


@pytest.mark.parametrize("class_", ALL_FORMATTERS)
def test_exc_info_as_array(env: LoggingEnvironment, class_: type[BaseJsonFormatter]):
env.set_formatter(class_(exc_info_as_array=True))

try:
raise Exception("Error")
except BaseException:
env.logger.exception("Error occurs")
log_json = env.load_json()

assert type(log_json["exc_info"]) is list
return


@pytest.mark.parametrize("class_", ALL_FORMATTERS)
def test_exc_info_as_array_no_exc_info(env: LoggingEnvironment, class_: type[BaseJsonFormatter]):
env.set_formatter(class_(exc_info_as_array=True))

env.logger.info("hello")
log_json = env.load_json()

assert log_json.get("exc_info") is None
return


@pytest.mark.parametrize("class_", ALL_FORMATTERS)
def test_stack_info_as_array(env: LoggingEnvironment, class_: type[BaseJsonFormatter]):
env.set_formatter(class_(stack_info_as_array=True))

env.logger.info("hello", stack_info=True)
log_json = env.load_json()

assert type(log_json["stack_info"]) is list
return


@pytest.mark.parametrize("class_", ALL_FORMATTERS)
def test_stack_info_as_array_no_stack_info(
env: LoggingEnvironment, class_: type[BaseJsonFormatter]
):
env.set_formatter(class_(stack_info_as_array=True))

env.logger.info("hello", stack_info=False)
log_json = env.load_json()

assert log_json.get("stack_info") is None
return


## JsonFormatter Specific
## -----------------------------------------------------------------------------
def test_json_ensure_ascii_true(env: LoggingEnvironment):
Expand Down
Loading