From 19295eef46e9155d78c71146110a4815ae84f832 Mon Sep 17 00:00:00 2001 From: Chris Eager Date: Wed, 17 Mar 2021 13:13:18 -0500 Subject: [PATCH] Add dimensional metrics for account creation and verification --- .../controllers/AccountController.java | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java index 967cf471f..34adab367 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -12,6 +12,8 @@ import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.annotation.Timed; import com.google.common.annotations.VisibleForTesting; import io.dropwizard.auth.Auth; +import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.Tag; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; @@ -34,8 +36,6 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import io.micrometer.core.instrument.Metrics; -import io.micrometer.core.instrument.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials; @@ -57,6 +57,7 @@ import org.whispersystems.textsecuregcm.entities.GcmRegistrationId; import org.whispersystems.textsecuregcm.entities.RegistrationLock; import org.whispersystems.textsecuregcm.entities.RegistrationLockFailure; import org.whispersystems.textsecuregcm.limits.RateLimiters; +import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil; import org.whispersystems.textsecuregcm.push.APNSender; import org.whispersystems.textsecuregcm.push.ApnMessage; import org.whispersystems.textsecuregcm.push.GCMSender; @@ -94,11 +95,13 @@ public class AccountController { private final Meter captchaFailureMeter = metricRegistry.meter(name(AccountController.class, "captcha_failure" )); private static final String PUSH_CHALLENGE_COUNTER_NAME = name(AccountController.class, "pushChallenge"); + private static final String ACCOUNT_CREATE_COUNTER_NAME = name(AccountController.class, "create"); + private static final String ACCOUNT_VERIFY_COUNTER_NAME = name(AccountController.class, "verify"); private static final String CHALLENGE_PRESENT_TAG_NAME = "present"; private static final String CHALLENGE_MATCH_TAG_NAME = "matches"; private static final String COUNTRY_CODE_TAG_NAME = "countryCode"; - + private static final String VERFICATION_TRANSPORT_TAG_NAME = "transport"; private final PendingAccountsManager pendingAccounts; private final AccountsManager accounts; @@ -185,7 +188,7 @@ public class AccountController { public Response createAccount(@PathParam("transport") String transport, @PathParam("number") String number, @HeaderParam("X-Forwarded-For") String forwardedFor, - @HeaderParam("User-Agent") List userAgent, + @HeaderParam("User-Agent") String userAgent, @HeaderParam("Accept-Language") Optional acceptLanguage, @QueryParam("client") Optional client, @QueryParam("captcha") Optional captcha, @@ -262,6 +265,15 @@ public class AccountController { metricRegistry.meter(name(AccountController.class, "create", Util.getCountryCode(number))).mark(); + { + final List tags = new ArrayList<>(); + tags.add(Tag.of(COUNTRY_CODE_TAG_NAME, Util.getCountryCode(number))); + tags.add(Tag.of(VERFICATION_TRANSPORT_TAG_NAME, transport)); + tags.add(UserAgentTagUtil.getPlatformTag(userAgent)); + + Metrics.counter(ACCOUNT_CREATE_COUNTER_NAME, tags).increment(); + } + return Response.ok().build(); } @@ -272,7 +284,8 @@ public class AccountController { @Path("/code/{verification_code}") public AccountCreationResult verifyAccount(@PathParam("verification_code") String verificationCode, @HeaderParam("Authorization") String authorizationHeader, - @HeaderParam("X-Signal-Agent") String userAgent, + @HeaderParam("X-Signal-Agent") String signalAgent, + @HeaderParam("User-Agent") String userAgent, @QueryParam("transfer") Optional availableForTransfer, @Valid AccountAttributes accountAttributes) throws RateLimitExceededException @@ -320,9 +333,17 @@ public class AccountController { throw new WebApplicationException(Response.status(409).build()); } - Account account = createAccount(number, password, userAgent, accountAttributes); + Account account = createAccount(number, password, signalAgent, accountAttributes); - metricRegistry.meter(name(AccountController.class, "verify", Util.getCountryCode(number))).mark(); + { + metricRegistry.meter(name(AccountController.class, "verify", Util.getCountryCode(number))).mark(); + + final List tags = new ArrayList<>(); + tags.add(Tag.of(COUNTRY_CODE_TAG_NAME, Util.getCountryCode(number))); + tags.add(UserAgentTagUtil.getPlatformTag(userAgent)); + + Metrics.counter(ACCOUNT_VERIFY_COUNTER_NAME, tags).increment(); + } return new AccountCreationResult(account.getUuid(), existingAccount.map(Account::isStorageSupported).orElse(false)); } catch (InvalidAuthorizationHeaderException e) { @@ -649,7 +670,7 @@ public class AccountController { return false; } - private Account createAccount(String number, String password, String userAgent, AccountAttributes accountAttributes) { + private Account createAccount(String number, String password, String signalAgent, AccountAttributes accountAttributes) { Optional maybeExistingAccount = accounts.get(number); Device device = new Device(); @@ -661,7 +682,7 @@ public class AccountController { device.setCapabilities(accountAttributes.getCapabilities()); device.setCreated(System.currentTimeMillis()); device.setLastSeen(Util.todayInMillis()); - device.setUserAgent(userAgent); + device.setUserAgent(signalAgent); Account account = new Account(); account.setNumber(number);