diff --git a/synapse/metrics/__init__.py b/synapse/metrics/__init__.py index 86ac2c2395..c7ad8005e3 100644 --- a/synapse/metrics/__init__.py +++ b/synapse/metrics/__init__.py @@ -41,19 +41,27 @@ from typing import ( ) import attr -from prometheus_client import CollectorRegistry, Counter, Gauge, Histogram, Metric -from prometheus_client.core import ( +from prometheus_client import ( REGISTRY, + CollectorRegistry, + Counter, + Gauge, + Histogram, + Metric, + generate_latest, +) +from prometheus_client.core import ( GaugeHistogramMetricFamily, GaugeMetricFamily, ) from twisted.python.threadpool import ThreadPool +from twisted.web.resource import Resource +from twisted.web.server import Request # This module is imported for its side effects; flake8 needn't warn that it's unused. import synapse.metrics._reactor_metrics # noqa: F401 from synapse.metrics._gc import MIN_TIME_BETWEEN_GCS, install_gc_manager -from synapse.metrics._twisted_exposition import MetricsResource, generate_latest from synapse.metrics._types import Collector from synapse.types import StrSequence from synapse.util import SYNAPSE_VERSION @@ -66,6 +74,35 @@ all_gauges: Dict[str, Collector] = {} HAVE_PROC_SELF_STAT = os.path.exists("/proc/self/stat") +CONTENT_TYPE_LATEST = "text/plain; version=0.0.4; charset=utf-8" + + +def _set_prometheus_client_use_created_metrics(new_value: bool) -> None: + """ + Sets whether prometheus_client should expose `_created`-suffixed metrics for + all gauges, histograms and summaries. + + There is no programmatic way in the old versions of `prometheus_client` to disable + this without poking at internals; the proper way in the old `prometheus_client` + versions is to use an environment variable which prometheus_client loads at import + time OR to use the dedicated `disable_created_metrics()`/`enable_created_metrics()` + functions, but these were only added in `prometheus_client` `0.18.0`. + + The motivation for disabling these `_created` metrics is that they're + a waste of space as they're not useful but they take up space in Prometheus. + """ + import prometheus_client.metrics + + if hasattr(prometheus_client.metrics, "_use_created"): + prometheus_client.metrics._use_created = new_value + else: + logger.error( + "Can't disable `_created` metrics in prometheus_client (brittle hack broken?)" + ) + + +_set_prometheus_client_use_created_metrics(False) + class _RegistryProxy: @staticmethod @@ -474,6 +511,23 @@ def register_threadpool(name: str, threadpool: ThreadPool) -> None: ) +class MetricsResource(Resource): + """ + Twisted ``Resource`` that serves prometheus metrics. + """ + + isLeaf = True + + def __init__(self, registry: CollectorRegistry = REGISTRY): + self.registry = registry + + def render_GET(self, request: Request) -> bytes: + request.setHeader(b"Content-Type", CONTENT_TYPE_LATEST.encode("ascii")) + response = generate_latest(self.registry) + request.setHeader(b"Content-Length", str(len(response))) + return response + + __all__ = [ "Collector", "MetricsResource", diff --git a/synapse/metrics/_twisted_exposition.py b/synapse/metrics/_twisted_exposition.py deleted file mode 100644 index b4199bc042..0000000000 --- a/synapse/metrics/_twisted_exposition.py +++ /dev/null @@ -1,80 +0,0 @@ -# -# This file is licensed under the Affero General Public License (AGPL) version 3. -# -# Copyright 2019 Matrix.org Foundation C.I.C. -# Copyright 2015-2019 Prometheus Python Client Developers -# Copyright (C) 2023 New Vector, Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# See the GNU Affero General Public License for more details: -# . -# -# Originally licensed under the Apache License, Version 2.0: -# . -# -# [This file includes modifications made by New Vector Limited] -# -# - -import logging - -from prometheus_client import ( - REGISTRY, - CollectorRegistry, - generate_latest, -) - -from twisted.web.resource import Resource -from twisted.web.server import Request - -logger = logging.getLogger(__name__) - -CONTENT_TYPE_LATEST = "text/plain; version=0.0.4; charset=utf-8" - - -def _set_prometheus_client_use_created_metrics(new_value: bool) -> None: - """ - Sets whether prometheus_client should expose `_created`-suffixed metrics for - all gauges, histograms and summaries. - - There is no programmatic way in the old versions of `prometheus_client` to disable - this without poking at internals; the proper way in the old `prometheus_client` - versions is to use an environment variable which prometheus_client loads at import - time OR to use the dedicated `disable_created_metrics()`/`enable_created_metrics()` - functions, but these were only added in `prometheus_client` `0.18.0`. - - The motivation for disabling these `_created` metrics is that they're - a waste of space as they're not useful but they take up space in Prometheus. - """ - import prometheus_client.metrics - - if hasattr(prometheus_client.metrics, "_use_created"): - prometheus_client.metrics._use_created = new_value - else: - logger.error( - "Can't disable `_created` metrics in prometheus_client (brittle hack broken?)" - ) - - -_set_prometheus_client_use_created_metrics(False) - - -class MetricsResource(Resource): - """ - Twisted ``Resource`` that serves prometheus metrics. - """ - - isLeaf = True - - def __init__(self, registry: CollectorRegistry = REGISTRY): - self.registry = registry - - def render_GET(self, request: Request) -> bytes: - request.setHeader(b"Content-Type", CONTENT_TYPE_LATEST.encode("ascii")) - response = generate_latest(self.registry) - request.setHeader(b"Content-Length", str(len(response))) - return response diff --git a/synapse/util/metrics.py b/synapse/util/metrics.py index 6a389f7a7e..faf3793346 100644 --- a/synapse/util/metrics.py +++ b/synapse/util/metrics.py @@ -46,6 +46,7 @@ from synapse.util import Clock logger = logging.getLogger(__name__) + block_counter = Counter("synapse_util_metrics_block_count", "", ["block_name"]) block_timer = Counter("synapse_util_metrics_block_time_seconds", "", ["block_name"]) diff --git a/tests/storage/test_event_metrics.py b/tests/storage/test_event_metrics.py index 3f7ee86498..fc6e02545f 100644 --- a/tests/storage/test_event_metrics.py +++ b/tests/storage/test_event_metrics.py @@ -18,9 +18,8 @@ # [This file includes modifications made by New Vector Limited] # # -from prometheus_client import generate_latest -from synapse.metrics import REGISTRY +from synapse.metrics import REGISTRY, generate_latest from synapse.types import UserID, create_requester from tests.unittest import HomeserverTestCase