Prometheus metrics for logins and registrations (#9511)
Add prom metrics for number of users successfully registering and logging in, by SSO provider.pull/9550/head
parent
7eb6e39a8f
commit
df425c2c63
|
@ -0,0 +1 @@
|
||||||
|
Add prometheus metrics for number of users successfully registering and logging in.
|
|
@ -18,6 +18,8 @@
|
||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple
|
from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple
|
||||||
|
|
||||||
|
from prometheus_client import Counter
|
||||||
|
|
||||||
from synapse import types
|
from synapse import types
|
||||||
from synapse.api.constants import MAX_USERID_LENGTH, EventTypes, JoinRules, LoginType
|
from synapse.api.constants import MAX_USERID_LENGTH, EventTypes, JoinRules, LoginType
|
||||||
from synapse.api.errors import AuthError, Codes, ConsentNotGivenError, SynapseError
|
from synapse.api.errors import AuthError, Codes, ConsentNotGivenError, SynapseError
|
||||||
|
@ -41,6 +43,19 @@ if TYPE_CHECKING:
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
registration_counter = Counter(
|
||||||
|
"synapse_user_registrations_total",
|
||||||
|
"Number of new users registered (since restart)",
|
||||||
|
["guest", "shadow_banned", "auth_provider"],
|
||||||
|
)
|
||||||
|
|
||||||
|
login_counter = Counter(
|
||||||
|
"synapse_user_logins_total",
|
||||||
|
"Number of user logins (since restart)",
|
||||||
|
["guest", "auth_provider"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class RegistrationHandler(BaseHandler):
|
class RegistrationHandler(BaseHandler):
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__(hs)
|
super().__init__(hs)
|
||||||
|
@ -156,6 +171,7 @@ class RegistrationHandler(BaseHandler):
|
||||||
bind_emails: Iterable[str] = [],
|
bind_emails: Iterable[str] = [],
|
||||||
by_admin: bool = False,
|
by_admin: bool = False,
|
||||||
user_agent_ips: Optional[List[Tuple[str, str]]] = None,
|
user_agent_ips: Optional[List[Tuple[str, str]]] = None,
|
||||||
|
auth_provider_id: Optional[str] = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Registers a new client on the server.
|
"""Registers a new client on the server.
|
||||||
|
|
||||||
|
@ -181,8 +197,10 @@ class RegistrationHandler(BaseHandler):
|
||||||
admin api, otherwise False.
|
admin api, otherwise False.
|
||||||
user_agent_ips: Tuples of IP addresses and user-agents used
|
user_agent_ips: Tuples of IP addresses and user-agents used
|
||||||
during the registration process.
|
during the registration process.
|
||||||
|
auth_provider_id: The SSO IdP the user used, if any (just used for the
|
||||||
|
prometheus metrics).
|
||||||
Returns:
|
Returns:
|
||||||
The registere user_id.
|
The registered user_id.
|
||||||
Raises:
|
Raises:
|
||||||
SynapseError if there was a problem registering.
|
SynapseError if there was a problem registering.
|
||||||
"""
|
"""
|
||||||
|
@ -280,6 +298,12 @@ class RegistrationHandler(BaseHandler):
|
||||||
# if user id is taken, just generate another
|
# if user id is taken, just generate another
|
||||||
fail_count += 1
|
fail_count += 1
|
||||||
|
|
||||||
|
registration_counter.labels(
|
||||||
|
guest=make_guest,
|
||||||
|
shadow_banned=shadow_banned,
|
||||||
|
auth_provider=(auth_provider_id or ""),
|
||||||
|
).inc()
|
||||||
|
|
||||||
if not self.hs.config.user_consent_at_registration:
|
if not self.hs.config.user_consent_at_registration:
|
||||||
if not self.hs.config.auto_join_rooms_for_guests and make_guest:
|
if not self.hs.config.auto_join_rooms_for_guests and make_guest:
|
||||||
logger.info(
|
logger.info(
|
||||||
|
@ -638,6 +662,7 @@ class RegistrationHandler(BaseHandler):
|
||||||
initial_display_name: Optional[str],
|
initial_display_name: Optional[str],
|
||||||
is_guest: bool = False,
|
is_guest: bool = False,
|
||||||
is_appservice_ghost: bool = False,
|
is_appservice_ghost: bool = False,
|
||||||
|
auth_provider_id: Optional[str] = None,
|
||||||
) -> Tuple[str, str]:
|
) -> Tuple[str, str]:
|
||||||
"""Register a device for a user and generate an access token.
|
"""Register a device for a user and generate an access token.
|
||||||
|
|
||||||
|
@ -648,7 +673,8 @@ class RegistrationHandler(BaseHandler):
|
||||||
device_id: The device ID to check, or None to generate a new one.
|
device_id: The device ID to check, or None to generate a new one.
|
||||||
initial_display_name: An optional display name for the device.
|
initial_display_name: An optional display name for the device.
|
||||||
is_guest: Whether this is a guest account
|
is_guest: Whether this is a guest account
|
||||||
|
auth_provider_id: The SSO IdP the user used, if any (just used for the
|
||||||
|
prometheus metrics).
|
||||||
Returns:
|
Returns:
|
||||||
Tuple of device ID and access token
|
Tuple of device ID and access token
|
||||||
"""
|
"""
|
||||||
|
@ -687,6 +713,11 @@ class RegistrationHandler(BaseHandler):
|
||||||
is_appservice_ghost=is_appservice_ghost,
|
is_appservice_ghost=is_appservice_ghost,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
login_counter.labels(
|
||||||
|
guest=is_guest,
|
||||||
|
auth_provider=(auth_provider_id or ""),
|
||||||
|
).inc()
|
||||||
|
|
||||||
return (registered_device_id, access_token)
|
return (registered_device_id, access_token)
|
||||||
|
|
||||||
async def post_registration_actions(
|
async def post_registration_actions(
|
||||||
|
|
|
@ -606,6 +606,7 @@ class SsoHandler:
|
||||||
default_display_name=attributes.display_name,
|
default_display_name=attributes.display_name,
|
||||||
bind_emails=attributes.emails,
|
bind_emails=attributes.emails,
|
||||||
user_agent_ips=[(user_agent, ip_address)],
|
user_agent_ips=[(user_agent, ip_address)],
|
||||||
|
auth_provider_id=auth_provider_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
await self._store.record_user_external_id(
|
await self._store.record_user_external_id(
|
||||||
|
|
|
@ -219,6 +219,7 @@ class LoginRestServlet(RestServlet):
|
||||||
callback: Optional[Callable[[Dict[str, str]], Awaitable[None]]] = None,
|
callback: Optional[Callable[[Dict[str, str]], Awaitable[None]]] = None,
|
||||||
create_non_existent_users: bool = False,
|
create_non_existent_users: bool = False,
|
||||||
ratelimit: bool = True,
|
ratelimit: bool = True,
|
||||||
|
auth_provider_id: Optional[str] = None,
|
||||||
) -> Dict[str, str]:
|
) -> Dict[str, str]:
|
||||||
"""Called when we've successfully authed the user and now need to
|
"""Called when we've successfully authed the user and now need to
|
||||||
actually login them in (e.g. create devices). This gets called on
|
actually login them in (e.g. create devices). This gets called on
|
||||||
|
@ -234,6 +235,8 @@ class LoginRestServlet(RestServlet):
|
||||||
create_non_existent_users: Whether to create the user if they don't
|
create_non_existent_users: Whether to create the user if they don't
|
||||||
exist. Defaults to False.
|
exist. Defaults to False.
|
||||||
ratelimit: Whether to ratelimit the login request.
|
ratelimit: Whether to ratelimit the login request.
|
||||||
|
auth_provider_id: The SSO IdP the user used, if any (just used for the
|
||||||
|
prometheus metrics).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
result: Dictionary of account information after successful login.
|
result: Dictionary of account information after successful login.
|
||||||
|
@ -256,7 +259,7 @@ class LoginRestServlet(RestServlet):
|
||||||
device_id = login_submission.get("device_id")
|
device_id = login_submission.get("device_id")
|
||||||
initial_display_name = login_submission.get("initial_device_display_name")
|
initial_display_name = login_submission.get("initial_device_display_name")
|
||||||
device_id, access_token = await self.registration_handler.register_device(
|
device_id, access_token = await self.registration_handler.register_device(
|
||||||
user_id, device_id, initial_display_name
|
user_id, device_id, initial_display_name, auth_provider_id=auth_provider_id
|
||||||
)
|
)
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
|
@ -286,7 +289,10 @@ class LoginRestServlet(RestServlet):
|
||||||
res = await auth_handler.validate_short_term_login_token(token)
|
res = await auth_handler.validate_short_term_login_token(token)
|
||||||
|
|
||||||
return await self._complete_login(
|
return await self._complete_login(
|
||||||
res.user_id, login_submission, self.auth_handler._sso_login_callback
|
res.user_id,
|
||||||
|
login_submission,
|
||||||
|
self.auth_handler._sso_login_callback,
|
||||||
|
auth_provider_id=res.auth_provider_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _do_jwt_login(self, login_submission: JsonDict) -> Dict[str, str]:
|
async def _do_jwt_login(self, login_submission: JsonDict) -> Dict[str, str]:
|
||||||
|
|
Loading…
Reference in New Issue