From 13afdbda9748ff1e2bd65800ca730ac1f94458b8 Mon Sep 17 00:00:00 2001 From: Chris Eager <79161849+eager-signal@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:48:23 -0500 Subject: [PATCH] Report system resource metrics from background tasks --- .../textsecuregcm/WhisperServerService.java | 28 +-------- .../textsecuregcm/metrics/MetricsUtil.java | 60 +++++++++++++++++++ .../workers/CrawlAccountsCommand.java | 56 ++++++++--------- .../MessagePersisterServiceCommand.java | 2 + ...nPushNotificationSenderServiceCommand.java | 2 + 5 files changed, 94 insertions(+), 54 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index fc571bb5f..2e83cb1ea 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -46,7 +46,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletRegistration; @@ -127,18 +126,8 @@ import org.whispersystems.textsecuregcm.mappers.NonNormalizedPhoneNumberExceptio import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper; import org.whispersystems.textsecuregcm.mappers.RegistrationServiceSenderExceptionMapper; import org.whispersystems.textsecuregcm.mappers.ServerRejectedExceptionMapper; -import org.whispersystems.textsecuregcm.metrics.ApplicationShutdownMonitor; -import org.whispersystems.textsecuregcm.metrics.BufferPoolGauges; -import org.whispersystems.textsecuregcm.metrics.CpuUsageGauge; -import org.whispersystems.textsecuregcm.metrics.FileDescriptorGauge; -import org.whispersystems.textsecuregcm.metrics.FreeMemoryGauge; -import org.whispersystems.textsecuregcm.metrics.GarbageCollectionGauges; -import org.whispersystems.textsecuregcm.metrics.MaxFileDescriptorGauge; import org.whispersystems.textsecuregcm.metrics.MetricsApplicationEventListener; import org.whispersystems.textsecuregcm.metrics.MetricsUtil; -import org.whispersystems.textsecuregcm.metrics.NetworkReceivedGauge; -import org.whispersystems.textsecuregcm.metrics.NetworkSentGauge; -import org.whispersystems.textsecuregcm.metrics.OperatingSystemMemoryGauge; import org.whispersystems.textsecuregcm.metrics.ReportedMessageMetricsListener; import org.whispersystems.textsecuregcm.metrics.TrafficSource; import org.whispersystems.textsecuregcm.providers.MultiRecipientMessageProvider; @@ -783,7 +772,6 @@ public class WhisperServerService extends Application provisioningEnvironment = new WebSocketEnvironment<>(environment, webSocketEnvironment.getRequestLog(), 60000); provisioningEnvironment.jersey().register(new WebsocketRefreshApplicationEventListener(accountsManager, clientPresenceManager)); @@ -817,21 +805,7 @@ public class WhisperServerService extends Application { + if (managedObject instanceof JettyManaged jettyManaged) { + if (jettyManaged.getManaged() instanceof ScheduledReporterManager scheduledReporterManager) { + try { + scheduledReporterManager.start(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + } + }); + } + + /** + * For use in commands where {@link JettyManaged} doesn't apply + * + * @see io.dropwizard.metrics.MetricsFactory#configure(LifecycleEnvironment, MetricRegistry) + */ + public static void stopManagedReporters(final Environment environment) { + environment.lifecycle().getManagedObjects().forEach(lifeCycle -> { + if (lifeCycle instanceof JettyManaged jettyManaged) { + if (jettyManaged.getManaged() instanceof ScheduledReporterManager scheduledReporterManager) { + try { + scheduledReporterManager.stop(); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + } + }); } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java index bab25843e..4f97347cd 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CrawlAccountsCommand.java @@ -97,38 +97,39 @@ public class CrawlAccountsCommand extends EnvironmentCommand { + final AccountDatabaseCrawlerCache accountDatabaseCrawlerCache = new AccountDatabaseCrawlerCache( + cacheCluster, + AccountDatabaseCrawlerCache.GENERAL_PURPOSE_PREFIX); - switch ((CrawlType) namespace.get(CRAWL_TYPE)) { - case GENERAL_PURPOSE -> { - final AccountDatabaseCrawlerCache accountDatabaseCrawlerCache = new AccountDatabaseCrawlerCache( - cacheCluster, - AccountDatabaseCrawlerCache.GENERAL_PURPOSE_PREFIX); + yield new AccountDatabaseCrawler("General-purpose account crawler", + accountsManager, + accountDatabaseCrawlerCache, accountDatabaseCrawlerListeners, + configuration.getAccountDatabaseCrawlerConfiguration().getChunkSize(), + dynamicConfigurationManager + ); + } + case ACCOUNT_CLEANER -> { + final ExecutorService accountDeletionExecutor = environment.lifecycle() + .executorService(name(getClass(), "accountCleaner-%d")).maxThreads(16).minThreads(16).build(); - yield new AccountDatabaseCrawler("General-purpose account crawler", - accountsManager, - accountDatabaseCrawlerCache, accountDatabaseCrawlerListeners, - configuration.getAccountDatabaseCrawlerConfiguration().getChunkSize(), - dynamicConfigurationManager - ); - } - case ACCOUNT_CLEANER -> { - final ExecutorService accountDeletionExecutor = environment.lifecycle() - .executorService(name(getClass(), "accountCleaner-%d")).maxThreads(16).minThreads(16).build(); + final AccountDatabaseCrawlerCache accountDatabaseCrawlerCache = new AccountDatabaseCrawlerCache( + cacheCluster, AccountDatabaseCrawlerCache.ACCOUNT_CLEANER_PREFIX); - final AccountDatabaseCrawlerCache accountDatabaseCrawlerCache = new AccountDatabaseCrawlerCache( - cacheCluster, AccountDatabaseCrawlerCache.ACCOUNT_CLEANER_PREFIX); + yield new AccountDatabaseCrawler("Account cleaner crawler", + accountsManager, + accountDatabaseCrawlerCache, + List.of(new AccountCleaner(accountsManager, accountDeletionExecutor)), + configuration.getAccountDatabaseCrawlerConfiguration().getChunkSize(), + dynamicConfigurationManager + ); + } + }; - yield new AccountDatabaseCrawler("Account cleaner crawler", - accountsManager, - accountDatabaseCrawlerCache, - List.of(new AccountCleaner(accountsManager, accountDeletionExecutor)), - configuration.getAccountDatabaseCrawlerConfiguration().getChunkSize(), - dynamicConfigurationManager - ); - } - }; + MetricsUtil.startManagedReporters(environment); try { crawler.crawlAllAccounts(); @@ -136,5 +137,6 @@ public class CrawlAccountsCommand extends EnvironmentCommand