Record the age of accounts that send unsealed-sender messages.

This commit is contained in:
Jon Chambers
2021-02-22 16:01:26 -05:00
committed by Jon Chambers
parent 8c9d871268
commit 06ca5f14fc
4 changed files with 38 additions and 5 deletions

View File

@@ -402,7 +402,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
AttachmentControllerV2 attachmentControllerV2 = new AttachmentControllerV2(rateLimiters, config.getAwsAttachmentsConfiguration().getAccessKey(), config.getAwsAttachmentsConfiguration().getAccessSecret(), config.getAwsAttachmentsConfiguration().getRegion(), config.getAwsAttachmentsConfiguration().getBucket());
AttachmentControllerV3 attachmentControllerV3 = new AttachmentControllerV3(rateLimiters, config.getGcpAttachmentsConfiguration().getDomain(), config.getGcpAttachmentsConfiguration().getEmail(), config.getGcpAttachmentsConfiguration().getMaxSizeInBytes(), config.getGcpAttachmentsConfiguration().getPathPrefix(), config.getGcpAttachmentsConfiguration().getRsaSigningKey());
KeysController keysController = new KeysController(rateLimiters, keysDynamoDb, accountsManager, directoryQueue);
MessageController messageController = new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, messagesManager, apnFallbackManager, dynamicConfigurationManager);
MessageController messageController = new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, messagesManager, apnFallbackManager, dynamicConfigurationManager, metricsCluster);
ProfileController profileController = new ProfileController(rateLimiters, accountsManager, profilesManager, usernamesManager, cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner, config.getCdnConfiguration().getBucket(), zkProfileOperations, isZkEnabled);
StickerController stickerController = new StickerController(rateLimiters, config.getCdnConfiguration().getAccessKey(), config.getCdnConfiguration().getAccessSecret(), config.getCdnConfiguration().getRegion(), config.getCdnConfiguration().getBucket());
RemoteConfigController remoteConfigController = new RemoteConfigController(remoteConfigsManager, config.getRemoteConfigConfiguration().getAuthorizedTokens(), config.getRemoteConfigConfiguration().getGlobalConfig());

View File

@@ -16,6 +16,7 @@ import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.protobuf.ByteString;
import io.dropwizard.auth.Auth;
import io.dropwizard.util.DataSize;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import java.io.IOException;
@@ -56,6 +57,7 @@ import org.whispersystems.textsecuregcm.push.ApnFallbackManager;
import org.whispersystems.textsecuregcm.push.MessageSender;
import org.whispersystems.textsecuregcm.push.NotPushRegisteredException;
import org.whispersystems.textsecuregcm.push.ReceiptSender;
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
import org.whispersystems.textsecuregcm.redis.RedisOperation;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
@@ -88,10 +90,12 @@ public class MessageController {
private final MessagesManager messagesManager;
private final ApnFallbackManager apnFallbackManager;
private final DynamicConfigurationManager dynamicConfigurationManager;
private final FaultTolerantRedisCluster metricsCluster;
private static final String SENT_MESSAGE_COUNTER_NAME = name(MessageController.class, "sentMessages");
private static final String REJECT_UNSEALED_SENDER_COUNTER_NAME = name(MessageController.class, "rejectUnsealedSenderLimit");
private static final String INTERNATIONAL_UNSEALED_SENDER_COUNTER_NAME = name(MessageController.class, "internationalUnsealedSender");
private static final String UNSEALED_SENDER_ACCOUNT_AGE_DISTRIBUTION_NAME = name(MessageController.class, "unsealedSenderAccountAge");
private static final String CONTENT_SIZE_DISTRIBUTION_NAME = name(MessageController.class, "messageContentSize");
private static final String OUTGOING_MESSAGE_LIST_SIZE_BYTES_DISTRIBUTION_NAME = name(MessageController.class, "outgoingMessageListSizeBytes");
@@ -101,13 +105,16 @@ public class MessageController {
private static final long MAX_MESSAGE_SIZE = DataSize.kibibytes(256).toBytes();
private static final String SENT_FIRST_UNSEALED_SENDER_MESSAGE_KEY = "sent_first_unsealed_sender_message";
public MessageController(RateLimiters rateLimiters,
MessageSender messageSender,
ReceiptSender receiptSender,
AccountsManager accountsManager,
MessagesManager messagesManager,
ApnFallbackManager apnFallbackManager,
DynamicConfigurationManager dynamicConfigurationManager)
DynamicConfigurationManager dynamicConfigurationManager,
FaultTolerantRedisCluster metricsCluster)
{
this.rateLimiters = rateLimiters;
this.messageSender = messageSender;
@@ -116,6 +123,7 @@ public class MessageController {
this.messagesManager = messagesManager;
this.apnFallbackManager = apnFallbackManager;
this.dynamicConfigurationManager = dynamicConfigurationManager;
this.metricsCluster = metricsCluster;
}
@Timed
@@ -135,6 +143,26 @@ public class MessageController {
}
if (source.isPresent() && !source.get().isFor(destinationName)) {
RedisOperation.unchecked(() -> {
metricsCluster.useCluster(connection -> {
if (connection.sync().pfadd(SENT_FIRST_UNSEALED_SENDER_MESSAGE_KEY, source.get().getUuid().toString()) == 1) {
final List<Tag> tags = List.of(
UserAgentTagUtil.getPlatformTag(userAgent),
Tag.of(SENDER_COUNTRY_TAG_NAME, Util.getCountryCode(source.get().getNumber())));
assert source.get().getMasterDevice().isPresent();
final long accountAge = System.currentTimeMillis() - source.get().getMasterDevice().get().getCreated();
DistributionSummary.builder(UNSEALED_SENDER_ACCOUNT_AGE_DISTRIBUTION_NAME)
.tags(tags)
.publishPercentileHistogram()
.register(Metrics.globalRegistry)
.record(accountAge);
}
});
});
try {
rateLimiters.getUnsealedSenderLimiter().validate(source.get().getUuid().toString(), destinationName.toString());
} catch (RateLimitExceededException e) {