diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index 98af6a342..3912ec94e 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -21,7 +21,6 @@ import io.dropwizard.core.server.DefaultServerFactory; import io.dropwizard.core.setup.Bootstrap; import io.dropwizard.core.setup.Environment; import io.dropwizard.jetty.HttpsConnectorFactory; -import io.dropwizard.lifecycle.setup.LifecycleEnvironment; import io.grpc.ServerBuilder; import io.lettuce.core.metrics.MicrometerCommandLatencyRecorder; import io.lettuce.core.metrics.MicrometerOptions; @@ -365,8 +364,8 @@ public class WhisperServerService extends Application dynamicConfigurationManager = new DynamicConfigurationManager<>( @@ -398,7 +397,8 @@ public class WhisperServerService extends Application messageDeletionQueue = new LinkedBlockingQueue<>(); Metrics.gaugeCollectionSize(name(getClass(), "messageDeletionQueueSize"), Collections.emptyList(), messageDeletionQueue); - ExecutorService messageDeletionAsyncExecutor = ExecutorServiceBuilder.of(environment, "messageDeletionAsyncExecutor") + ExecutorService messageDeletionAsyncExecutor = environment.lifecycle() + .executorService(name(getClass(), "messageDeletionAsyncExecutor-%d")) .minThreads(2) .maxThreads(2) .allowCoreThreadTimeOut(true) @@ -502,79 +503,98 @@ public class WhisperServerService extends Application()) .keepAliveTime(io.dropwizard.util.Duration.seconds(60L)) .build(); - ExecutorService cloudflareTurnHttpExecutor = ExecutorServiceBuilder.of(environment, "cloudflareTurn") + ExecutorService cloudflareTurnHttpExecutor = environment.lifecycle() + .executorService(name(getClass(), "cloudflareTurn-%d")) .maxThreads(2) .minThreads(2) .build(); - ExecutorService googlePlayBillingExecutor = virtualExecutorService(environment, "googlePlayBilling"); - ExecutorService appleAppStoreExecutor = virtualExecutorService(environment, "appleAppStore"); - ExecutorService clientEventExecutor = virtualExecutorService(environment, "clientEvent"); - ExecutorService disconnectionRequestListenerExecutor = virtualExecutorService(environment, "disconnectionRequest"); + ExecutorService googlePlayBillingExecutor = environment.lifecycle() + .virtualExecutorService(name(getClass(), "googlePlayBilling-%d")); + ExecutorService appleAppStoreExecutor = environment.lifecycle() + .virtualExecutorService(name(getClass(), "appleAppStore-%d")); + ExecutorService clientEventExecutor = environment.lifecycle() + .virtualExecutorService(name(getClass(), "clientEvent-%d")); + ExecutorService disconnectionRequestListenerExecutor = environment.lifecycle() + .virtualExecutorService(name(getClass(), "disconnectionRequest-%d")); - ScheduledExecutorService appleAppStoreRetryExecutor = ScheduledExecutorServiceBuilder.of(environment, "appleAppStoreRetry").threads(1).build(); - ScheduledExecutorService subscriptionProcessorRetryExecutor = ScheduledExecutorServiceBuilder.of(environment, "subscriptionProcessorRetry").threads(1).build(); - ScheduledExecutorService cloudflareTurnRetryExecutor = ScheduledExecutorServiceBuilder.of(environment, "cloudflareTurnRetry").threads(1).build(); - ScheduledExecutorService messagePollExecutor = ScheduledExecutorServiceBuilder.of(environment, "messagePollExecutor").threads(1).build(); - ScheduledExecutorService provisioningWebsocketTimeoutExecutor = ScheduledExecutorServiceBuilder.of(environment, "provisioningWebsocketTimeout").threads(1).build(); + ScheduledExecutorService appleAppStoreRetryExecutor = environment.lifecycle() + .scheduledExecutorService(name(getClass(), "appleAppStoreRetry-%d")).threads(1).build(); + ScheduledExecutorService subscriptionProcessorRetryExecutor = environment.lifecycle() + .scheduledExecutorService(name(getClass(), "subscriptionProcessorRetry-%d")).threads(1).build(); + ScheduledExecutorService cloudflareTurnRetryExecutor = environment.lifecycle() + .scheduledExecutorService(name(getClass(), "cloudflareTurnRetry-%d")).threads(1).build(); + ScheduledExecutorService messagePollExecutor = environment.lifecycle() + .scheduledExecutorService(name(getClass(), "messagePollExecutor-%d")).threads(1).build(); + ScheduledExecutorService provisioningWebsocketTimeoutExecutor = environment.lifecycle() + .scheduledExecutorService(name(getClass(), "provisioningWebsocketTimeout-%d")).threads(1).build(); final ManagedNioEventLoopGroup dnsResolutionEventLoopGroup = new ManagedNioEventLoopGroup(); final DnsNameResolver cloudflareDnsResolver = new DnsNameResolverBuilder(dnsResolutionEventLoopGroup.next()) @@ -902,7 +922,8 @@ public class WhisperServerService extends Application getPendingMessages(@Auth AuthenticatedDevice auth, @@ -832,6 +835,7 @@ public class MessageController { return size; } + @Timed @DELETE @Path("/uuid/{uuid}") public CompletableFuture removePendingMessage(@Auth AuthenticatedDevice auth, @PathParam("uuid") UUID uuid) { @@ -870,6 +874,7 @@ public class MessageController { .thenApply(Util.ASYNC_EMPTY_RESPONSE); } + @Timed @POST @Consumes(MediaType.APPLICATION_JSON) @Path("/report/{source}/{messageGuid}") diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/jetty/JettyHttpConfigurationCustomizer.java b/service/src/main/java/org/whispersystems/textsecuregcm/jetty/JettyHttpConfigurationCustomizer.java index 3415c0086..c42eb8cad 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/jetty/JettyHttpConfigurationCustomizer.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/jetty/JettyHttpConfigurationCustomizer.java @@ -14,8 +14,6 @@ import org.eclipse.jetty.util.component.Container; import org.eclipse.jetty.util.component.LifeCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import io.micrometer.core.instrument.Metrics; -import io.micrometer.core.instrument.binder.jetty.JettyConnectionMetrics; /** * Uses {@link Container.Listener} to update {@link org.eclipse.jetty.server.HttpConfiguration} @@ -27,6 +25,7 @@ public class JettyHttpConfigurationCustomizer implements Container.Listener, Lif @Override public void beanAdded(final Container parent, final Object child) { if (child instanceof Connector c) { + for (ConnectionFactory cf : c.getConnectionFactories()) { final HttpConfiguration httpConfiguration = switch (cf) { case HTTP2ServerConnectionFactory h2cf -> h2cf.getHttpConfiguration(); @@ -40,8 +39,6 @@ public class JettyHttpConfigurationCustomizer implements Container.Listener, Lif httpConfiguration.setNotifyRemoteAsyncErrors(false); } } - - c.addBean(new JettyConnectionMetrics(Metrics.globalRegistry)); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java b/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java index 2f34a1ba4..3ff6d56bd 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/push/ReceiptSender.java @@ -5,6 +5,8 @@ package org.whispersystems.textsecuregcm.push; +import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.binder.jvm.ExecutorServiceMetrics; import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutorService; @@ -14,6 +16,7 @@ import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier; import org.whispersystems.textsecuregcm.identity.ServiceIdentifier; +import org.whispersystems.textsecuregcm.metrics.MetricsUtil; import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; @@ -30,7 +33,9 @@ public class ReceiptSender { final ExecutorService executor) { this.accountManager = accountManager; this.messageSender = messageSender; - this.executor = executor; + this.executor = ExecutorServiceMetrics.monitor( + Metrics.globalRegistry, executor, MetricsUtil.name(ReceiptSender.class, "executor"), MetricsUtil.PREFIX) + ; } public void sendReceipt(ServiceIdentifier sourceIdentifier, byte sourceDeviceId, AciServiceIdentifier destinationIdentifier, long messageId) {