From 41ce0925628b7061edc6d26da5d201f94d42fec7 Mon Sep 17 00:00:00 2001 From: Patrick Tombez Date: Thu, 3 Sep 2020 10:48:59 +0200 Subject: [PATCH] monitoring_log_requests: Improve data output * Add environment var to enable/disable requests log * Add ability to send data to an UDP listener instead of stdout --- monitoring_log_requests/README.rst | 14 +++++++++++++- monitoring_log_requests/__init__.py | 1 + monitoring_log_requests/models/__init__.py | 5 ++++- monitoring_log_requests/models/ir_http.py | 19 ++++++++++++++++--- monitoring_log_requests/utils.py | 10 ++++++++++ 5 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 monitoring_log_requests/utils.py diff --git a/monitoring_log_requests/README.rst b/monitoring_log_requests/README.rst index 9b4af8d..addeb5b 100644 --- a/monitoring_log_requests/README.rst +++ b/monitoring_log_requests/README.rst @@ -6,7 +6,14 @@ Monitoring: Requests Logging This addon is used to output in the logs informations about the user's requests. Data such as *what* is the request, *who* requested it and *how -much* time did it took to complete could then be extracted from the logs and +much* time did it took to complete. + +The requests logging is activated with the environment variable `ODOO_REQUESTS_LOGGING` set to `1`. + +Data output +########### + +The data could then be extracted from the logs and loaded in an analysis tool such as ElasticSearch/Kibana. Each log line is a JSON with the monitored fields, so it is easier to parse. @@ -15,3 +22,8 @@ The logs are prefixed with ``monitoring.http.requests`` so be sure to enable this path in the log handler:: - LOG_HANDLER=":WARNING,monitoring.http.requests:INFO" + +It is also possible to send the data directly to an UDP listener without +outputting anything to the logs to avoid flooding on busy instances. +To do so, use the environment variable `ODOO_REQUESTS_LOGGING_UDP` +set to a value like `
:` (`address` can be an IP or a domain). \ No newline at end of file diff --git a/monitoring_log_requests/__init__.py b/monitoring_log_requests/__init__.py index a9e3372..911b582 100644 --- a/monitoring_log_requests/__init__.py +++ b/monitoring_log_requests/__init__.py @@ -1,2 +1,3 @@ +from . import utils from . import models diff --git a/monitoring_log_requests/models/__init__.py b/monitoring_log_requests/models/__init__.py index 0d643ba..77afcad 100644 --- a/monitoring_log_requests/models/__init__.py +++ b/monitoring_log_requests/models/__init__.py @@ -1,2 +1,5 @@ -from . import ir_http +from ..utils import is_enabled + +if is_enabled(): + from . import ir_http diff --git a/monitoring_log_requests/models/ir_http.py b/monitoring_log_requests/models/ir_http.py index abaf46b..c5bf9b9 100644 --- a/monitoring_log_requests/models/ir_http.py +++ b/monitoring_log_requests/models/ir_http.py @@ -2,15 +2,28 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) import json -import logging import time +from os import environ from odoo import models from odoo.http import request as http_request from odoo.tools.config import config +udp_dest = environ.get('ODOO_REQUESTS_LOGGING_UDP') +if udp_dest: + import socket + import atexit -_logger = logging.getLogger('monitoring.http.requests') + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) + atexit.register(sock.close) + ip, port = udp_dest.split(':') + + def output_method(data): + sock.sendto(data.encode('utf-8'), (ip, port)) +else: + import logging + _logger = logging.getLogger('monitoring.http.requests') + output_method = _logger.info class IrHttp(models.AbstractModel): @@ -80,4 +93,4 @@ class IrHttp(models.AbstractModel): @classmethod def _monitoring_log(cls, info): - _logger.info(json.dumps(info)) + output_method(json.dumps(info)) diff --git a/monitoring_log_requests/utils.py b/monitoring_log_requests/utils.py new file mode 100644 index 0000000..7a2a690 --- /dev/null +++ b/monitoring_log_requests/utils.py @@ -0,0 +1,10 @@ +# Copyright 2020 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from distutils.util import strtobool +from os import environ + + +def is_enabled(): + env_val = environ.get('ODOO_REQUESTS_LOGGING') + return bool(strtobool(env_val or '0'.lower()))