From 84f85ae098aede08d49f409c568ae26355b1a537 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Tue, 29 Jun 2021 18:15:46 -0400 Subject: [PATCH] Collapse various account meters into a single, multi-dimensional counter. --- .../auth/BaseAccountAuthenticator.java | 61 ++++++++++--------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/BaseAccountAuthenticator.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/BaseAccountAuthenticator.java index 6dd1c3211..a5697b92e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/auth/BaseAccountAuthenticator.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/BaseAccountAuthenticator.java @@ -5,45 +5,34 @@ package org.whispersystems.textsecuregcm.auth; -import com.codahale.metrics.Meter; -import com.codahale.metrics.MetricRegistry; -import com.codahale.metrics.SharedMetricRegistries; +import static com.codahale.metrics.MetricRegistry.name; + import com.google.common.annotations.VisibleForTesting; import io.dropwizard.auth.basic.BasicCredentials; import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.Metrics; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.whispersystems.textsecuregcm.storage.Account; -import org.whispersystems.textsecuregcm.storage.AccountsManager; -import org.whispersystems.textsecuregcm.storage.Device; -import org.whispersystems.textsecuregcm.util.Constants; -import org.whispersystems.textsecuregcm.util.Util; - +import io.micrometer.core.instrument.Tags; import java.time.Clock; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.Optional; - -import static com.codahale.metrics.MetricRegistry.name; +import org.apache.commons.lang3.StringUtils; +import org.whispersystems.textsecuregcm.storage.Account; +import org.whispersystems.textsecuregcm.storage.AccountsManager; +import org.whispersystems.textsecuregcm.storage.Device; +import org.whispersystems.textsecuregcm.util.Util; public class BaseAccountAuthenticator { - private final MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME); - private final Meter authenticationFailedMeter = metricRegistry.meter(name(getClass(), "authentication", "failed" )); - private final Meter authenticationSucceededMeter = metricRegistry.meter(name(getClass(), "authentication", "succeeded" )); - private final Meter noSuchAccountMeter = metricRegistry.meter(name(getClass(), "authentication", "noSuchAccount" )); - private final Meter noSuchDeviceMeter = metricRegistry.meter(name(getClass(), "authentication", "noSuchDevice" )); - private final Meter accountDisabledMeter = metricRegistry.meter(name(getClass(), "authentication", "accountDisabled")); - private final Meter deviceDisabledMeter = metricRegistry.meter(name(getClass(), "authentication", "deviceDisabled" )); - private final Meter invalidAuthHeaderMeter = metricRegistry.meter(name(getClass(), "authentication", "invalidHeader" )); + private static final String AUTHENTICATION_COUNTER_NAME = name(BaseAccountAuthenticator.class, "authentication"); + private static final String AUTHENTICATION_SUCCEEDED_TAG_NAME = "succeeded"; + private static final String AUTHENTICATION_FAILURE_REASON_TAG_NAME = "reason"; + private static final String AUTHENTICATION_ENABLED_REQUIRED_TAG_NAME = "enabledRequired"; private final String daysSinceLastSeenDistributionName = name(getClass(), "authentication", "daysSinceLastSeen"); private static final String IS_PRIMARY_DEVICE_TAG = "isPrimary"; - private final Logger logger = LoggerFactory.getLogger(BaseAccountAuthenticator.class); - private final AccountsManager accountsManager; private final Clock clock; @@ -58,46 +47,58 @@ public class BaseAccountAuthenticator { } public Optional authenticate(BasicCredentials basicCredentials, boolean enabledRequired) { + boolean succeeded = false; + String failureReason = null; + try { AuthorizationHeader authorizationHeader = AuthorizationHeader.fromUserAndPassword(basicCredentials.getUsername(), basicCredentials.getPassword()); Optional account = accountsManager.get(authorizationHeader.getIdentifier()); if (!account.isPresent()) { - noSuchAccountMeter.mark(); + failureReason = "noSuchAccount"; return Optional.empty(); } Optional device = account.get().getDevice(authorizationHeader.getDeviceId()); if (!device.isPresent()) { - noSuchDeviceMeter.mark(); + failureReason = "noSuchDevice"; return Optional.empty(); } if (enabledRequired) { if (!device.get().isEnabled()) { - deviceDisabledMeter.mark(); + failureReason = "deviceDisabled"; return Optional.empty(); } if (!account.get().isEnabled()) { - accountDisabledMeter.mark(); + failureReason = "accountDisabled"; return Optional.empty(); } } if (device.get().getAuthenticationCredentials().verify(basicCredentials.getPassword())) { - authenticationSucceededMeter.mark(); + succeeded = true; account.get().setAuthenticatedDevice(device.get()); updateLastSeen(account.get(), device.get()); return account; } - authenticationFailedMeter.mark(); return Optional.empty(); } catch (IllegalArgumentException | InvalidAuthorizationHeaderException iae) { - invalidAuthHeaderMeter.mark(); + failureReason = "invalidHeader"; return Optional.empty(); + } finally { + Tags tags = Tags.of( + AUTHENTICATION_SUCCEEDED_TAG_NAME, String.valueOf(succeeded), + AUTHENTICATION_ENABLED_REQUIRED_TAG_NAME, String.valueOf(enabledRequired)); + + if (StringUtils.isNotBlank(failureReason)) { + tags = tags.and(AUTHENTICATION_FAILURE_REASON_TAG_NAME, failureReason); + } + + Metrics.counter(AUTHENTICATION_COUNTER_NAME, tags).increment(); } }