def start_listening(self, listeners): config = self.get_config() for listener in listeners: if listener["type"] == "http": self._listening_services.extend(self._listener_http(config, listener)) elif listener["type"] == "manhole": listen_tcp( listener["bind_addresses"], listener["port"], manhole( username="******", password="******", globals={"hs": self} ), ) elif listener["type"] == "replication": services = listen_tcp( listener["bind_addresses"], listener["port"], ReplicationStreamProtocolFactory(self), ) for s in services: reactor.addSystemEventTrigger("before", "shutdown", s.stopListening) elif listener["type"] == "metrics": if not self.get_config().enable_metrics: logger.warning( ( "Metrics listener configured, but " "enable_metrics is not True!" ) ) else: _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warning("Unrecognized listener type: %s", listener["type"])
def start_listening(self): if self.config.redis_enabled: # If redis is enabled we connect via the replication command handler # in the same way as the workers (since we're effectively a client # rather than a server). self.get_tcp_replication().start_replication(self) for listener in self.config.server.listeners: if listener.type == "http": self._listening_services.extend( self._listener_http(self.config, listener)) elif listener.type == "manhole": _base.listen_manhole(listener.bind_addresses, listener.port, manhole_globals={"hs": self}) elif listener.type == "replication": services = listen_tcp( listener.bind_addresses, listener.port, ReplicationStreamProtocolFactory(self), ) for s in services: reactor.addSystemEventTrigger("before", "shutdown", s.stopListening) elif listener.type == "metrics": if not self.config.enable_metrics: logger.warning("Metrics listener configured, but " "enable_metrics is not True!") else: _base.listen_metrics(listener.bind_addresses, listener.port) else: # this shouldn't happen, as the listener type should have been checked # during parsing logger.warning("Unrecognized listener type: %s", listener.type)
def performance_stats_init(): try: process = psutil.Process() # Ensure we can fetch both, and make the initial request for cpu_percent # so the next request will use this as the initial point. process.memory_info().rss process.cpu_percent(interval=None) logger.info("report_stats can use psutil") stats_process.append(process) except (AttributeError): logger.warning( "Unable to read memory/cpu stats. Disabling reporting.")
def performance_stats_init(): try: process = psutil.Process() # Ensure we can fetch both, and make the initial request for cpu_percent # so the next request will use this as the initial point. process.memory_info().rss process.cpu_percent(interval=None) logger.info("report_stats can use psutil") stats_process.append(process) except (AttributeError): logger.warning( "Unable to read memory/cpu stats. Disabling reporting." )
def start_listening(self, listeners): config = self.get_config() if config.redis_enabled: # If redis is enabled we connect via the replication command handler # in the same way as the workers (since we're effectively a client # rather than a server). self.get_tcp_replication().start_replication(self) for listener in listeners: if listener["type"] == "http": self._listening_services.extend(self._listener_http(config, listener)) elif listener["type"] == "manhole": listen_tcp( listener["bind_addresses"], listener["port"], manhole( username="******", password="******", globals={"hs": self} ), ) elif listener["type"] == "replication": services = listen_tcp( listener["bind_addresses"], listener["port"], ReplicationStreamProtocolFactory(self), ) for s in services: reactor.addSystemEventTrigger("before", "shutdown", s.stopListening) elif listener["type"] == "metrics": if not self.get_config().enable_metrics: logger.warning( ( "Metrics listener configured, but " "enable_metrics is not True!" ) ) else: _base.listen_metrics(listener["bind_addresses"], listener["port"]) else: logger.warning("Unrecognized listener type: %s", listener["type"])
def _configure_named_resource(self, name, compress=False): """Build a resource map for a named resource Args: name (str): named resource: one of "client", "federation", etc compress (bool): whether to enable gzip compression for this resource Returns: dict[str, Resource]: map from path to HTTP resource """ resources = {} if name == "client": client_resource = ClientRestResource(self) if compress: client_resource = gz_wrap(client_resource) resources.update({ "/_matrix/client/api/v1": client_resource, "/_matrix/client/r0": client_resource, "/_matrix/client/unstable": client_resource, "/_matrix/client/v2_alpha": client_resource, "/_matrix/client/versions": client_resource, "/.well-known/matrix/client": WellKnownResource(self), "/_synapse/admin": AdminRestResource(self), "/_synapse/client/pick_username": pick_username_resource(self), "/_synapse/client/pick_idp": PickIdpResource(self), }) if self.get_config().oidc_enabled: from synapse.rest.oidc import OIDCResource resources["/_synapse/oidc"] = OIDCResource(self) if self.get_config().saml2_enabled: from synapse.rest.saml2 import SAML2Resource resources["/_matrix/saml2"] = SAML2Resource(self) if self.get_config( ).threepid_behaviour_email == ThreepidBehaviour.LOCAL: from synapse.rest.synapse.client.password_reset import ( PasswordResetSubmitTokenResource, ) resources[ "/_synapse/client/password_reset/email/submit_token"] = PasswordResetSubmitTokenResource( self) if name == "consent": from synapse.rest.consent.consent_resource import ConsentResource consent_resource = ConsentResource(self) if compress: consent_resource = gz_wrap(consent_resource) resources.update({"/_matrix/consent": consent_resource}) if name == "federation": resources.update({FEDERATION_PREFIX: TransportLayerServer(self)}) if name == "openid": resources.update({ FEDERATION_PREFIX: TransportLayerServer(self, servlet_groups=["openid"]) }) if name in ["static", "client"]: resources.update({ STATIC_PREFIX: StaticResource( os.path.join(os.path.dirname(synapse.__file__), "static")) }) if name in ["media", "federation", "client"]: if self.get_config().enable_media_repo: media_repo = self.get_media_repository_resource() resources.update({ MEDIA_PREFIX: media_repo, LEGACY_MEDIA_PREFIX: media_repo }) elif name == "media": raise ConfigError( "'media' resource conflicts with enable_media_repo=False") if name in ["keys", "federation"]: resources[SERVER_KEY_V2_PREFIX] = KeyApiV2Resource(self) if name == "webclient": webclient_loc = self.get_config().web_client_location if webclient_loc is None: logger.warning( "Not enabling webclient resource, as web_client_location is unset." ) elif webclient_loc.startswith( "http://") or webclient_loc.startswith("https://"): resources[WEB_CLIENT_PREFIX] = RootRedirect(webclient_loc) else: logger.warning( "Running webclient on the same domain is not recommended: " "https://github.com/matrix-org/synapse#security-note - " "after you move webclient to different host you can set " "web_client_location to its full URL to enable redirection." ) # GZip is disabled here due to # https://twistedmatrix.com/trac/ticket/7678 resources[WEB_CLIENT_PREFIX] = File(webclient_loc) if name == "metrics" and self.get_config().enable_metrics: resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) if name == "replication": resources[REPLICATION_PREFIX] = ReplicationRestResource(self) return resources
def _configure_named_resource(self, name, compress=False): """Build a resource map for a named resource Args: name (str): named resource: one of "client", "federation", etc compress (bool): whether to enable gzip compression for this resource Returns: dict[str, Resource]: map from path to HTTP resource """ resources = {} if name == "client": client_resource = ClientRestResource(self) if compress: client_resource = gz_wrap(client_resource) resources.update({ "/_matrix/client/api/v1": client_resource, "/_matrix/client/r0": client_resource, "/_matrix/client/unstable": client_resource, "/_matrix/client/v2_alpha": client_resource, "/_matrix/client/versions": client_resource, "/.well-known/matrix/client": WellKnownResource(self), }) if self.get_config().saml2_enabled: from synapse.rest.saml2 import SAML2Resource resources["/_matrix/saml2"] = SAML2Resource(self) if name == "consent": from synapse.rest.consent.consent_resource import ConsentResource consent_resource = ConsentResource(self) if compress: consent_resource = gz_wrap(consent_resource) resources.update({ "/_matrix/consent": consent_resource, }) if name == "federation": resources.update({ FEDERATION_PREFIX: TransportLayerServer(self), }) if name == "openid": resources.update({ FEDERATION_PREFIX: TransportLayerServer(self, servlet_groups=["openid"]), }) if name in ["static", "client"]: resources.update({ STATIC_PREFIX: File(os.path.join(os.path.dirname(synapse.__file__), "static")), }) if name in ["media", "federation", "client"]: if self.get_config().enable_media_repo: media_repo = self.get_media_repository_resource() resources.update({ MEDIA_PREFIX: media_repo, LEGACY_MEDIA_PREFIX: media_repo, CONTENT_REPO_PREFIX: ContentRepoResource(self, self.config.uploads_path), }) elif name == "media": raise ConfigError( "'media' resource conflicts with enable_media_repo=False", ) if name in ["keys", "federation"]: resources[SERVER_KEY_V2_PREFIX] = KeyApiV2Resource(self) if name == "webclient": webclient_path = self.get_config().web_client_location if webclient_path is None: logger.warning( "Not enabling webclient resource, as web_client_location is unset." ) else: # GZip is disabled here due to # https://twistedmatrix.com/trac/ticket/7678 resources[WEB_CLIENT_PREFIX] = File(webclient_path) if name == "metrics" and self.get_config().enable_metrics: resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) if name == "replication": resources[REPLICATION_PREFIX] = ReplicationRestResource(self) return resources
def phone_stats_home(hs, stats, stats_process=_stats_process): logger.info("Gathering stats for reporting") now = int(hs.get_clock().time()) uptime = int(now - hs.start_time) if uptime < 0: uptime = 0 stats["homeserver"] = hs.config.server_name stats["server_context"] = hs.config.server_context stats["timestamp"] = now stats["uptime_seconds"] = uptime version = sys.version_info stats["python_version"] = "{}.{}.{}".format( version.major, version.minor, version.micro ) stats["total_users"] = yield hs.get_datastore().count_all_users() total_nonbridged_users = yield hs.get_datastore().count_nonbridged_users() stats["total_nonbridged_users"] = total_nonbridged_users daily_user_type_results = yield hs.get_datastore().count_daily_user_type() for name, count in iteritems(daily_user_type_results): stats["daily_user_type_" + name] = count room_count = yield hs.get_datastore().get_room_count() stats["total_room_count"] = room_count stats["daily_active_users"] = yield hs.get_datastore().count_daily_users() stats["monthly_active_users"] = yield hs.get_datastore().count_monthly_users() stats["daily_active_rooms"] = yield hs.get_datastore().count_daily_active_rooms() stats["daily_messages"] = yield hs.get_datastore().count_daily_messages() r30_results = yield hs.get_datastore().count_r30_users() for name, count in iteritems(r30_results): stats["r30_users_" + name] = count daily_sent_messages = yield hs.get_datastore().count_daily_sent_messages() stats["daily_sent_messages"] = daily_sent_messages stats["cache_factor"] = CACHE_SIZE_FACTOR stats["event_cache_size"] = hs.config.event_cache_size # # Performance statistics # old = stats_process[0] new = (now, resource.getrusage(resource.RUSAGE_SELF)) stats_process[0] = new # Get RSS in bytes stats["memory_rss"] = new[1].ru_maxrss # Get CPU time in % of a single core, not % of all cores used_cpu_time = (new[1].ru_utime + new[1].ru_stime) - ( old[1].ru_utime + old[1].ru_stime ) if used_cpu_time == 0 or new[0] == old[0]: stats["cpu_average"] = 0 else: stats["cpu_average"] = math.floor(used_cpu_time / (new[0] - old[0]) * 100) # # Database version # stats["database_engine"] = hs.database_engine.module.__name__ stats["database_server_version"] = hs.database_engine.server_version logger.info("Reporting stats to %s: %s" % (hs.config.report_stats_endpoint, stats)) try: yield hs.get_proxied_http_client().put_json( hs.config.report_stats_endpoint, stats ) except Exception as e: logger.warning("Error reporting stats: %s", e)
def _configure_named_resource(self, name, compress=False): """Build a resource map for a named resource Args: name (str): named resource: one of "client", "federation", etc compress (bool): whether to enable gzip compression for this resource Returns: dict[str, Resource]: map from path to HTTP resource """ resources = {} if name == "client": client_resource = ClientRestResource(self) if compress: client_resource = gz_wrap(client_resource) resources.update({ "/_matrix/client/api/v1": client_resource, "/_matrix/client/r0": client_resource, "/_matrix/client/unstable": client_resource, "/_matrix/client/v2_alpha": client_resource, "/_matrix/client/versions": client_resource, "/.well-known/matrix/client": WellKnownResource(self), "/_synapse/admin": AdminRestResource(self), }) if self.get_config().saml2_enabled: from synapse.rest.saml2 import SAML2Resource resources["/_matrix/saml2"] = SAML2Resource(self) if name == "consent": from synapse.rest.consent.consent_resource import ConsentResource consent_resource = ConsentResource(self) if compress: consent_resource = gz_wrap(consent_resource) resources.update({ "/_matrix/consent": consent_resource, }) if name == "federation": resources.update({ FEDERATION_PREFIX: TransportLayerServer(self), }) if name == "openid": resources.update({ FEDERATION_PREFIX: TransportLayerServer(self, servlet_groups=["openid"]), }) if name in ["static", "client"]: resources.update({ STATIC_PREFIX: File( os.path.join(os.path.dirname(synapse.__file__), "static") ), }) if name in ["media", "federation", "client"]: if self.get_config().enable_media_repo: media_repo = self.get_media_repository_resource() resources.update({ MEDIA_PREFIX: media_repo, LEGACY_MEDIA_PREFIX: media_repo, CONTENT_REPO_PREFIX: ContentRepoResource( self, self.config.uploads_path ), }) elif name == "media": raise ConfigError( "'media' resource conflicts with enable_media_repo=False", ) if name in ["keys", "federation"]: resources[SERVER_KEY_V2_PREFIX] = KeyApiV2Resource(self) if name == "webclient": webclient_path = self.get_config().web_client_location if webclient_path is None: logger.warning( "Not enabling webclient resource, as web_client_location is unset." ) else: # GZip is disabled here due to # https://twistedmatrix.com/trac/ticket/7678 resources[WEB_CLIENT_PREFIX] = File(webclient_path) if name == "metrics" and self.get_config().enable_metrics: resources[METRICS_PREFIX] = MetricsResource(RegistryProxy) if name == "replication": resources[REPLICATION_PREFIX] = ReplicationRestResource(self) return resources