diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java index 8b94ebe78..e567a6c6b 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListener.java @@ -81,7 +81,7 @@ public class MetricsRequestEventListener implements RequestEventListener { userAgent = userAgentValues != null && !userAgentValues.isEmpty() ? userAgentValues.get(0) : null; } - tags.add(UserAgentTagUtil.getPlatformTag(userAgent)); + tags.addAll(UserAgentTagUtil.getLibsignalAndPlatformTags(userAgent)); meterRegistry.counter(REQUEST_COUNTER_NAME, tags).increment(); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/UserAgentTagUtil.java b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/UserAgentTagUtil.java index 7ca8ccfc1..6a4d09ddd 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/UserAgentTagUtil.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/UserAgentTagUtil.java @@ -5,14 +5,10 @@ package org.whispersystems.textsecuregcm.metrics; -import com.vdurmont.semver4j.Semver; import io.micrometer.core.instrument.Tag; -import java.util.Collections; -import java.util.Map; +import java.util.List; import java.util.Optional; -import java.util.Set; import org.whispersystems.textsecuregcm.storage.ClientReleaseManager; -import org.whispersystems.textsecuregcm.util.ua.ClientPlatform; import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException; import org.whispersystems.textsecuregcm.util.ua.UserAgent; import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil; @@ -24,6 +20,7 @@ public class UserAgentTagUtil { public static final String PLATFORM_TAG = "platform"; public static final String VERSION_TAG = "clientVersion"; + public static final String LIBSIGNAL_TAG = "libsignal"; private UserAgentTagUtil() { } @@ -52,4 +49,23 @@ public class UserAgentTagUtil { return Optional.empty(); } + + public static List getLibsignalAndPlatformTags(final String userAgentString) { + String platform; + boolean libsignal; + + try { + final UserAgent userAgent = UserAgentUtil.parseUserAgentString(userAgentString); + platform = userAgent.getPlatform().name().toLowerCase(); + libsignal = userAgent.getAdditionalSpecifiers() + .map(additionalSpecifiers -> additionalSpecifiers.contains("libsignal")) + .orElse(false); + } catch (final UnrecognizedUserAgentException e) { + platform = "unrecognized"; + libsignal = false; + } + + return List.of(Tag.of(PLATFORM_TAG, platform), Tag.of(LIBSIGNAL_TAG, String.valueOf(libsignal))); + } + } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java index 9ba5a76bb..232dbdd6c 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsRequestEventListenerTest.java @@ -90,7 +90,7 @@ class MetricsRequestEventListenerTest { final ContainerRequest request = mock(ContainerRequest.class); when(request.getMethod()).thenReturn(method); when(request.getRequestHeader(HttpHeaders.USER_AGENT)).thenReturn( - Collections.singletonList("Signal-Android/4.53.7 (Android 8.1)")); + Collections.singletonList("Signal-Android/7.6.2 Android/34 libsignal/0.46.0")); final ContainerResponse response = mock(ContainerResponse.class); when(response.getStatus()).thenReturn(statusCode); @@ -116,12 +116,13 @@ class MetricsRequestEventListenerTest { tags.add(tag); } - assertEquals(5, tags.size()); + assertEquals(6, tags.size()); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.PATH_TAG, path))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.METHOD_TAG, method))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.STATUS_CODE_TAG, String.valueOf(statusCode)))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.TRAFFIC_SOURCE_TAG, TRAFFIC_SOURCE.name().toLowerCase()))); assertTrue(tags.contains(Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android"))); + assertTrue(tags.contains(Tag.of(UserAgentTagUtil.LIBSIGNAL_TAG, "true"))); } @Test @@ -178,12 +179,13 @@ class MetricsRequestEventListenerTest { tags.add(tag); } - assertEquals(5, tags.size()); + assertEquals(6, tags.size()); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.PATH_TAG, "/v1/test/hello"))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.METHOD_TAG, "GET"))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.STATUS_CODE_TAG, String.valueOf(200)))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.TRAFFIC_SOURCE_TAG, TRAFFIC_SOURCE.name().toLowerCase()))); assertTrue(tags.contains(Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android"))); + assertTrue(tags.contains(Tag.of(UserAgentTagUtil.LIBSIGNAL_TAG, "false"))); } @Test @@ -238,12 +240,13 @@ class MetricsRequestEventListenerTest { tags.add(tag); } - assertEquals(5, tags.size()); + assertEquals(6, tags.size()); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.PATH_TAG, "/v1/test/hello"))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.METHOD_TAG, "GET"))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.STATUS_CODE_TAG, String.valueOf(200)))); assertTrue(tags.contains(Tag.of(MetricsRequestEventListener.TRAFFIC_SOURCE_TAG, TRAFFIC_SOURCE.name().toLowerCase()))); assertTrue(tags.contains(Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized"))); + assertTrue(tags.contains(Tag.of(UserAgentTagUtil.LIBSIGNAL_TAG, "false"))); } private static SubProtocol.WebSocketResponseMessage getResponse(ArgumentCaptor responseCaptor)