From ed6a2c55ebda635a446eab5b71a63eb6040ae57b Mon Sep 17 00:00:00 2001 From: Ravi Khadiwala Date: Thu, 10 Aug 2023 17:44:34 -0500 Subject: [PATCH] adjust lettuce metric denial for post-transform name --- .../textsecuregcm/metrics/MetricsUtil.java | 79 ++++++++++--------- .../metrics/MetricsUtilTest.java | 26 ++++++ 2 files changed, 68 insertions(+), 37 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsUtil.java b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsUtil.java index 8b72a044e..23dea4224 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsUtil.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/metrics/MetricsUtil.java @@ -6,12 +6,13 @@ package org.whispersystems.textsecuregcm.metrics; import com.codahale.metrics.SharedMetricRegistries; +import com.google.common.annotations.VisibleForTesting; import io.dropwizard.setup.Environment; import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.config.MeterFilter; -import io.micrometer.core.instrument.config.MeterFilterReply; import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; import io.micrometer.datadog.DatadogMeterRegistry; import java.util.concurrent.TimeUnit; @@ -43,47 +44,17 @@ public class MetricsUtil { public static void configureRegistries(final WhisperServerConfiguration config, final Environment environment) { SharedMetricRegistries.add(Constants.METRICS_NAME, environment.metrics()); - final DistributionStatisticConfig defaultDistributionStatisticConfig = DistributionStatisticConfig.builder() - .percentiles(.75, .95, .99, .999) - .build(); - { final DatadogMeterRegistry datadogMeterRegistry = new DatadogMeterRegistry( config.getDatadogConfiguration(), io.micrometer.core.instrument.Clock.SYSTEM); datadogMeterRegistry.config().commonTags( - Tags.of( - "service", "chat", - "host", HostnameUtil.getLocalHostname(), - "version", WhisperServerVersion.getServerVersion(), - "env", config.getDatadogConfiguration().getEnvironment())) - .meterFilter(new MeterFilter() { - @Override - public DistributionStatisticConfig configure(final Meter.Id id, final DistributionStatisticConfig config) { - return defaultDistributionStatisticConfig.merge(config); - } - }); - - datadogMeterRegistry.config() - // Deny lettuce metrics, but leave command.completions.max - .meterFilter(MeterFilter.deny(id -> - id.getName().startsWith("lettuce") && !id.getName().contains("command.completions.max") - )) - // Remove high-cardinality `command` tags from Lettuce metrics and prepend "chat." to meter names - .meterFilter(new MeterFilter() { - @Override - public Meter.Id map(final Meter.Id id) { - if (id.getName().startsWith("lettuce")) { - return id.withName(PREFIX + "." + id.getName()) - .replaceTags(id.getTags().stream() - .filter(tag -> !"command".equals(tag.getKey())) - .toList()); - } - - return MeterFilter.super.map(id); - } - }); - + Tags.of( + "service", "chat", + "host", HostnameUtil.getLocalHostname(), + "version", WhisperServerVersion.getServerVersion(), + "env", config.getDatadogConfiguration().getEnvironment())); + configureMeterFilters(datadogMeterRegistry.config()); Metrics.addRegistry(datadogMeterRegistry); } @@ -91,6 +62,40 @@ public class MetricsUtil { environment.lifecycle().manage(new ApplicationShutdownMonitor(Metrics.globalRegistry)); } + @VisibleForTesting + static MeterRegistry.Config configureMeterFilters(MeterRegistry.Config config) { + final DistributionStatisticConfig defaultDistributionStatisticConfig = DistributionStatisticConfig.builder() + .percentiles(.75, .95, .99, .999) + .build(); + + return config + .meterFilter(new MeterFilter() { + @Override + public DistributionStatisticConfig configure(final Meter.Id id, final DistributionStatisticConfig config) { + return defaultDistributionStatisticConfig.merge(config); + } + }) + // Remove high-cardinality `command` tags from Lettuce metrics and prepend "chat." to meter names + .meterFilter(new MeterFilter() { + @Override + public Meter.Id map(final Meter.Id id) { + if (id.getName().startsWith("lettuce")) { + return id.withName(PREFIX + "." + id.getName()) + .replaceTags(id.getTags().stream() + .filter(tag -> !"command".equals(tag.getKey())) + .toList()); + } + + return MeterFilter.super.map(id); + } + }) + // Deny lettuce metrics, but leave command.completions.max. Note that regardless of configured order, accept + // filters are applied after map filters. + .meterFilter(MeterFilter.deny(id -> + id.getName().startsWith(PREFIX + ".lettuce") && !id.getName().contains("command.completion.max") + )); + } + public static void registerSystemResourceMetrics(final Environment environment) { environment.metrics().register(name(CpuUsageGauge.class, "cpu"), new CpuUsageGauge(3, TimeUnit.SECONDS)); environment.metrics().register(name(FreeMemoryGauge.class, "free_memory"), new FreeMemoryGauge()); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsUtilTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsUtilTest.java index e102d2d92..6825f4798 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsUtilTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/metrics/MetricsUtilTest.java @@ -5,8 +5,13 @@ package org.whispersystems.textsecuregcm.metrics; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import java.util.List; import org.junit.jupiter.api.Test; @@ -19,4 +24,25 @@ class MetricsUtilTest { assertEquals("chat.MetricsUtilTest.namespace.metric", MetricsUtil.name(MetricsUtilTest.class, "namespace", "metric")); } + + @Test + void lettuceRejection() { + MeterRegistry registry = new SimpleMeterRegistry(); + MetricsUtil.configureMeterFilters(registry.config()); + + registry.counter("lettuce.command.completion.count").increment(); + registry.counter("lettuce.command.firstresponse.max").increment(); + registry.counter("lettuce.test").increment(); + assertThat(registry.getMeters()).isEmpty(); + + // this lettuce statistic is allow-listed + registry.counter("lettuce.command.completion.max", "command", "hello", "remote", "world").increment(); + final List meters = registry.getMeters(); + assertThat(meters).hasSize(1); + + Meter meter = meters.get(0); + assertThat(meter.getId().getName()).isEqualTo("chat.lettuce.command.completion.max"); + assertThat(meter.getId().getTag("command")).isNull(); + assertThat(meter.getId().getTag("remote")).isNotNull(); + } }