From 47ac7e3757f9976d72d16c75c7bc33b9e3db2ad4 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 23 May 2018 13:42:52 -0500 Subject: [PATCH 01/12] serve metrics on a different thread --- synapse/app/homeserver.py | 6 ++++++ synapse/config/server.py | 15 --------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 449bfacdb940..700a74d25a96 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -161,6 +161,12 @@ def _listener_http(self, config, listener_config): ) logger.info("Synapse now listening on port %d", port) + if config.enable_metrics and config.metrics_port: + from prometheus_client import start_http_server + start_http_server(int(config.metrics_port), addr=config.metrics_bind_host) + logger.info("Metrics now reporting on %s:%d", + config.metrics_bind_host, config.metrics_port) + def _configure_named_resource(self, name, compress=False): """Build a resource map for a named resource diff --git a/synapse/config/server.py b/synapse/config/server.py index 8f0b6d1f2820..adcb469b776c 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -136,21 +136,6 @@ def read_config(self, config): "type": "manhole", }) - metrics_port = config.get("metrics_port") - if metrics_port: - self.listeners.append({ - "port": metrics_port, - "bind_addresses": [config.get("metrics_bind_host", "127.0.0.1")], - "tls": False, - "type": "http", - "resources": [ - { - "names": ["metrics"], - "compress": False, - }, - ] - }) - def default_config(self, server_name, **kwargs): if ":" in server_name: bind_port = int(server_name.split(":")[1]) From 40c2d353e8d999ec9b96426428cb5e7aba5a1c9a Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 23 May 2018 13:49:34 -0500 Subject: [PATCH 02/12] kick off the metrics server, in another thread. --- synapse/app/homeserver.py | 18 +++++++++++------- synapse/metrics/__init__.py | 3 ++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 700a74d25a96..10a355a8f2d0 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -161,12 +161,6 @@ def _listener_http(self, config, listener_config): ) logger.info("Synapse now listening on port %d", port) - if config.enable_metrics and config.metrics_port: - from prometheus_client import start_http_server - start_http_server(int(config.metrics_port), addr=config.metrics_bind_host) - logger.info("Metrics now reporting on %s:%d", - config.metrics_bind_host, config.metrics_port) - def _configure_named_resource(self, name, compress=False): """Build a resource map for a named resource @@ -238,13 +232,20 @@ def _configure_named_resource(self, name, compress=False): resources[WEB_CLIENT_PREFIX] = build_resource_for_web_client(self) if name == "metrics" and self.get_config().enable_metrics: - resources[METRICS_PREFIX] = MetricsResource(RegistryProxy()) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) if name == "replication": resources[REPLICATION_PREFIX] = ReplicationRestResource(self) return resources + def _listener_metrics(self, config): + if config.enable_metrics and config.metrics_port: + from prometheus_client import start_http_server + reactor.callInThread(start_http_server, int(config.metrics_port), addr=config.metrics_bind_host, registry=RegistryProxy) + logger.info("Metrics now reporting on %s:%d", + config.metrics_bind_host, config.metrics_port) + def start_listening(self): config = self.get_config() @@ -274,6 +275,9 @@ def start_listening(self): else: logger.warn("Unrecognized listener type: %s", listener["type"]) + # Kick off the metrics server. + self._listener_metrics(config) + def run_startup_checks(self, db_conn, database_engine): all_users_native = are_all_users_on_domain( db_conn.cursor(), database_engine, self.hostname diff --git a/synapse/metrics/__init__.py b/synapse/metrics/__init__.py index e33ed6c9bed7..88045a844b37 100644 --- a/synapse/metrics/__init__.py +++ b/synapse/metrics/__init__.py @@ -37,7 +37,8 @@ class RegistryProxy(object): - def collect(self): + @staticmethod + def collect(): for metric in REGISTRY.collect(): if not metric.name.startswith("__"): yield metric From e6272169df996118ac097d93ffcdd23ecf987bf3 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Wed, 23 May 2018 13:54:40 -0500 Subject: [PATCH 03/12] pep8 --- synapse/app/homeserver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 10a355a8f2d0..b8fbe6be5960 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -242,7 +242,8 @@ def _configure_named_resource(self, name, compress=False): def _listener_metrics(self, config): if config.enable_metrics and config.metrics_port: from prometheus_client import start_http_server - reactor.callInThread(start_http_server, int(config.metrics_port), addr=config.metrics_bind_host, registry=RegistryProxy) + reactor.callInThread(start_http_server, int(config.metrics_port), + addr=config.metrics_bind_host, registry=RegistryProxy) logger.info("Metrics now reporting on %s:%d", config.metrics_bind_host, config.metrics_port) From 81bc4cedb1bd67d49aa97a0b1e9b74b3f70ea9cc Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 28 May 2018 22:47:09 +1000 Subject: [PATCH 04/12] add some docs on the metrics changes --- docs/metrics-howto.rst | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/metrics-howto.rst b/docs/metrics-howto.rst index 8acc479bc337..d440657aa6fc 100644 --- a/docs/metrics-howto.rst +++ b/docs/metrics-howto.rst @@ -34,6 +34,39 @@ How to monitor Synapse metrics using Prometheus Restart prometheus. +Removal of deprecated metrics & time based counters becoming histograms in 0.30.0 +--------------------------------------------------------------------------------- + +The duplicated metrics deprecated in Synapse 0.27.0 have been removed. + +All time duration-based metrics have been changed to be seconds. This affects: + +================================ +msec -> sec metrics +================================ +python_gc_time +python_twisted_reactor_tick_time +synapse_storage_query_time +synapse_storage_schedule_time +synapse_storage_transaction_time +================================ + +Several metrics have been changed to be histograms, which sort entries into +buckets and allow better analysis. The following metrics are now histograms: + +========================================= +Altered metrics +========================================= +python_gc_time +python_twisted_reactor_pending_calls +python_twisted_reactor_tick_time +synapse_http_server_response_time_seconds +synapse_storage_query_time +synapse_storage_schedule_time +synapse_storage_transaction_time +========================================= + + Block and response metrics renamed for 0.27.0 --------------------------------------------- From b1029fd25bc3b2ea17665d495416f534e28d59fe Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 28 May 2018 23:15:43 +1000 Subject: [PATCH 05/12] update docs --- docs/metrics-howto.rst | 45 +++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/docs/metrics-howto.rst b/docs/metrics-howto.rst index d440657aa6fc..aa0fe4e21e4a 100644 --- a/docs/metrics-howto.rst +++ b/docs/metrics-howto.rst @@ -1,25 +1,48 @@ How to monitor Synapse metrics using Prometheus =============================================== -1. Install prometheus: +1. Install Prometheus: Follow instructions at http://prometheus.io/docs/introduction/install/ -2. Enable synapse metrics: +2. Enable Synapse metrics: - Simply setting a (local) port number will enable it. Pick a port. - prometheus itself defaults to 9090, so starting just above that for - locally monitored services seems reasonable. E.g. 9092: + There are two methods of enabling metrics in Synapse. - Add to homeserver.yaml:: + The first serves the metrics as a part of the usual web server and can be + enabled by adding the "metrics" resource to the existing listener as such:: - metrics_port: 9092 + resources: + - names: + - client + - metrics - Also ensure that ``enable_metrics`` is set to ``True``. + This provides a simple way of adding metrics to your Synapse installation, + and serves under ``/_synapse/metrics``. If you do not wish your metrics be + publicly exposed, you will need to either filter it out at your load + balancer, or use the second method. - Restart synapse. + The second method runs the metrics server on a different port, in a + different thread to Synapse. This can make it more resilient to heavy load + meaning metrics cannot be retrieved, and can be exposed to just internal + networks easier. The served metrics are available over HTTP only, and will + be available at ``/``. -3. Add a prometheus target for synapse. + Add a new listener to homeserver.yaml:: + + listeners: + - type: metrics + port: 9000 + bind_addresses: + - '::' + - '0.0.0.0' + + For both options, you will need to ensure that ``enable_metrics`` is set to + ``True``. + + Restart Synapse. + +3. Add a Prometheus target for Synapse. It needs to set the ``metrics_path`` to a non-default value (under ``scrape_configs``):: @@ -31,7 +54,7 @@ How to monitor Synapse metrics using Prometheus If your prometheus is older than 1.5.2, you will need to replace ``static_configs`` in the above with ``target_groups``. - Restart prometheus. + Restart Prometheus. Removal of deprecated metrics & time based counters becoming histograms in 0.30.0 From 183f18673c789f10ede79ff25cc1b6a7e9073d13 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 28 May 2018 23:15:48 +1000 Subject: [PATCH 06/12] update listener config --- synapse/app/homeserver.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index b8fbe6be5960..59022a9c130d 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -239,14 +239,6 @@ def _configure_named_resource(self, name, compress=False): return resources - def _listener_metrics(self, config): - if config.enable_metrics and config.metrics_port: - from prometheus_client import start_http_server - reactor.callInThread(start_http_server, int(config.metrics_port), - addr=config.metrics_bind_host, registry=RegistryProxy) - logger.info("Metrics now reporting on %s:%d", - config.metrics_bind_host, config.metrics_port) - def start_listening(self): config = self.get_config() @@ -273,12 +265,20 @@ def start_listening(self): reactor.addSystemEventTrigger( "before", "shutdown", server_listener.stopListening, ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + from prometheus_client import start_http_server + for host in listener["bind_addresses"]: + reactor.callInThread(start_http_server, int(listener["port"]), + addr=host, registry=RegistryProxy) + logger.info("Metrics now reporting on %s:%d", + host, listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) - # Kick off the metrics server. - self._listener_metrics(config) - def run_startup_checks(self, db_conn, database_engine): all_users_native = are_all_users_on_domain( db_conn.cursor(), database_engine, self.hostname From 98c0c7135715e7e52822af6eed3a38cd0b14cb0c Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 28 May 2018 23:29:19 +1000 Subject: [PATCH 07/12] add listening for metrics to all the apps --- synapse/app/_base.py | 13 +++++++++++++ synapse/app/appservice.py | 6 ++++++ synapse/app/client_reader.py | 9 ++++++++- synapse/app/event_creator.py | 9 ++++++++- synapse/app/federation_reader.py | 9 ++++++++- synapse/app/federation_sender.py | 9 ++++++++- synapse/app/frontend_proxy.py | 9 ++++++++- synapse/app/homeserver.py | 11 ++--------- synapse/app/media_repository.py | 9 ++++++++- synapse/app/pusher.py | 9 ++++++++- synapse/app/synchrotron.py | 9 ++++++++- synapse/app/user_dir.py | 9 ++++++++- synapse/metrics/resource.py | 4 ++++ 13 files changed, 97 insertions(+), 18 deletions(-) diff --git a/synapse/app/_base.py b/synapse/app/_base.py index e4318cdfc3ea..a6925ab13917 100644 --- a/synapse/app/_base.py +++ b/synapse/app/_base.py @@ -124,6 +124,19 @@ def quit_with_error(error_string): sys.exit(1) +def listen_metrics(bind_addresses, port): + """ + Start Prometheus metrics server. + """ + from synapse.metrics import RegistryProxy + from prometheus_client import start_http_server + + for host in bind_addresses: + reactor.callInThread(start_http_server, int(port), + addr=host, registry=RegistryProxy) + logger.info("Metrics now reporting on %s:%d", host, port) + + def listen_tcp(bind_addresses, port, factory, backlog=50): """ Create a TCP socket for a port and several addresses diff --git a/synapse/app/appservice.py b/synapse/app/appservice.py index b1efacc9f8ea..23f47be6840e 100644 --- a/synapse/app/appservice.py +++ b/synapse/app/appservice.py @@ -94,6 +94,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/client_reader.py b/synapse/app/client_reader.py index 38b98382c678..eba910c98060 100644 --- a/synapse/app/client_reader.py +++ b/synapse/app/client_reader.py @@ -25,6 +25,7 @@ from synapse.crypto import context_factory from synapse.http.server import JsonResource from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.appservice import SlavedApplicationServiceStore @@ -77,7 +78,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "client": resource = JsonResource(self, canonical_json=False) PublicRoomListRestServlet(self).register(resource) @@ -118,6 +119,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/event_creator.py b/synapse/app/event_creator.py index bd7f3d567952..6ad6b8723904 100644 --- a/synapse/app/event_creator.py +++ b/synapse/app/event_creator.py @@ -25,6 +25,7 @@ from synapse.crypto import context_factory from synapse.http.server import JsonResource from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.account_data import SlavedAccountDataStore @@ -90,7 +91,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "client": resource = JsonResource(self, canonical_json=False) RoomSendEventRestServlet(self).register(resource) @@ -134,6 +135,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/federation_reader.py b/synapse/app/federation_reader.py index 6e10b27b9e23..168d9582baa0 100644 --- a/synapse/app/federation_reader.py +++ b/synapse/app/federation_reader.py @@ -26,6 +26,7 @@ from synapse.crypto import context_factory from synapse.federation.transport.server import TransportLayerServer from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.directory import DirectoryStore @@ -71,7 +72,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "federation": resources.update({ FEDERATION_PREFIX: TransportLayerServer(self), @@ -107,6 +108,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/federation_sender.py b/synapse/app/federation_sender.py index 6f24e32d6d75..9c1c1e4b6bf4 100644 --- a/synapse/app/federation_sender.py +++ b/synapse/app/federation_sender.py @@ -25,6 +25,7 @@ from synapse.crypto import context_factory from synapse.federation import send_queue from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage.deviceinbox import SlavedDeviceInboxStore from synapse.replication.slave.storage.devices import SlavedDeviceStore @@ -89,7 +90,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) root_resource = create_resource_tree(resources, NoResource()) @@ -121,6 +122,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/frontend_proxy.py b/synapse/app/frontend_proxy.py index 0f700ee78603..1d1cc938443d 100644 --- a/synapse/app/frontend_proxy.py +++ b/synapse/app/frontend_proxy.py @@ -29,6 +29,7 @@ RestServlet, parse_json_object_from_request, ) from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.appservice import SlavedApplicationServiceStore @@ -131,7 +132,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "client": resource = JsonResource(self, canonical_json=False) KeyUploadServlet(self).register(resource) @@ -172,6 +173,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index 59022a9c130d..e7f6ddf3e1cf 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -35,7 +35,7 @@ from synapse.http.server import RootRedirect from synapse.http.site import SynapseSite from synapse.metrics import RegistryProxy -from synapse.metrics.resource import METRICS_PREFIX +from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.python_dependencies import CONDITIONAL_REQUIREMENTS, \ check_requirements from synapse.replication.http import ReplicationRestResource, REPLICATION_PREFIX @@ -61,8 +61,6 @@ from twisted.web.server import GzipEncoderFactory from twisted.web.static import File -from prometheus_client.twisted import MetricsResource - logger = logging.getLogger("synapse.app.homeserver") @@ -270,12 +268,7 @@ def start_listening(self): logger.warn( "Metrics listener configured, but collect_metrics is not enabled!") else: - from prometheus_client import start_http_server - for host in listener["bind_addresses"]: - reactor.callInThread(start_http_server, int(listener["port"]), - addr=host, registry=RegistryProxy) - logger.info("Metrics now reporting on %s:%d", - host, listener["port"]) + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/media_repository.py b/synapse/app/media_repository.py index 9c93195f0a85..b468b375f4ec 100644 --- a/synapse/app/media_repository.py +++ b/synapse/app/media_repository.py @@ -27,6 +27,7 @@ from synapse.config.logger import setup_logging from synapse.crypto import context_factory from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.appservice import SlavedApplicationServiceStore @@ -73,7 +74,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "media": media_repo = self.get_media_repository_resource() resources.update({ @@ -114,6 +115,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/pusher.py b/synapse/app/pusher.py index 3912eae48cb8..62f781326548 100644 --- a/synapse/app/pusher.py +++ b/synapse/app/pusher.py @@ -23,6 +23,7 @@ from synapse.config.homeserver import HomeServerConfig from synapse.config.logger import setup_logging from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage.account_data import SlavedAccountDataStore from synapse.replication.slave.storage.events import SlavedEventStore @@ -92,7 +93,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) root_resource = create_resource_tree(resources, NoResource()) @@ -124,6 +125,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/synchrotron.py b/synapse/app/synchrotron.py index c6294a7a0cac..eb4e6732e44c 100644 --- a/synapse/app/synchrotron.py +++ b/synapse/app/synchrotron.py @@ -26,6 +26,7 @@ from synapse.handlers.presence import PresenceHandler, get_interested_parties from synapse.http.server import JsonResource from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.account_data import SlavedAccountDataStore @@ -257,7 +258,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "client": resource = JsonResource(self, canonical_json=False) sync.register_servlets(self, resource) @@ -301,6 +302,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/user_dir.py b/synapse/app/user_dir.py index 53eb3474da79..e39e78027840 100644 --- a/synapse/app/user_dir.py +++ b/synapse/app/user_dir.py @@ -26,6 +26,7 @@ from synapse.crypto import context_factory from synapse.http.server import JsonResource from synapse.http.site import SynapseSite +from synapse.metrics import RegistryProxy from synapse.metrics.resource import METRICS_PREFIX, MetricsResource from synapse.replication.slave.storage._base import BaseSlavedStore from synapse.replication.slave.storage.appservice import SlavedApplicationServiceStore @@ -105,7 +106,7 @@ def _listen_http(self, listener_config): for res in listener_config["resources"]: for name in res["names"]: if name == "metrics": - resources[METRICS_PREFIX] = MetricsResource(self) + resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) elif name == "client": resource = JsonResource(self, canonical_json=False) user_directory.register_servlets(self, resource) @@ -146,6 +147,12 @@ def start_listening(self, listeners): globals={"hs": self}, ) ) + elif listener["type"] == "metrics": + if not config.enable_metrics: + logger.warn( + "Metrics listener configured, but collect_metrics is not enabled!") + else: + _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/metrics/resource.py b/synapse/metrics/resource.py index 7996e6ab669b..9789359077cb 100644 --- a/synapse/metrics/resource.py +++ b/synapse/metrics/resource.py @@ -13,4 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from prometheus_client.twisted import MetricsResource + METRICS_PREFIX = "/_synapse/metrics" + +__all__ = ["MetricsResource", "METRICS_PREFIX"] From f551ac3923648899451f2a9e80918097404f5197 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 28 May 2018 23:29:37 +1000 Subject: [PATCH 08/12] just have quad zero --- docs/metrics-howto.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/metrics-howto.rst b/docs/metrics-howto.rst index aa0fe4e21e4a..982135f75958 100644 --- a/docs/metrics-howto.rst +++ b/docs/metrics-howto.rst @@ -34,7 +34,6 @@ How to monitor Synapse metrics using Prometheus - type: metrics port: 9000 bind_addresses: - - '::' - '0.0.0.0' For both options, you will need to ensure that ``enable_metrics`` is set to From c157c59c799ea4e00c21764083a4cc21075efe78 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Mon, 28 May 2018 23:38:20 +1000 Subject: [PATCH 09/12] fix pep8 :) --- synapse/app/appservice.py | 9 +++++---- synapse/app/client_reader.py | 10 +++++----- synapse/app/event_creator.py | 9 +++++---- synapse/app/federation_reader.py | 9 +++++---- synapse/app/federation_sender.py | 9 +++++---- synapse/app/frontend_proxy.py | 9 +++++---- synapse/app/homeserver.py | 9 +++++---- synapse/app/media_repository.py | 9 +++++---- synapse/app/pusher.py | 9 +++++---- synapse/app/synchrotron.py | 9 +++++---- synapse/app/user_dir.py | 9 +++++---- 11 files changed, 55 insertions(+), 45 deletions(-) diff --git a/synapse/app/appservice.py b/synapse/app/appservice.py index 23f47be6840e..dd114dee0784 100644 --- a/synapse/app/appservice.py +++ b/synapse/app/appservice.py @@ -95,11 +95,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/client_reader.py b/synapse/app/client_reader.py index eba910c98060..85dada7f9f3b 100644 --- a/synapse/app/client_reader.py +++ b/synapse/app/client_reader.py @@ -120,12 +120,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) - + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/event_creator.py b/synapse/app/event_creator.py index 6ad6b8723904..5ca77c0f1af3 100644 --- a/synapse/app/event_creator.py +++ b/synapse/app/event_creator.py @@ -136,11 +136,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/federation_reader.py b/synapse/app/federation_reader.py index 168d9582baa0..2a1995d0cd7f 100644 --- a/synapse/app/federation_reader.py +++ b/synapse/app/federation_reader.py @@ -109,11 +109,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/federation_sender.py b/synapse/app/federation_sender.py index 9c1c1e4b6bf4..81ad574043a9 100644 --- a/synapse/app/federation_sender.py +++ b/synapse/app/federation_sender.py @@ -123,11 +123,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/frontend_proxy.py b/synapse/app/frontend_proxy.py index 1d1cc938443d..5a164a7a95fa 100644 --- a/synapse/app/frontend_proxy.py +++ b/synapse/app/frontend_proxy.py @@ -174,11 +174,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py index e7f6ddf3e1cf..51fc3645d53f 100755 --- a/synapse/app/homeserver.py +++ b/synapse/app/homeserver.py @@ -264,11 +264,12 @@ def start_listening(self): "before", "shutdown", server_listener.stopListening, ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/media_repository.py b/synapse/app/media_repository.py index b468b375f4ec..006bba80a8f3 100644 --- a/synapse/app/media_repository.py +++ b/synapse/app/media_repository.py @@ -116,11 +116,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/pusher.py b/synapse/app/pusher.py index 62f781326548..64df47f9cc01 100644 --- a/synapse/app/pusher.py +++ b/synapse/app/pusher.py @@ -126,11 +126,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/synchrotron.py b/synapse/app/synchrotron.py index eb4e6732e44c..6808d6d3e042 100644 --- a/synapse/app/synchrotron.py +++ b/synapse/app/synchrotron.py @@ -303,11 +303,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) diff --git a/synapse/app/user_dir.py b/synapse/app/user_dir.py index e39e78027840..ada1c13cec43 100644 --- a/synapse/app/user_dir.py +++ b/synapse/app/user_dir.py @@ -148,11 +148,12 @@ def start_listening(self, listeners): ) ) elif listener["type"] == "metrics": - if not config.enable_metrics: - logger.warn( - "Metrics listener configured, but collect_metrics is not enabled!") + if not self.get_config().enable_metrics: + logger.warn(("Metrics listener configured, but " + "collect_metrics is not enabled!")) else: - _base.listen_metrics(listener["bind_addresses"], listener["port"]) + _base.listen_metrics(listener["bind_addresses"], + listener["port"]) else: logger.warn("Unrecognized listener type: %s", listener["type"]) From 644b62d259f3faa53bc6a76579426d5171466a1b Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 31 May 2018 13:22:38 +1000 Subject: [PATCH 10/12] put back the old metrics port option for compatibility --- synapse/config/server.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/synapse/config/server.py b/synapse/config/server.py index adcb469b776c..8f0b6d1f2820 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -136,6 +136,21 @@ def read_config(self, config): "type": "manhole", }) + metrics_port = config.get("metrics_port") + if metrics_port: + self.listeners.append({ + "port": metrics_port, + "bind_addresses": [config.get("metrics_bind_host", "127.0.0.1")], + "tls": False, + "type": "http", + "resources": [ + { + "names": ["metrics"], + "compress": False, + }, + ] + }) + def default_config(self, server_name, **kwargs): if ":" in server_name: bind_port = int(server_name.split(":")[1]) From 357033caf1080c68e2cb85fd2a7f7ed233567274 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 31 May 2018 13:35:48 +1000 Subject: [PATCH 11/12] add a warning --- synapse/config/server.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/synapse/config/server.py b/synapse/config/server.py index 8f0b6d1f2820..968ecd9ea089 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -14,8 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging + from ._base import Config, ConfigError +logger = logging.Logger(__name__) + class ServerConfig(Config): @@ -138,6 +142,12 @@ def read_config(self, config): metrics_port = config.get("metrics_port") if metrics_port: + logger.warn( + ("The metrics_port configuration option is deprecated in Synapse 0.31 " + "in favour of a listener. Please see " + "http://github.com/matrix-org/synapse/blob/master/docs/metrics-howto.rst" + " on how to configure the new listener.")) + self.listeners.append({ "port": metrics_port, "bind_addresses": [config.get("metrics_bind_host", "127.0.0.1")], From ce9b11232b7812bb5bc7b2bef22d75c1713e5b48 Mon Sep 17 00:00:00 2001 From: Amber Brown Date: Thu, 31 May 2018 15:02:00 +1000 Subject: [PATCH 12/12] make this 0.31.0 --- docs/metrics-howto.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/metrics-howto.rst b/docs/metrics-howto.rst index 982135f75958..25e06bca5869 100644 --- a/docs/metrics-howto.rst +++ b/docs/metrics-howto.rst @@ -56,7 +56,7 @@ How to monitor Synapse metrics using Prometheus Restart Prometheus. -Removal of deprecated metrics & time based counters becoming histograms in 0.30.0 +Removal of deprecated metrics & time based counters becoming histograms in 0.31.0 --------------------------------------------------------------------------------- The duplicated metrics deprecated in Synapse 0.27.0 have been removed.