Compare commits

...

25 Commits

Author SHA1 Message Date
Eric Eastwood
2e42f53c93
Merge 95eab2193a04b99a7f3212400b1dee28f5f037f7 into 6ddbb0361222da276cf0f9b76dd2dff92862327e 2025-07-02 18:09:17 +02:00
V02460
6ddbb03612
Raise poetry-core version cap to 2.1.3 (#18575)
Request to raise the defensive version cap for poetry-core from 1.9.1 to
2.1.3.

My understanding is that the major version bump of poetry signals the
transition to standardized pyproject.toml metadata, but does not affect
backwards compatibility.

This is a subset of the changes in #18432

Fixes #18200

### Pull Request Checklist

<!-- Please read
https://element-hq.github.io/synapse/latest/development/contributing_guide.html
before submitting your pull request -->

* [x] Pull request is based on the develop branch
* [x] Pull request includes a [changelog
file](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#changelog).
The entry should:
- Be a short description of your change which makes sense to users.
"Fixed a bug that prevented receiving messages from other servers."
instead of "Moved X method from `EventStore` to `EventWorkerStore`.".
  - Use markdown where necessary, mostly for `code blocks`.
  - End with either a period (.) or an exclamation mark (!).
  - Start with a capital letter.
- Feel free to credit yourself, by adding a sentence "Contributed by
@github_username." or "Contributed by [Your Name]." to the end of the
entry.
* [x] [Code
style](https://element-hq.github.io/synapse/latest/code_style.html) is
correct (run the
[linters](https://element-hq.github.io/synapse/latest/development/contributing_guide.html#run-the-linters))
2025-07-02 15:57:30 +00:00
Erik Johnston
cc8da2c5ed
Log the room ID we're purging state for (#18625)
So we can see what we're deleting.
2025-07-02 15:02:12 +01:00
reivilibre
c17fd947f3
Fix documentation of the Delete Room Admin API's status field. (#18519)
Fixes: #18502

---------

Signed-off-by: Olivier 'reivilibre <oliverw@matrix.org>
2025-07-01 17:55:38 +01:00
Eric Eastwood
95eab2193a Merge branch 'develop' into madlittlemods/remove-metrics-listener 2025-06-26 17:34:53 -05:00
Eric Eastwood
25585b4b49 Merge branch 'develop' into madlittlemods/remove-metrics-listener
Conflicts:
	poetry.lock
2025-06-24 13:23:58 -05:00
Eric Eastwood
467084d43e Merge branch 'develop' into madlittlemods/remove-metrics-listener 2025-06-23 12:51:35 -05:00
Eric Eastwood
1ce74d444d Log an error for old versions 2025-06-23 12:14:33 -05:00
Eric Eastwood
03ae604af7 Remove extra newline 2025-06-23 11:57:00 -05:00
Eric Eastwood
6c662e02e7 Fix lints 2025-06-23 11:55:56 -05:00
Eric Eastwood
b849bed8f9 Make broken hack more obvious when it happens 2025-06-23 11:55:17 -05:00
Eric Eastwood
04084ae224 Re-organize metrics resource 2025-06-23 11:54:51 -05:00
Eric Eastwood
d0604463f6 Remove tests which don't assert anything beyond what the util already does 2025-06-23 11:53:35 -05:00
Eric Eastwood
07c680633f Update minimum version of prometheus-client so prometheus_client.metrics is available
See https://github.com/element-hq/synapse/pull/18584#discussion_r2159707081
2025-06-20 17:00:41 -05:00
Eric Eastwood
16e87ed5c9 Restore _set_prometheus_client_use_created_metrics tests 2025-06-20 16:51:54 -05:00
Eric Eastwood
cfdacb8664 Fix lints 2025-06-20 16:41:28 -05:00
Eric Eastwood
adaf5b0fa3 Update with new state of reality 2025-06-20 16:18:19 -05:00
Eric Eastwood
bb3904cac9 Restore _set_prometheus_client_use_created_metrics
See https://github.com/element-hq/synapse/pull/18584#discussion_r2159670686
2025-06-20 16:15:02 -05:00
Eric Eastwood
8ccd52c93c Fix lints 2025-06-20 15:38:59 -05:00
Eric Eastwood
54b836cce6 Remove tests for _set_prometheus_client_use_created_metrics (which was removed) 2025-06-20 15:38:26 -05:00
Eric Eastwood
3b05b5efe9 Add changelog 2025-06-20 15:37:49 -05:00
Eric Eastwood
3e16b887ed Remove stray file 2025-06-20 15:14:31 -05:00
Eric Eastwood
6e47458b91 Fix lints 2025-06-20 15:13:20 -05:00
Eric Eastwood
1fe3fa40a8 Disable _created metrics via dedicated built-in function
Added in https://github.com/prometheus/client_python/pull/973
2025-06-20 15:09:36 -05:00
Eric Eastwood
bb31f6097c Remove metrics listener type in favor of http listener with metrics resource 2025-06-20 11:51:54 -05:00
18 changed files with 151 additions and 209 deletions

1
changelog.d/18519.doc Normal file
View File

@ -0,0 +1 @@
Fix documentation of the Delete Room Admin API's status field.

1
changelog.d/18575.misc Normal file
View File

@ -0,0 +1 @@
Raise poetry-core version cap to 2.1.3.

View File

@ -0,0 +1 @@
Remove `metrics` listener (serves metrics at `/metrics`) type in favor of `http` listener with `metrics` resource (serves metrics at `/_synapse/metrics`).

1
changelog.d/18625.misc Normal file
View File

@ -0,0 +1 @@
Log the room ID we're purging state for.

View File

@ -806,7 +806,7 @@ A response body like the following is returned:
}, { }, {
"delete_id": "delete_id2", "delete_id": "delete_id2",
"room_id": "!roomid:example.com", "room_id": "!roomid:example.com",
"status": "purging", "status": "active",
"shutdown_room": { "shutdown_room": {
"kicked_users": [ "kicked_users": [
"@foobar:example.com" "@foobar:example.com"
@ -843,7 +843,7 @@ A response body like the following is returned:
```json ```json
{ {
"status": "purging", "status": "active",
"delete_id": "bHkCNQpHqOaFhPtK", "delete_id": "bHkCNQpHqOaFhPtK",
"room_id": "!roomid:example.com", "room_id": "!roomid:example.com",
"shutdown_room": { "shutdown_room": {
@ -876,8 +876,8 @@ The following fields are returned in the JSON response body:
- `delete_id` - The ID for this purge - `delete_id` - The ID for this purge
- `room_id` - The ID of the room being deleted - `room_id` - The ID of the room being deleted
- `status` - The status will be one of: - `status` - The status will be one of:
- `shutting_down` - The process is removing users from the room. - `scheduled` - The deletion is waiting to be started
- `purging` - The process is purging the room and event data from database. - `active` - The process is purging the room and event data from database.
- `complete` - The process has completed successfully. - `complete` - The process has completed successfully.
- `failed` - The process is aborted, an error has occurred. - `failed` - The process is aborted, an error has occurred.
- `error` - A string that shows an error message if `status` is `failed`. - `error` - A string that shows an error message if `status` is `failed`.

View File

@ -60,8 +60,11 @@
# beginning of the new metrics listener # beginning of the new metrics listener
- port: 9000 - port: 9000
type: metrics type: http
bind_addresses: ['::1', '127.0.0.1'] bind_addresses: ['::1', '127.0.0.1']
resources:
- names: [metrics]
compress: false
``` ```
1. Restart Synapse. 1. Restart Synapse.

View File

@ -494,7 +494,7 @@ Options for each entry include:
* `bind_addresses` (array|null): A list of local addresses to listen on. The default is "all local interfaces". * `bind_addresses` (array|null): A list of local addresses to listen on. The default is "all local interfaces".
* `type` (string): The type of listener. Normally `http`, but other valid options are [`manhole`](../../manhole.md) and [`metrics`](../../metrics-howto.md). * `type` (string): The type of listener. Normally `http`, but other valid options are [`manhole`](../../manhole.md).
* `tls` (boolean): Set to true to enable TLS for this listener. Will use the TLS key/cert specified in tls_private_key_path/tls_certificate_path. * `tls` (boolean): Set to true to enable TLS for this listener. Will use the TLS key/cert specified in tls_private_key_path/tls_certificate_path.

5
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. # This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand.
[[package]] [[package]]
name = "annotated-types" name = "annotated-types"
@ -1721,6 +1721,7 @@ files = [
{file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"}, {file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"},
{file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"}, {file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"},
{file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"}, {file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"},
{file = "psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2"},
{file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"}, {file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"},
{file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"}, {file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"},
{file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"}, {file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"},
@ -3388,4 +3389,4 @@ user-search = ["pyicu"]
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.1"
python-versions = "^3.9.0" python-versions = "^3.9.0"
content-hash = "9824e42dfc0e128129ee0c8641f7fe639bf47574cdd3f052dd995941abc6e44b" content-hash = "ad95ef9da5a5f71fd0da41719e94b2920c8ba119f8bf942b25c2b50661ffa42b"

View File

@ -47,11 +47,7 @@ target-version = "py39"
# flake8-bugbear compatible checks. Its error codes are described at # flake8-bugbear compatible checks. Its error codes are described at
# https://beta.ruff.rs/docs/rules/#flake8-bugbear-b # https://beta.ruff.rs/docs/rules/#flake8-bugbear-b
# B023: Functions defined inside a loop must not use variables redefined in the loop # B023: Functions defined inside a loop must not use variables redefined in the loop
ignore = [ ignore = ["B023", "E501", "E731"]
"B023",
"E501",
"E731",
]
select = [ select = [
# pycodestyle # pycodestyle
"E", "E",
@ -82,7 +78,15 @@ select = [
[tool.ruff.lint.isort] [tool.ruff.lint.isort]
combine-as-imports = true combine-as-imports = true
section-order = ["future", "standard-library", "third-party", "twisted", "first-party", "testing", "local-folder"] section-order = [
"future",
"standard-library",
"third-party",
"twisted",
"first-party",
"testing",
"local-folder",
]
known-first-party = ["synapse"] known-first-party = ["synapse"]
[tool.ruff.lint.isort.sections] [tool.ruff.lint.isort.sections]
@ -107,9 +111,7 @@ authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
license = "AGPL-3.0-or-later" license = "AGPL-3.0-or-later"
readme = "README.rst" readme = "README.rst"
repository = "https://github.com/element-hq/synapse" repository = "https://github.com/element-hq/synapse"
packages = [ packages = [{ include = "synapse" }]
{ include = "synapse" },
]
classifiers = [ classifiers = [
"Development Status :: 5 - Production/Stable", "Development Status :: 5 - Production/Stable",
"Topic :: Communications :: Chat", "Topic :: Communications :: Chat",
@ -135,9 +137,7 @@ include = [
{ path = "rust/build.rs", format = "sdist" }, { path = "rust/build.rs", format = "sdist" },
{ path = "rust/src/**", format = "sdist" }, { path = "rust/src/**", format = "sdist" },
] ]
exclude = [ exclude = [{ path = "synapse/*.so", format = "sdist" }]
{ path = "synapse/*.so", format = "sdist"}
]
[tool.poetry.build] [tool.poetry.build]
script = "build_rust.py" script = "build_rust.py"
@ -195,7 +195,9 @@ pymacaroons = ">=0.13.0"
msgpack = ">=0.5.2" msgpack = ">=0.5.2"
phonenumbers = ">=8.2.0" phonenumbers = ">=8.2.0"
# we use GaugeHistogramMetric, which was added in prom-client 0.4.0. # we use GaugeHistogramMetric, which was added in prom-client 0.4.0.
prometheus-client = ">=0.4.0" # `prometheus_client.metrics` was added in 0.5.0, so we require that too.
# We chose 0.6.0 as that is the current version in Debian Buster (oldstable).
prometheus-client = ">=0.6.0"
# we use `order`, which arrived in attrs 19.2.0. # we use `order`, which arrived in attrs 19.2.0.
# Note: 21.1.0 broke `/sync`, see https://github.com/matrix-org/synapse/issues/9936 # Note: 21.1.0 broke `/sync`, see https://github.com/matrix-org/synapse/issues/9936
attrs = ">=19.2.0,!=21.1.0" attrs = ">=19.2.0,!=21.1.0"
@ -297,7 +299,9 @@ all = [
# matrix-synapse-ldap3 # matrix-synapse-ldap3
"matrix-synapse-ldap3", "matrix-synapse-ldap3",
# postgres # postgres
"psycopg2", "psycopg2cffi", "psycopg2cffi-compat", "psycopg2",
"psycopg2cffi",
"psycopg2cffi-compat",
# saml2 # saml2
"pysaml2", "pysaml2",
# oidc and jwt # oidc and jwt
@ -307,9 +311,11 @@ all = [
# sentry # sentry
"sentry-sdk", "sentry-sdk",
# opentracing # opentracing
"jaeger-client", "opentracing", "jaeger-client",
"opentracing",
# redis # redis
"txredisapi", "hiredis", "txredisapi",
"hiredis",
# cache-memory # cache-memory
"pympler", "pympler",
# improved user search # improved user search
@ -374,7 +380,7 @@ tomli = ">=1.2.3"
# runtime errors caused by build system changes. # runtime errors caused by build system changes.
# We are happy to raise these upper bounds upon request, # We are happy to raise these upper bounds upon request,
# provided we check that it's safe to do so (i.e. that CI passes). # provided we check that it's safe to do so (i.e. that CI passes).
requires = ["poetry-core>=1.1.0,<=1.9.1", "setuptools_rust>=1.3,<=1.10.2"] requires = ["poetry-core>=1.1.0,<=2.1.3", "setuptools_rust>=1.3,<=1.10.2"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"

View File

@ -451,8 +451,7 @@ properties:
type: string type: string
description: >- description: >-
The type of listener. Normally `http`, but other valid options are The type of listener. Normally `http`, but other valid options are
[`manhole`](../../manhole.md) and [`manhole`](../../manhole.md).
[`metrics`](../../metrics-howto.md).
enum: enum:
- http - http
- manhole - manhole

View File

@ -283,42 +283,6 @@ def register_start(
reactor.callWhenRunning(lambda: defer.ensureDeferred(wrapper())) reactor.callWhenRunning(lambda: defer.ensureDeferred(wrapper()))
def listen_metrics(bind_addresses: StrCollection, port: int) -> None:
"""
Start Prometheus metrics server.
"""
from prometheus_client import start_http_server as start_http_server_prometheus
from synapse.metrics import RegistryProxy
for host in bind_addresses:
logger.info("Starting metrics listener on %s:%d", host, port)
_set_prometheus_client_use_created_metrics(False)
start_http_server_prometheus(port, addr=host, registry=RegistryProxy)
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 to disable this without poking at internals;
the proper way is to use an environment variable which prometheus_client
loads at import time.
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?)"
)
def listen_manhole( def listen_manhole(
bind_addresses: StrCollection, bind_addresses: StrCollection,
port: int, port: int,

View File

@ -283,23 +283,6 @@ class GenericWorkerServer(HomeServer):
raise ConfigError( raise ConfigError(
"Can not using a unix socket for manhole at this time." "Can not using a unix socket for manhole at this time."
) )
elif listener.type == "metrics":
if not self.config.metrics.enable_metrics:
logger.warning(
"Metrics listener configured, but enable_metrics is not True!"
)
else:
if isinstance(listener, TCPListenerConfig):
_base.listen_metrics(
listener.bind_addresses,
listener.port,
)
else:
raise ConfigError(
"Can not use a unix socket for metrics at this time."
)
else: else:
logger.warning("Unsupported listener type: %s", listener.type) logger.warning("Unsupported listener type: %s", listener.type)

View File

@ -286,22 +286,6 @@ class SynapseHomeServer(HomeServer):
raise ConfigError( raise ConfigError(
"Can not use a unix socket for manhole at this time." "Can not use a unix socket for manhole at this time."
) )
elif listener.type == "metrics":
if not self.config.metrics.enable_metrics:
logger.warning(
"Metrics listener configured, but enable_metrics is not True!"
)
else:
if isinstance(listener, TCPListenerConfig):
_base.listen_metrics(
listener.bind_addresses,
listener.port,
)
else:
raise ConfigError(
"Can not use a unix socket for metrics at this time."
)
else: else:
# this shouldn't happen, as the listener type should have been checked # this shouldn't happen, as the listener type should have been checked
# during parsing # during parsing

View File

@ -25,6 +25,7 @@ import logging
import os import os
import platform import platform
import threading import threading
from importlib import metadata
from typing import ( from typing import (
Callable, Callable,
Dict, Dict,
@ -41,19 +42,28 @@ from typing import (
) )
import attr import attr
from prometheus_client import CollectorRegistry, Counter, Gauge, Histogram, Metric from pkg_resources import parse_version
from prometheus_client.core import ( from prometheus_client import (
REGISTRY, REGISTRY,
CollectorRegistry,
Counter,
Gauge,
Histogram,
Metric,
generate_latest,
)
from prometheus_client.core import (
GaugeHistogramMetricFamily, GaugeHistogramMetricFamily,
GaugeMetricFamily, GaugeMetricFamily,
) )
from twisted.python.threadpool import ThreadPool 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. # This module is imported for its side effects; flake8 needn't warn that it's unused.
import synapse.metrics._reactor_metrics # noqa: F401 import synapse.metrics._reactor_metrics # noqa: F401
from synapse.metrics._gc import MIN_TIME_BETWEEN_GCS, install_gc_manager 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.metrics._types import Collector
from synapse.types import StrSequence from synapse.types import StrSequence
from synapse.util import SYNAPSE_VERSION from synapse.util import SYNAPSE_VERSION
@ -66,6 +76,47 @@ all_gauges: Dict[str, Collector] = {}
HAVE_PROC_SELF_STAT = os.path.exists("/proc/self/stat") 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 (> `0.14.0` < `0.18.0`) is to use an environment variable which
prometheus_client loads at import time. For versions > `0.18.0`, we can use the
dedicated `disable_created_metrics()`/`enable_created_metrics()`.
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. It's not the end
of the world if this doesn't work.
"""
import prometheus_client.metrics
if hasattr(prometheus_client.metrics, "_use_created"):
prometheus_client.metrics._use_created = new_value
# Just log an error for old versions that don't support disabling the unecessary
# metrics. It's not the end of the world if this doesn't work as it just means extra
# wasted space taken up in Prometheus but things keep working.
elif parse_version(metadata.version("prometheus_client")) < parse_version("0.14.0"):
logger.error(
"Can't disable `_created` metrics in prometheus_client (unsupported `prometheus_client` version, too old)"
)
# If the attribute doesn't exist on a newer version, this is a sign that the brittle
# hack is broken. We should consider updating the minimum version of
# `prometheus_client` to a version (> `0.18.0`) where we can use dedicated
# `disable_created_metrics()`/`enable_created_metrics()` functions.
else:
raise Exception(
"Can't disable `_created` metrics in prometheus_client (brittle hack broken?)"
)
_set_prometheus_client_use_created_metrics(False)
class _RegistryProxy: class _RegistryProxy:
@staticmethod @staticmethod
@ -474,6 +525,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__ = [ __all__ = [
"Collector", "Collector",
"MetricsResource", "MetricsResource",

View File

@ -1,45 +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:
# <https://www.gnu.org/licenses/agpl-3.0.html>.
#
# Originally licensed under the Apache License, Version 2.0:
# <http://www.apache.org/licenses/LICENSE-2.0>.
#
# [This file includes modifications made by New Vector Limited]
#
#
from prometheus_client import REGISTRY, CollectorRegistry, generate_latest
from twisted.web.resource import Resource
from twisted.web.server import Request
CONTENT_TYPE_LATEST = "text/plain; version=0.0.4; charset=utf-8"
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

View File

@ -34,6 +34,7 @@ from synapse.metrics.background_process_metrics import wrap_as_background_proces
from synapse.storage.database import LoggingTransaction from synapse.storage.database import LoggingTransaction
from synapse.storage.databases import Databases from synapse.storage.databases import Databases
from synapse.types.storage import _BackgroundUpdates from synapse.types.storage import _BackgroundUpdates
from synapse.util.stringutils import shortstr
if TYPE_CHECKING: if TYPE_CHECKING:
from synapse.server import HomeServer from synapse.server import HomeServer
@ -167,6 +168,12 @@ class PurgeEventsStorageController:
break break
(room_id, groups_to_sequences) = next_to_delete (room_id, groups_to_sequences) = next_to_delete
logger.info(
"[purge] deleting state groups for room %s: %s",
room_id,
shortstr(groups_to_sequences.keys(), maxitems=10),
)
made_progress = await self._delete_state_groups( made_progress = await self._delete_state_groups(
room_id, groups_to_sequences room_id, groups_to_sequences
) )

View File

@ -18,14 +18,10 @@
# [This file includes modifications made by New Vector Limited] # [This file includes modifications made by New Vector Limited]
# #
# #
from importlib import metadata
from typing import Dict, Protocol, Tuple from typing import Dict, Protocol, Tuple
from unittest.mock import patch
from pkg_resources import parse_version
from prometheus_client.core import Sample from prometheus_client.core import Sample
from synapse.app._base import _set_prometheus_client_use_created_metrics
from synapse.metrics import REGISTRY, InFlightGauge, generate_latest from synapse.metrics import REGISTRY, InFlightGauge, generate_latest
from synapse.util.caches.deferred_cache import DeferredCache from synapse.util.caches.deferred_cache import DeferredCache
@ -184,30 +180,3 @@ class CacheMetricsTests(unittest.HomeserverTestCase):
self.assertEqual(items["synapse_util_caches_cache_size"], "1.0") self.assertEqual(items["synapse_util_caches_cache_size"], "1.0")
self.assertEqual(items["synapse_util_caches_cache_max_size"], "777.0") self.assertEqual(items["synapse_util_caches_cache_max_size"], "777.0")
class PrometheusMetricsHackTestCase(unittest.HomeserverTestCase):
if parse_version(metadata.version("prometheus_client")) < parse_version("0.14.0"):
skip = "prometheus-client too old"
def test_created_metrics_disabled(self) -> None:
"""
Tests that a brittle hack, to disable `_created` metrics, works.
This involves poking at the internals of prometheus-client.
It's not the end of the world if this doesn't work.
This test gives us a way to notice if prometheus-client changes
their internals.
"""
import prometheus_client.metrics
PRIVATE_FLAG_NAME = "_use_created"
# By default, the pesky `_created` metrics are enabled.
# Check this assumption is still valid.
self.assertTrue(getattr(prometheus_client.metrics, PRIVATE_FLAG_NAME))
with patch("prometheus_client.metrics") as mock:
setattr(mock, PRIVATE_FLAG_NAME, True)
_set_prometheus_client_use_created_metrics(False)
self.assertFalse(getattr(mock, PRIVATE_FLAG_NAME, False))

View File

@ -18,9 +18,8 @@
# [This file includes modifications made by New Vector Limited] # [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 synapse.types import UserID, create_requester
from tests.unittest import HomeserverTestCase from tests.unittest import HomeserverTestCase