Exemplo n.º 1
0
    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"])
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
 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.")
Exemplo n.º 4
0
 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."
         )
Exemplo n.º 5
0
    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"])
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
    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