mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 00:28:02 +01:00
Migrate WebSocket duration instrumentation to OpenWebSocketCounter
This commit is contained in:
committed by
ravi-signal
parent
68814813c3
commit
100955a7db
@@ -3,6 +3,7 @@ package org.whispersystems.textsecuregcm.metrics;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Tags;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
||||
import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException;
|
||||
import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil;
|
||||
@@ -11,6 +12,7 @@ import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OpenWebSocketCounter {
|
||||
@@ -18,14 +20,17 @@ public class OpenWebSocketCounter {
|
||||
private final Map<ClientPlatform, AtomicInteger> openWebsocketsByClientPlatform;
|
||||
private final AtomicInteger openWebsocketsFromUnknownPlatforms;
|
||||
|
||||
public OpenWebSocketCounter(final String openWebSocketGaugeName) {
|
||||
this(openWebSocketGaugeName, Tags.empty());
|
||||
private final Map<ClientPlatform, Timer> durationTimersByClientPlatform;
|
||||
private final Timer durationTimerForUnknownPlatforms;
|
||||
|
||||
public OpenWebSocketCounter(final String openWebSocketGaugeName, final String durationTimerName) {
|
||||
this(openWebSocketGaugeName, durationTimerName, Tags.empty());
|
||||
}
|
||||
|
||||
public OpenWebSocketCounter(final String openWebSocketGaugeName, final Tags tags) {
|
||||
public OpenWebSocketCounter(final String openWebSocketGaugeName, final String durationTimerName, final Tags tags) {
|
||||
openWebsocketsByClientPlatform = Arrays.stream(ClientPlatform.values())
|
||||
.collect(Collectors.toMap(
|
||||
clientPlatform -> clientPlatform,
|
||||
Function.identity(),
|
||||
clientPlatform -> buildGauge(openWebSocketGaugeName, clientPlatform.name().toLowerCase(), tags),
|
||||
(a, b) -> {
|
||||
throw new AssertionError("Duplicate client platform enumeration key");
|
||||
@@ -34,6 +39,18 @@ public class OpenWebSocketCounter {
|
||||
));
|
||||
|
||||
openWebsocketsFromUnknownPlatforms = buildGauge(openWebSocketGaugeName, "unknown", tags);
|
||||
|
||||
durationTimersByClientPlatform = Arrays.stream(ClientPlatform.values())
|
||||
.collect(Collectors.toMap(
|
||||
clientPlatform -> clientPlatform,
|
||||
clientPlatform -> buildTimer(durationTimerName, clientPlatform.name().toLowerCase(), tags),
|
||||
(a, b) -> {
|
||||
throw new AssertionError("Duplicate client platform enumeration key");
|
||||
},
|
||||
() -> new EnumMap<>(ClientPlatform.class)
|
||||
));
|
||||
|
||||
durationTimerForUnknownPlatforms = buildTimer(durationTimerName, "unknown", tags);
|
||||
}
|
||||
|
||||
private static AtomicInteger buildGauge(final String gaugeName, final String clientPlatformName, final Tags tags) {
|
||||
@@ -42,18 +59,45 @@ public class OpenWebSocketCounter {
|
||||
new AtomicInteger(0));
|
||||
}
|
||||
|
||||
private static Timer buildTimer(final String timerName, final String clientPlatformName, final Tags tags) {
|
||||
return Timer.builder(timerName)
|
||||
.publishPercentileHistogram(true)
|
||||
.tags(tags.and(Tag.of(UserAgentTagUtil.PLATFORM_TAG, clientPlatformName)))
|
||||
.register(Metrics.globalRegistry);
|
||||
}
|
||||
|
||||
public void countOpenWebSocket(final WebSocketSessionContext context) {
|
||||
final AtomicInteger openWebSocketCounter = getOpenWebsocketCounter(context.getClient().getUserAgent());
|
||||
final Timer.Sample sample = Timer.start();
|
||||
|
||||
// We have to jump through some hoops here to have something "effectively final" for the close listener, but
|
||||
// assignable from a `catch` block.
|
||||
final AtomicInteger openWebSocketCounter;
|
||||
final Timer durationTimer;
|
||||
|
||||
{
|
||||
AtomicInteger calculatedOpenWebSocketCounter;
|
||||
Timer calculatedDurationTimer;
|
||||
|
||||
try {
|
||||
final ClientPlatform clientPlatform =
|
||||
UserAgentUtil.parseUserAgentString(context.getClient().getUserAgent()).getPlatform();
|
||||
|
||||
calculatedOpenWebSocketCounter = openWebsocketsByClientPlatform.get(clientPlatform);
|
||||
calculatedDurationTimer = durationTimersByClientPlatform.get(clientPlatform);
|
||||
} catch (final UnrecognizedUserAgentException e) {
|
||||
calculatedOpenWebSocketCounter = openWebsocketsFromUnknownPlatforms;
|
||||
calculatedDurationTimer = durationTimerForUnknownPlatforms;
|
||||
}
|
||||
|
||||
openWebSocketCounter = calculatedOpenWebSocketCounter;
|
||||
durationTimer = calculatedDurationTimer;
|
||||
}
|
||||
|
||||
openWebSocketCounter.incrementAndGet();
|
||||
context.addWebsocketClosedListener((context1, statusCode, reason) -> openWebSocketCounter.decrementAndGet());
|
||||
}
|
||||
|
||||
private AtomicInteger getOpenWebsocketCounter(final String userAgentString) {
|
||||
try {
|
||||
return openWebsocketsByClientPlatform.get(UserAgentUtil.parseUserAgentString(userAgentString).getPlatform());
|
||||
} catch (final UnrecognizedUserAgentException e) {
|
||||
return openWebsocketsFromUnknownPlatforms;
|
||||
}
|
||||
context.addWebsocketClosedListener((context1, statusCode, reason) -> {
|
||||
sample.stop(durationTimer);
|
||||
openWebSocketCounter.decrementAndGet();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user