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
|
||||
from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple
|
||||
|
||||
from prometheus_client import Counter
|
||||
|
||||
from synapse import types
|
||||
from synapse.api.constants import MAX_USERID_LENGTH, EventTypes, JoinRules, LoginType
|
||||
from synapse.api.errors import AuthError, Codes, ConsentNotGivenError, SynapseError
|
||||
|
@ -41,6 +43,19 @@ if TYPE_CHECKING:
|
|||
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):
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
super().__init__(hs)
|
||||
|
@ -156,6 +171,7 @@ class RegistrationHandler(BaseHandler):
|
|||
bind_emails: Iterable[str] = [],
|
||||
by_admin: bool = False,
|
||||
user_agent_ips: Optional[List[Tuple[str, str]]] = None,
|
||||
auth_provider_id: Optional[str] = None,
|
||||
) -> str:
|
||||
"""Registers a new client on the server.
|
||||
|
||||
|
@ -181,8 +197,10 @@ class RegistrationHandler(BaseHandler):
|
|||
admin api, otherwise False.
|
||||
user_agent_ips: Tuples of IP addresses and user-agents used
|
||||
during the registration process.
|
||||
auth_provider_id: The SSO IdP the user used, if any (just used for the
|
||||
prometheus metrics).
|
||||
Returns:
|
||||
The registere user_id.
|
||||
The registered user_id.
|
||||
Raises:
|
||||
SynapseError if there was a problem registering.
|
||||
"""
|
||||
|
@ -280,6 +298,12 @@ class RegistrationHandler(BaseHandler):
|
|||
# if user id is taken, just generate another
|
||||
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.auto_join_rooms_for_guests and make_guest:
|
||||
logger.info(
|
||||
|
@ -638,6 +662,7 @@ class RegistrationHandler(BaseHandler):
|
|||
initial_display_name: Optional[str],
|
||||
is_guest: bool = False,
|
||||
is_appservice_ghost: bool = False,
|
||||
auth_provider_id: Optional[str] = None,
|
||||
) -> Tuple[str, str]:
|
||||
"""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.
|
||||
initial_display_name: An optional display name for the device.
|
||||
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:
|
||||
Tuple of device ID and access token
|
||||
"""
|
||||
|
@ -687,6 +713,11 @@ class RegistrationHandler(BaseHandler):
|
|||
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)
|
||||
|
||||
async def post_registration_actions(
|
||||
|
|
|
@ -606,6 +606,7 @@ class SsoHandler:
|
|||
default_display_name=attributes.display_name,
|
||||
bind_emails=attributes.emails,
|
||||
user_agent_ips=[(user_agent, ip_address)],
|
||||
auth_provider_id=auth_provider_id,
|
||||
)
|
||||
|
||||
await self._store.record_user_external_id(
|
||||
|
|
|
@ -219,6 +219,7 @@ class LoginRestServlet(RestServlet):
|
|||
callback: Optional[Callable[[Dict[str, str]], Awaitable[None]]] = None,
|
||||
create_non_existent_users: bool = False,
|
||||
ratelimit: bool = True,
|
||||
auth_provider_id: Optional[str] = None,
|
||||
) -> Dict[str, str]:
|
||||
"""Called when we've successfully authed the user and now need to
|
||||
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
|
||||
exist. Defaults to False.
|
||||
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:
|
||||
result: Dictionary of account information after successful login.
|
||||
|
@ -256,7 +259,7 @@ class LoginRestServlet(RestServlet):
|
|||
device_id = login_submission.get("device_id")
|
||||
initial_display_name = login_submission.get("initial_device_display_name")
|
||||
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 = {
|
||||
|
@ -286,7 +289,10 @@ class LoginRestServlet(RestServlet):
|
|||
res = await auth_handler.validate_short_term_login_token(token)
|
||||
|
||||
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]:
|
||||
|
|
Loading…
Reference in New Issue