Add micrometer metrics to RateLimiter

This commit is contained in:
Chris Eager 2023-02-22 18:39:21 -06:00 committed by Chris Eager
parent ef2cc6620e
commit ecbef9c6ee
2 changed files with 20 additions and 13 deletions

View File

@ -11,8 +11,11 @@ import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.SharedMetricRegistries;
import io.lettuce.core.SetArgs; import io.lettuce.core.SetArgs;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;
import java.time.Duration; import java.time.Duration;
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException; import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster; import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
import org.whispersystems.textsecuregcm.util.Constants; import org.whispersystems.textsecuregcm.util.Constants;
@ -21,7 +24,9 @@ public class LockingRateLimiter extends StaticRateLimiter {
private static final RateLimitExceededException REUSABLE_RATE_LIMIT_EXCEEDED_EXCEPTION private static final RateLimitExceededException REUSABLE_RATE_LIMIT_EXCEEDED_EXCEPTION
= new RateLimitExceededException(Duration.ZERO, true); = new RateLimitExceededException(Duration.ZERO, true);
@Deprecated
private final Meter meter; private final Meter meter;
private final Counter counter;
public LockingRateLimiter( public LockingRateLimiter(
@ -31,12 +36,14 @@ public class LockingRateLimiter extends StaticRateLimiter {
super(name, config, cacheCluster); super(name, config, cacheCluster);
final MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME); final MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME);
this.meter = metricRegistry.meter(name(getClass(), name, "locked")); this.meter = metricRegistry.meter(name(getClass(), name, "locked"));
this.counter = Metrics.counter(MetricsUtil.name(getClass(), "locked"), "name", name);
} }
@Override @Override
public void validate(final String key, final int amount) throws RateLimitExceededException { public void validate(final String key, final int amount) throws RateLimitExceededException {
if (!acquireLock(key)) { if (!acquireLock(key)) {
meter.mark(); meter.mark();
counter.increment();
throw REUSABLE_RATE_LIMIT_EXCEEDED_EXCEPTION; throw REUSABLE_RATE_LIMIT_EXCEEDED_EXCEPTION;
} }

View File

@ -10,13 +10,15 @@ import static java.util.Objects.requireNonNull;
import com.codahale.metrics.Meter; import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.SharedMetricRegistries;
import com.codahale.metrics.Timer;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;
import java.io.IOException; import java.io.IOException;
import java.time.Duration; import java.time.Duration;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException; import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster; import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
import org.whispersystems.textsecuregcm.util.Constants; import org.whispersystems.textsecuregcm.util.Constants;
import org.whispersystems.textsecuregcm.util.SystemMapper; import org.whispersystems.textsecuregcm.util.SystemMapper;
@ -31,11 +33,10 @@ public class StaticRateLimiter implements RateLimiter {
protected final FaultTolerantRedisCluster cacheCluster; protected final FaultTolerantRedisCluster cacheCluster;
private final Counter counter;
@Deprecated
private final Meter meter; private final Meter meter;
private final Timer validateTimer;
public StaticRateLimiter( public StaticRateLimiter(
final String name, final String name,
final RateLimiterConfig config, final RateLimiterConfig config,
@ -45,19 +46,18 @@ public class StaticRateLimiter implements RateLimiter {
this.config = requireNonNull(config); this.config = requireNonNull(config);
this.cacheCluster = requireNonNull(cacheCluster); this.cacheCluster = requireNonNull(cacheCluster);
this.meter = metricRegistry.meter(name(getClass(), name, "exceeded")); this.meter = metricRegistry.meter(name(getClass(), name, "exceeded"));
this.validateTimer = metricRegistry.timer(name(getClass(), name, "validate")); this.counter = Metrics.counter(MetricsUtil.name(getClass(), "exceeded"), "name", name);
} }
@Override @Override
public void validate(final String key, final int amount) throws RateLimitExceededException { public void validate(final String key, final int amount) throws RateLimitExceededException {
try (final Timer.Context ignored = validateTimer.time()) { final LeakyBucket bucket = getBucket(key);
final LeakyBucket bucket = getBucket(key); if (bucket.add(amount)) {
if (bucket.add(amount)) { setBucket(key, bucket);
setBucket(key, bucket); } else {
} else { meter.mark();
meter.mark(); counter.increment();
throw new RateLimitExceededException(bucket.getTimeUntilSpaceAvailable(amount), true); throw new RateLimitExceededException(bucket.getTimeUntilSpaceAvailable(amount), true);
}
} }
} }