Add metric publishers to DynamoDB clients

This commit is contained in:
Jon Chambers
2024-09-25 16:50:07 -04:00
committed by Jon Chambers
parent 78b40397f9
commit 946a486c4b
8 changed files with 50 additions and 14 deletions

View File

@@ -186,6 +186,7 @@ import org.whispersystems.textsecuregcm.metrics.MessageMetrics;
import org.whispersystems.textsecuregcm.metrics.MetricsApplicationEventListener;
import org.whispersystems.textsecuregcm.metrics.MetricsHttpChannelListener;
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
import org.whispersystems.textsecuregcm.metrics.MicrometerAwsSdkMetricPublisher;
import org.whispersystems.textsecuregcm.metrics.ReportedMessageMetricsListener;
import org.whispersystems.textsecuregcm.metrics.TrafficSource;
import org.whispersystems.textsecuregcm.providers.MultiRecipientMessageProvider;
@@ -393,10 +394,15 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
BankMandateTranslator bankMandateTranslator = new BankMandateTranslator(headerControlledResourceBundleLookup);
environment.lifecycle().manage(new ManagedAwsCrt());
DynamoDbAsyncClient dynamoDbAsyncClient = config.getDynamoDbClientConfiguration()
.buildAsyncClient(awsCredentialsProvider);
DynamoDbClient dynamoDbClient = config.getDynamoDbClientConfiguration().buildSyncClient(awsCredentialsProvider);
final ExecutorService awsSdkMetricsExecutor = environment.lifecycle()
.virtualExecutorService(name(getClass(), "awsSdkMetrics-%d"));
final DynamoDbAsyncClient dynamoDbAsyncClient = config.getDynamoDbClientConfiguration()
.buildAsyncClient(awsCredentialsProvider, new MicrometerAwsSdkMetricPublisher(awsSdkMetricsExecutor, "dynamoDbAsync"));
final DynamoDbClient dynamoDbClient = config.getDynamoDbClientConfiguration()
.buildSyncClient(awsCredentialsProvider, new MicrometerAwsSdkMetricPublisher(awsSdkMetricsExecutor, "dynamoDbSync"));
BlockingQueue<Runnable> messageDeletionQueue = new LinkedBlockingQueue<>();
Metrics.gaugeCollectionSize(name(getClass(), "messageDeletionQueueSize"), Collections.emptyList(),

View File

@@ -14,6 +14,7 @@ import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
@@ -39,13 +40,14 @@ public record DynamoDbClientConfiguration(@NotBlank String region,
}
@Override
public DynamoDbClient buildSyncClient(final AwsCredentialsProvider credentialsProvider) {
public DynamoDbClient buildSyncClient(final AwsCredentialsProvider credentialsProvider, final MetricPublisher metricPublisher) {
return DynamoDbClient.builder()
.region(Region.of(region()))
.credentialsProvider(credentialsProvider)
.overrideConfiguration(ClientOverrideConfiguration.builder()
.apiCallTimeout(clientExecutionTimeout())
.apiCallAttemptTimeout(clientRequestTimeout())
.addMetricPublisher(metricPublisher)
.build())
.httpClientBuilder(AwsCrtHttpClient.builder()
.maxConcurrency(maxConnections()))
@@ -53,13 +55,14 @@ public record DynamoDbClientConfiguration(@NotBlank String region,
}
@Override
public DynamoDbAsyncClient buildAsyncClient(final AwsCredentialsProvider credentialsProvider) {
public DynamoDbAsyncClient buildAsyncClient(final AwsCredentialsProvider credentialsProvider, final MetricPublisher metricPublisher) {
return DynamoDbAsyncClient.builder()
.region(Region.of(region()))
.credentialsProvider(credentialsProvider)
.overrideConfiguration(ClientOverrideConfiguration.builder()
.apiCallTimeout(clientExecutionTimeout())
.apiCallAttemptTimeout(clientRequestTimeout())
.addMetricPublisher(metricPublisher)
.build())
.httpClientBuilder(NettyNioAsyncHttpClient.builder()
.maxConcurrency(maxConnections()))

View File

@@ -8,13 +8,14 @@ package org.whispersystems.textsecuregcm.configuration;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.dropwizard.jackson.Discoverable;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.metrics.MetricPublisher;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", defaultImpl = DynamoDbClientConfiguration.class)
public interface DynamoDbClientFactory extends Discoverable {
DynamoDbClient buildSyncClient(AwsCredentialsProvider awsCredentialsProvider);
DynamoDbClient buildSyncClient(AwsCredentialsProvider awsCredentialsProvider, MetricPublisher metricPublisher);
DynamoDbAsyncClient buildAsyncClient(AwsCredentialsProvider awsCredentialsProvider);
DynamoDbAsyncClient buildAsyncClient(AwsCredentialsProvider awsCredentialsProvider, MetricPublisher metricPublisher);
}

View File

@@ -0,0 +1,15 @@
package org.whispersystems.textsecuregcm.metrics;
import software.amazon.awssdk.metrics.MetricCollection;
import software.amazon.awssdk.metrics.MetricPublisher;
public class NoopAwsSdkMetricPublisher implements MetricPublisher {
@Override
public void publish(final MetricCollection metricCollection) {
}
@Override
public void close() {
}
}

View File

@@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.workers;
import static com.codahale.metrics.MetricRegistry.name;
import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.databind.DeserializationFeature;
import io.dropwizard.core.setup.Environment;
import io.lettuce.core.resource.ClientResources;
@@ -32,6 +33,8 @@ import org.whispersystems.textsecuregcm.controllers.SecureStorageController;
import org.whispersystems.textsecuregcm.controllers.SecureValueRecovery2Controller;
import org.whispersystems.textsecuregcm.experiment.PushNotificationExperimentSamples;
import org.whispersystems.textsecuregcm.limits.RateLimiters;
import org.whispersystems.textsecuregcm.metrics.MicrometerAwsSdkMetricPublisher;
import org.whispersystems.textsecuregcm.metrics.NoopAwsSdkMetricPublisher;
import org.whispersystems.textsecuregcm.push.APNSender;
import org.whispersystems.textsecuregcm.push.PushNotificationScheduler;
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
@@ -148,11 +151,14 @@ record CommandDependencies(
ExternalServiceCredentialsGenerator secureValueRecoveryCredentialsGenerator = SecureValueRecovery2Controller.credentialsGenerator(
configuration.getSvr2Configuration());
final ExecutorService awsSdkMetricsExecutor = environment.lifecycle()
.virtualExecutorService(MetricRegistry.name(CommandDependencies.class, "awsSdkMetrics-%d"));
DynamoDbAsyncClient dynamoDbAsyncClient = configuration.getDynamoDbClientConfiguration()
.buildAsyncClient(awsCredentialsProvider);
.buildAsyncClient(awsCredentialsProvider, new MicrometerAwsSdkMetricPublisher(awsSdkMetricsExecutor, "dynamoDbAsyncCommand"));
DynamoDbClient dynamoDbClient = configuration.getDynamoDbClientConfiguration()
.buildSyncClient(awsCredentialsProvider);
.buildSyncClient(awsCredentialsProvider, new MicrometerAwsSdkMetricPublisher(awsSdkMetricsExecutor, "dynamoDbSyncCommand"));
RegistrationRecoveryPasswords registrationRecoveryPasswords = new RegistrationRecoveryPasswords(
configuration.getDynamoDbTables().getRegistrationRecovery().getTableName(),