Add counter with WebSocket close codes
This commit is contained in:
parent
a9975e524b
commit
2dfd17af4a
|
@ -1,19 +1,23 @@
|
||||||
package org.whispersystems.textsecuregcm.metrics;
|
package org.whispersystems.textsecuregcm.metrics;
|
||||||
|
|
||||||
|
import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
|
||||||
|
|
||||||
import io.micrometer.core.instrument.Metrics;
|
import io.micrometer.core.instrument.Metrics;
|
||||||
import io.micrometer.core.instrument.Tag;
|
import io.micrometer.core.instrument.Tag;
|
||||||
import io.micrometer.core.instrument.Tags;
|
import io.micrometer.core.instrument.Tags;
|
||||||
import io.micrometer.core.instrument.Timer;
|
import io.micrometer.core.instrument.Timer;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import org.whispersystems.textsecuregcm.util.EnumMapUtil;
|
import org.whispersystems.textsecuregcm.util.EnumMapUtil;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException;
|
import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException;
|
||||||
import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil;
|
import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil;
|
||||||
import org.whispersystems.websocket.session.WebSocketSessionContext;
|
import org.whispersystems.websocket.session.WebSocketSessionContext;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class OpenWebSocketCounter {
|
public class OpenWebSocketCounter {
|
||||||
|
|
||||||
|
private static final String WEBSOCKET_CLOSED_COUNTER_NAME = name(OpenWebSocketCounter.class, "websocketClosed");
|
||||||
|
|
||||||
private final Map<ClientPlatform, AtomicInteger> openWebsocketsByClientPlatform;
|
private final Map<ClientPlatform, AtomicInteger> openWebsocketsByClientPlatform;
|
||||||
private final AtomicInteger openWebsocketsFromUnknownPlatforms;
|
private final AtomicInteger openWebsocketsFromUnknownPlatforms;
|
||||||
|
|
||||||
|
@ -81,6 +85,9 @@ public class OpenWebSocketCounter {
|
||||||
context.addWebsocketClosedListener((context1, statusCode, reason) -> {
|
context.addWebsocketClosedListener((context1, statusCode, reason) -> {
|
||||||
sample.stop(durationTimer);
|
sample.stop(durationTimer);
|
||||||
openWebSocketCounter.decrementAndGet();
|
openWebSocketCounter.decrementAndGet();
|
||||||
|
|
||||||
|
Metrics.counter(WEBSOCKET_CLOSED_COUNTER_NAME, "status", String.valueOf(statusCode))
|
||||||
|
.increment();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,12 @@ import jakarta.ws.rs.core.Response;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.eclipse.jetty.util.component.LifeCycle;
|
||||||
import org.eclipse.jetty.websocket.api.Session;
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
|
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.whispersystems.textsecuregcm.metrics.NoopAwsSdkMetricPublisher;
|
import org.whispersystems.textsecuregcm.metrics.NoopAwsSdkMetricPublisher;
|
||||||
|
@ -47,27 +48,22 @@ class WhisperServerServiceTest {
|
||||||
Resources.getResource("config/test-secrets-bundle.yml").getPath());
|
Resources.getResource("config/test-secrets-bundle.yml").getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final WebSocketClient webSocketClient = new WebSocketClient();
|
||||||
|
|
||||||
private static final DropwizardAppExtension<WhisperServerConfiguration> EXTENSION = new DropwizardAppExtension<>(
|
private static final DropwizardAppExtension<WhisperServerConfiguration> EXTENSION = new DropwizardAppExtension<>(
|
||||||
WhisperServerService.class, Resources.getResource("config/test.yml").getPath());
|
WhisperServerService.class, Resources.getResource("config/test.yml").getPath());
|
||||||
|
|
||||||
private WebSocketClient webSocketClient;
|
|
||||||
|
|
||||||
@AfterAll
|
@AfterAll
|
||||||
static void teardown() {
|
static void teardown() {
|
||||||
System.clearProperty("secrets.bundle.filename");
|
System.clearProperty("secrets.bundle.filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeAll
|
||||||
void setUp() throws Exception {
|
static void setUp() throws Exception {
|
||||||
webSocketClient = new WebSocketClient();
|
|
||||||
webSocketClient.start();
|
webSocketClient.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
void tearDown() throws Exception {
|
|
||||||
webSocketClient.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void start() throws Exception {
|
void start() throws Exception {
|
||||||
// make sure the service nominally starts and responds to health checks
|
// make sure the service nominally starts and responds to health checks
|
||||||
|
@ -96,6 +92,16 @@ class WhisperServerServiceTest {
|
||||||
|
|
||||||
final TestWebsocketListener testWebsocketListener = new TestWebsocketListener();
|
final TestWebsocketListener testWebsocketListener = new TestWebsocketListener();
|
||||||
|
|
||||||
|
EXTENSION.getTestSupport().getEnvironment().getApplicationContext().getServer()
|
||||||
|
.addEventListener(new LifeCycle.Listener() {
|
||||||
|
@Override
|
||||||
|
public void lifeCycleStopped(final LifeCycle event) {
|
||||||
|
// closed by org.eclipse.jetty.websocket.common.SessionTracker during the container Lifecycle stopping phase
|
||||||
|
assertEquals(StatusCode.SHUTDOWN, testWebsocketListener.closeFuture().getNow(-1));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Session is Closeable, but we intentionally keep it open so that we can confirm the container Lifecycle behavior
|
||||||
final Session session = webSocketClient.connect(testWebsocketListener,
|
final Session session = webSocketClient.connect(testWebsocketListener,
|
||||||
URI.create(String.format("ws://localhost:%d/v1/websocket/", EXTENSION.getLocalPort())))
|
URI.create(String.format("ws://localhost:%d/v1/websocket/", EXTENSION.getLocalPort())))
|
||||||
.join();
|
.join();
|
||||||
|
@ -112,6 +118,8 @@ class WhisperServerServiceTest {
|
||||||
assertEquals(401, whoami.getStatus());
|
assertEquals(401, whoami.getStatus());
|
||||||
final long whoamiTimestamp = Long.parseLong(whoami.getHeaders().get(HeaderUtils.TIMESTAMP_HEADER.toLowerCase()));
|
final long whoamiTimestamp = Long.parseLong(whoami.getHeaders().get(HeaderUtils.TIMESTAMP_HEADER.toLowerCase()));
|
||||||
assertTrue(whoamiTimestamp >= start);
|
assertTrue(whoamiTimestamp >= start);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue