@@ -1,16 +1,45 @@ -DICT_CONFIG = dict( - version=1, - disable_existing_loggers=False, - formatters=dict(standard=dict(format='%(asctime)s [%(levelname)s] %(name)s: %(message)s')), - handlers=dict( - default={ - 'level': 'INFO', - 'formatter': 'standard', +DICT_CONFIG = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'json': { + '()': 'backend.logging_formatters.JsonFormatter', + 'datefmt': '%Y-%m-%dT%H:%M:%S%z', + }, + }, + 'handlers': { + 'default': { 'class': 'logging.StreamHandler', + 'formatter': 'json', + 'level': 'INFO', 'stream': 'ext://sys.stdout', }, - ), - loggers={ - '': dict(handlers=['default'], level='INFO'), }, -) + 'loggers': { + 'django': { + 'handlers': ['default'], + 'level': 'INFO', + 'propagate': False, + }, + # 'uvicorn': { + # 'handlers': ['default'], + # 'level': 'INFO', + # 'propagate': False, + # }, + 'gunicorn': { + 'handlers': ['default'], + 'level': 'INFO', + 'propagate': False, + }, + '': { + 'handlers': ['default'], + 'level': 'INFO', + 'propagate': False, + }, + '__main__': { + 'handlers': ['default'], + 'level': 'INFO', + 'propagate': False, + }, + }, +} @@ -0,0 +1,21 @@ +import json +import logging +from logging import Formatter + + +class JsonFormatter(Formatter): + def format(self, record: logging.LogRecord) -> str: + log_record = { + 'timestamp': self.formatTime(record, self.datefmt), + 'message': record.getMessage(), + 'level': record.levelname, + } + if record.exc_info: + log_record.update( + { + 'exception': self.formatException(record.exc_info), + 'func_name': record.funcName, + 'lineno': record.lineno, + } + ) + return json.dumps(log_record, ensure_ascii=False)