From 1d68c883a7082f51897d1be00ac39712fb77a527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Zacchino?= Date: Wed, 24 Sep 2025 15:24:46 +0000 Subject: [PATCH] logging_json: enhance logging output by splitting levels into stdout and stderr --- logging_json/README.rst | 4 ++++ logging_json/json_log.py | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/logging_json/README.rst b/logging_json/README.rst index 4d60884d..d6929e7e 100644 --- a/logging_json/README.rst +++ b/logging_json/README.rst @@ -12,3 +12,7 @@ The json logging is activated with the environment variable In order to have the logs from the start of the server, you should add ``logging_json`` in the ``--load`` flag or in the ``server_wide_modules`` option in the configuration file. + +You can split the logs in stderr and stdout with the environment variable +``ODOO_LOGGING_JSON_STDERR`` set to ``1``. In this case, the logs with a level +of WARNING or above will be sent to stderr, the others to stdout. diff --git a/logging_json/json_log.py b/logging_json/json_log.py index 9c00922e..2a2fedfd 100644 --- a/logging_json/json_log.py +++ b/logging_json/json_log.py @@ -3,6 +3,7 @@ import logging import os +import sys import threading import uuid @@ -38,7 +39,38 @@ def add_fields(self, log_record, record, message_dict): "%(asctime)s %(pid)s %(levelname)s %(dbname)s %(name)s: %(message)s" ) formatter = OdooJsonFormatter(formatted_message) - logging.getLogger().handlers[0].formatter = formatter + + if is_true(os.environ.get("ODOO_LOGGING_JSON_STDERR")): + + class MaxLevelFilter(logging.Filter): + def __init__(self, max_level): + self.max_level = max_level + + def filter(self, record): + return record.levelno < self.max_level + + # keep the original level + root_logger = logging.getLogger() + original_level = root_logger.level + + # Split lower levels into stdout + stdout_handler = logging.StreamHandler(sys.stdout) + stdout_handler.setLevel(logging.NOTSET) + stdout_handler.addFilter(MaxLevelFilter(logging.WARNING)) + stdout_handler.setFormatter(formatter) + + # Split WARNING and upper into stderr + stderr_handler = logging.StreamHandler(sys.stderr) + stderr_handler.setLevel(logging.WARNING) + stderr_handler.setFormatter(formatter) + + # Replace handlers + root_logger.handlers = [] + root_logger.setLevel(original_level) + root_logger.addHandler(stdout_handler) + root_logger.addHandler(stderr_handler) + else: + logging.getLogger().handlers[0].formatter = formatter # monkey patch Request constructor to store request_uuid