42 lines
1.3 KiB
Python
42 lines
1.3 KiB
Python
import datetime as dt
|
|
import json
|
|
import logging
|
|
from typing import override
|
|
|
|
class custom_json_logger(logging.Formatter):
|
|
def __init__(
|
|
self,
|
|
*,
|
|
format_keys: dict[str,str] | None = None,
|
|
):
|
|
super().__init__()
|
|
self.format_keys = format_keys if format_keys is not None else {}
|
|
|
|
@override
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
record_dict = self._prepare_log_dict(record)
|
|
return json.dumps(record_dict, default=str)
|
|
|
|
def _prepare_log_dict(self, record: logging.LogRecord) -> dict:
|
|
always_fields = {
|
|
"message" : record.getMessage(),
|
|
"timestamp" : dt.datetime.fromtimestamp(
|
|
record.created, tz=dt.timezone.utc
|
|
).isoformat(),
|
|
}
|
|
if record.exc_info is not None:
|
|
always_fields["exc_info"] = self.formatException(record.exc_info)
|
|
|
|
if record.stack_info is not None:
|
|
always_fields["stack_info"] = self.formatStack(record.stack_info)
|
|
|
|
message = {
|
|
key: msg_val
|
|
if (msg_val := always_fields.pop(val, None)) is not None
|
|
else getattr(record, val)
|
|
for key, val in self.format_keys.items()
|
|
}
|
|
message.update(always_fields)
|
|
return message
|
|
|