From 6bb5ffe3e91acfc1121cc71241c05a88c758fb5f Mon Sep 17 00:00:00 2001 From: Patrick Tombez <35060345+p-tombez@users.noreply.github.com> Date: Wed, 4 Aug 2021 11:16:46 +0200 Subject: [PATCH] [13.0][ADD] monitoring_prometheus (#239) [13.0][ADD] monitoring_prometheus --- monitoring_prometheus/README.rst | 17 ++++++++ monitoring_prometheus/__init__.py | 2 + monitoring_prometheus/__manifest__.py | 22 ++++++++++ monitoring_prometheus/controllers/__init__.py | 1 + .../controllers/prometheus_metrics.py | 11 +++++ monitoring_prometheus/models/__init__.py | 1 + monitoring_prometheus/models/ir_http.py | 40 +++++++++++++++++++ requirements.txt | 1 + 8 files changed, 95 insertions(+) create mode 100644 monitoring_prometheus/README.rst create mode 100644 monitoring_prometheus/__init__.py create mode 100644 monitoring_prometheus/__manifest__.py create mode 100644 monitoring_prometheus/controllers/__init__.py create mode 100644 monitoring_prometheus/controllers/prometheus_metrics.py create mode 100644 monitoring_prometheus/models/__init__.py create mode 100644 monitoring_prometheus/models/ir_http.py diff --git a/monitoring_prometheus/README.rst b/monitoring_prometheus/README.rst new file mode 100644 index 0000000..aa98ffe --- /dev/null +++ b/monitoring_prometheus/README.rst @@ -0,0 +1,17 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License + +============================== +Monitoring: Prometheus metrics +============================== + +Add an endpoint */metrics* to allow a Prometheus server to fetch application metrics. +Current available metrics are: + +* Request completion time with 3 differentiators: + * Filestore + * Assets + * Everything else +* Longpolling request count + +No additional configuration is needed, just ensure that the Prometheus server is allowed to communicate with Odoo diff --git a/monitoring_prometheus/__init__.py b/monitoring_prometheus/__init__.py new file mode 100644 index 0000000..91c5580 --- /dev/null +++ b/monitoring_prometheus/__init__.py @@ -0,0 +1,2 @@ +from . import controllers +from . import models diff --git a/monitoring_prometheus/__manifest__.py b/monitoring_prometheus/__manifest__.py new file mode 100644 index 0000000..22594d4 --- /dev/null +++ b/monitoring_prometheus/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2016-2019 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + + +{ + "name": "Monitoring: Prometheus Metrics", + "version": "13.0.1.0.0", + "author": "Camptocamp,Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "category", + "depends": [ + "base", + "web", + "server_environment", + ], + "website": "http://www.camptocamp.com", + "data": [], + "external_dependencies": { + "python": ["prometheus_client"], + }, + "installable": True, +} diff --git a/monitoring_prometheus/controllers/__init__.py b/monitoring_prometheus/controllers/__init__.py new file mode 100644 index 0000000..13ff72f --- /dev/null +++ b/monitoring_prometheus/controllers/__init__.py @@ -0,0 +1 @@ +from . import prometheus_metrics diff --git a/monitoring_prometheus/controllers/prometheus_metrics.py b/monitoring_prometheus/controllers/prometheus_metrics.py new file mode 100644 index 0000000..411a2ac --- /dev/null +++ b/monitoring_prometheus/controllers/prometheus_metrics.py @@ -0,0 +1,11 @@ +# Copyright 2016-2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo.http import Controller, route +from prometheus_client import generate_latest + + +class PrometheusController(Controller): + @route('/metrics', auth='public') + def metrics(self): + return generate_latest() diff --git a/monitoring_prometheus/models/__init__.py b/monitoring_prometheus/models/__init__.py new file mode 100644 index 0000000..9a5eb71 --- /dev/null +++ b/monitoring_prometheus/models/__init__.py @@ -0,0 +1 @@ +from . import ir_http diff --git a/monitoring_prometheus/models/ir_http.py b/monitoring_prometheus/models/ir_http.py new file mode 100644 index 0000000..0c026d6 --- /dev/null +++ b/monitoring_prometheus/models/ir_http.py @@ -0,0 +1,40 @@ +# Copyright 2016-2021 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import models +from odoo.http import request +from prometheus_client import Summary, Counter + + +REQUEST_TIME = Summary( + "request_latency_sec", "Request response time in sec", ["query_type"] +) +LONGPOLLING_COUNT = Counter("longpolling", "Longpolling request count") + + +class IrHttp(models.AbstractModel): + _inherit = "ir.http" + + @classmethod + def _dispatch(cls): + path_info = request.httprequest.environ.get("PATH_INFO") + + if path_info.startswith("/longpolling/"): + LONGPOLLING_COUNT.inc() + return super()._dispatch() + + if path_info.startswith("/metrics"): + return super()._dispatch() + + if path_info.startswith("/web/static"): + label = "assets" + elif path_info.startswith("/web/content"): + label = "filestore" + else: + label = "client" + + res = None + with REQUEST_TIME.labels(label).time(): + res = super()._dispatch() + + return res diff --git a/requirements.txt b/requirements.txt index 8d39c30..0525441 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ python-keystoneclient==3.22.0 keystoneauth1==3.14.0 # error with 5.x (ConstructorError: could not determine a constructor for the tag '!record') PyYAML==4.2b4 +prometheus_client==0.11.0