From 53ed5d2a6a0f8e3c438c53b976ffba3983efd837 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Wed, 4 Jun 2025 13:12:08 -0400 Subject: [PATCH 01/16] Add ability to filter out metric by id name Users might want to the ability to filter out metrics that are not necessary for them to view. Created a static getMeterFilter function in MeterRegistryFactory to filter out metrics user does not want to see. Created new Property GENERAL_MICROMETER_ID_FILTERS, and filters specified via this property will be added to meter registries created in MeterInfoImpl Closes issue #4599 --- .../apache/accumulo/core/conf/Property.java | 2 + .../spi/metrics/MeterRegistryFactory.java | 37 +++++++ .../spi/metrics/MeterRegistryFactoryTest.java | 101 ++++++++++++++++++ .../server/metrics/MetricsInfoImpl.java | 13 +++ 4 files changed, 153 insertions(+) create mode 100644 core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java b/core/src/main/java/org/apache/accumulo/core/conf/Property.java index 6b0ea4ae4fb..68daa202df9 100644 --- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java +++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java @@ -362,6 +362,8 @@ public enum Property { "A comma separated list of tags to emit with all metrics from the process. Example:" + "\"tag1=value1,tag2=value2\".", "4.0.0"), + GENERAL_MICROMETER_ID_FILTERS("general.micrometer.id.filters", "", PropertyType.STRING, + "A comma separated list of patterns to deny meters with matching id names. Example: \"foo.*,bar\".", "4.0"), GENERAL_PROCESS_BIND_ADDRESS("general.process.bind.addr", "0.0.0.0", PropertyType.STRING, "The local IP address to which this server should bind for sending and receiving network traffic.", "3.0.0"), diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index 3e57cc200a1..a47b236ac95 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -19,7 +19,12 @@ package org.apache.accumulo.core.spi.metrics; import java.util.Map; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import com.google.common.base.Preconditions; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.config.MeterFilter; import org.apache.accumulo.core.spi.common.ServiceEnvironment; import io.micrometer.core.instrument.MeterRegistry; @@ -69,4 +74,36 @@ interface InitParameters { * @return a Micrometer registry that will be added to the metrics configuration. */ MeterRegistry create(final InitParameters params); + /** + * Description of what the function does. + * @param patternList Description of what this variable is, i.e. comma-delimited regext patterns + * @return description of what this function returns, i.e. a predicate + */ + static MeterFilter getMeterFilter(String patternList) { + Preconditions.checkNotNull(patternList, "patternList must not be null"); + Preconditions.checkArgument(!patternList.isEmpty(), "patternList must not be empty"); + + String[] patterns = patternList.split(","); + Predicate finalPredicate = null; + + for (String pattern : patterns) { + // Compile the pattern. + // Will throw PatternSyntaxException if invalid pattern. + Pattern compiledPattern = Pattern.compile(pattern); + + // Create a predicate that will return true if the ID's name matches the pattern. + Predicate predicate = id -> compiledPattern.matcher(id.getName()).matches(); + + if (finalPredicate == null) { + // This is the first pattern. Establish the initial predicate. + finalPredicate = predicate; + } else { + // Conjoin the pattern into the final predicates. The final predicate will return true if the name of the ID matches any of its conjoined predicates. + finalPredicate = finalPredicate.or(predicate); + } + } + + // Assert that meter filter reply == MeterFilterReply.DENY; + return MeterFilter.deny(finalPredicate); + } } diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java new file mode 100644 index 00000000000..a3e45cac6ad --- /dev/null +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java @@ -0,0 +1,101 @@ +package org.apache.accumulo.core.spi.metrics; + +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.config.MeterFilter; +import io.micrometer.core.instrument.config.MeterFilterReply; +import org.junit.Test; + +import java.util.regex.PatternSyntaxException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class MeterRegistryFactoryTest { + + /** + * Verify that when a Null pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, that we + * catch a NullPointerException and receive the errorMessage: "patternList must not be null" + */ + @Test + public void testNullPatternList () { + Throwable exception = assertThrows(NullPointerException.class, + () -> MeterRegistryFactory.getMeterFilter(null), "Expected an NPE"); + assertEquals("patternList must not be null", exception.getMessage()); + } + + /** + * Verify that when an empty pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, that we + * catch an IllegalArgumentException and receive the errorMessage: "patternList must not be empty" + */ + @Test + public void testIfEmptyPattern() { + Throwable exception = assertThrows(IllegalArgumentException.class, + () -> MeterRegistryFactory.getMeterFilter(""), "Expected an IllegalArgumentException"); + assertEquals("patternList must not be empty", exception.getMessage()); + + } + + /** + * Verify that when an invalid regex pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, + * that a PatternSyntaxException is thrown. + */ + @Test + public void testIfPatternListInvalid() { + assertThrows(PatternSyntaxException.class, + () -> MeterRegistryFactory.getMeterFilter("[\\]"), "Expected an PatternSyntaxException"); + + } + + /** + * Verify that when only one pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)} and the + * resulting filter is given an id whose name matches that pattern, that we get a reply of + * {@link MeterFilterReply#DENY}. + */ + @Test + public void testIfSinglePatternMatchesId() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter("aaa.*"); + Meter.Id id = new Meter.Id("aaaName", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); + } + + /** + * Verify that when only one pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, and the + * resulting filter is given an id whose name does not match that patten, that we get a reply of + * {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testIfSinglePatternDoesNotMatch(){ + MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*")); + Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } + + /** + * Verify that when multiple patterns are supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, and the + * resulting filter is given an id whose name matches at least one of the patterns, that we get a reply of + * {@link MeterFilterReply#DENY}. + */ + @Test + public void testIfMultiplePatternsMatches() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); + Meter.Id id = new Meter.Id("aaaRight", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); + } + + /** + * Verify that when multiple patterns are supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, and the + * resulting filter is given an id whose name matches none of the patterns, that we get a reply of + * {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testMultiplePatternsWithNoMatch() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); + Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } +} diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index 9b8613662b7..b1ba459f221 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Objects; +import io.micrometer.core.instrument.config.MeterFilter; import org.apache.accumulo.core.classloader.ClassLoaderUtil; import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.metrics.MetricsInfo; @@ -33,6 +34,7 @@ import org.apache.accumulo.core.spi.metrics.MeterRegistryFactory; import org.apache.accumulo.core.util.threads.ThreadPools; import org.apache.accumulo.server.ServerContext; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -153,10 +155,21 @@ public synchronized void init(Collection tags) { String userRegistryFactories = context.getConfiguration().get(Property.GENERAL_MICROMETER_FACTORY); + // Fetch the patterns to filter from the meter registry. + String filterPatterns = context.getConfiguration().get(Property.GENERAL_MICROMETER_ID_FILTERS); + MeterFilter meterFilter = null; + if (StringUtils.isNotEmpty(filterPatterns)) { + meterFilter = MeterRegistryFactory.getMeterFilter(filterPatterns); + } + + for (String factoryName : getTrimmedStrings(userRegistryFactories)) { try { MeterRegistry registry = getRegistryFromFactory(factoryName, context); registry.config().commonTags(commonTags); + if(meterFilter != null) { + registry.config().meterFilter(meterFilter); + } Metrics.globalRegistry.add(registry); } catch (ReflectiveOperationException ex) { LOG.warn("Could not load registry {}", factoryName, ex); From ee3f4799d597399f669ad8e82879f321a89eea53 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Wed, 4 Jun 2025 14:15:08 -0400 Subject: [PATCH 02/16] Update import statements to JUnit 5 --- .../accumulo/core/spi/metrics/MeterRegistryFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java index a3e45cac6ad..2845a370e07 100644 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java @@ -4,7 +4,7 @@ import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.core.instrument.config.MeterFilterReply; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.regex.PatternSyntaxException; From 6be621dfbf03aaf0ac56b7559c319fb3b734327d Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Wed, 4 Jun 2025 15:50:13 -0400 Subject: [PATCH 03/16] Update import statements to JUnit 5 --- .../apache/accumulo/core/conf/Property.java | 3 +- .../spi/metrics/MeterRegistryFactory.java | 12 +- .../spi/metrics/MeterRegistryFactoryTest.java | 189 ++++++++++-------- 3 files changed, 116 insertions(+), 88 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java b/core/src/main/java/org/apache/accumulo/core/conf/Property.java index 68daa202df9..9bb37a8bba4 100644 --- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java +++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java @@ -363,7 +363,8 @@ public enum Property { + "\"tag1=value1,tag2=value2\".", "4.0.0"), GENERAL_MICROMETER_ID_FILTERS("general.micrometer.id.filters", "", PropertyType.STRING, - "A comma separated list of patterns to deny meters with matching id names. Example: \"foo.*,bar\".", "4.0"), + "A comma separated list of patterns to deny meters with matching id names. Example: \"foo.*,bar\".", + "4.0"), GENERAL_PROCESS_BIND_ADDRESS("general.process.bind.addr", "0.0.0.0", PropertyType.STRING, "The local IP address to which this server should bind for sending and receiving network traffic.", "3.0.0"), diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index a47b236ac95..0b432252f5b 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -22,12 +22,13 @@ import java.util.function.Predicate; import java.util.regex.Pattern; -import com.google.common.base.Preconditions; -import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.config.MeterFilter; import org.apache.accumulo.core.spi.common.ServiceEnvironment; +import com.google.common.base.Preconditions; + +import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.config.MeterFilter; /** * The Micrometer metrics allows for different monitoring systems. and can be enabled within @@ -74,8 +75,10 @@ interface InitParameters { * @return a Micrometer registry that will be added to the metrics configuration. */ MeterRegistry create(final InitParameters params); + /** * Description of what the function does. + * * @param patternList Description of what this variable is, i.e. comma-delimited regext patterns * @return description of what this function returns, i.e. a predicate */ @@ -98,7 +101,8 @@ static MeterFilter getMeterFilter(String patternList) { // This is the first pattern. Establish the initial predicate. finalPredicate = predicate; } else { - // Conjoin the pattern into the final predicates. The final predicate will return true if the name of the ID matches any of its conjoined predicates. + // Conjoin the pattern into the final predicates. The final predicate will return true if + // the name of the ID matches any of its conjoined predicates. finalPredicate = finalPredicate.or(predicate); } } diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java index 2845a370e07..56781d8f760 100644 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java @@ -1,101 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.accumulo.core.spi.metrics; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.regex.PatternSyntaxException; + +import org.junit.jupiter.api.Test; + import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.core.instrument.config.MeterFilterReply; -import org.junit.jupiter.api.Test; - -import java.util.regex.PatternSyntaxException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; public class MeterRegistryFactoryTest { - /** - * Verify that when a Null pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, that we - * catch a NullPointerException and receive the errorMessage: "patternList must not be null" - */ - @Test - public void testNullPatternList () { - Throwable exception = assertThrows(NullPointerException.class, - () -> MeterRegistryFactory.getMeterFilter(null), "Expected an NPE"); - assertEquals("patternList must not be null", exception.getMessage()); - } + /** + * Verify that when a Null pattern is supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)}, that we catch a NullPointerException and + * receive the errorMessage: "patternList must not be null" + */ + @Test + public void testNullPatternList() { + Throwable exception = assertThrows(NullPointerException.class, + () -> MeterRegistryFactory.getMeterFilter(null), "Expected an NPE"); + assertEquals("patternList must not be null", exception.getMessage()); + } - /** - * Verify that when an empty pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, that we - * catch an IllegalArgumentException and receive the errorMessage: "patternList must not be empty" - */ - @Test - public void testIfEmptyPattern() { - Throwable exception = assertThrows(IllegalArgumentException.class, - () -> MeterRegistryFactory.getMeterFilter(""), "Expected an IllegalArgumentException"); - assertEquals("patternList must not be empty", exception.getMessage()); + /** + * Verify that when an empty pattern is supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)}, that we catch an IllegalArgumentException + * and receive the errorMessage: "patternList must not be empty" + */ + @Test + public void testIfEmptyPattern() { + Throwable exception = assertThrows(IllegalArgumentException.class, + () -> MeterRegistryFactory.getMeterFilter(""), "Expected an IllegalArgumentException"); + assertEquals("patternList must not be empty", exception.getMessage()); - } + } - /** - * Verify that when an invalid regex pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, - * that a PatternSyntaxException is thrown. - */ - @Test - public void testIfPatternListInvalid() { - assertThrows(PatternSyntaxException.class, - () -> MeterRegistryFactory.getMeterFilter("[\\]"), "Expected an PatternSyntaxException"); + /** + * Verify that when an invalid regex pattern is supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)}, that a PatternSyntaxException is thrown. + */ + @Test + public void testIfPatternListInvalid() { + assertThrows(PatternSyntaxException.class, () -> MeterRegistryFactory.getMeterFilter("[\\]"), + "Expected an PatternSyntaxException"); - } + } - /** - * Verify that when only one pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)} and the - * resulting filter is given an id whose name matches that pattern, that we get a reply of - * {@link MeterFilterReply#DENY}. - */ - @Test - public void testIfSinglePatternMatchesId() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter("aaa.*"); - Meter.Id id = new Meter.Id("aaaName", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); - } + /** + * Verify that when only one pattern is supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)} and the resulting filter is given an id + * whose name matches that pattern, that we get a reply of {@link MeterFilterReply#DENY}. + */ + @Test + public void testIfSinglePatternMatchesId() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter("aaa.*"); + Meter.Id id = new Meter.Id("aaaName", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); + } - /** - * Verify that when only one pattern is supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, and the - * resulting filter is given an id whose name does not match that patten, that we get a reply of - * {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testIfSinglePatternDoesNotMatch(){ - MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*")); - Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } + /** + * Verify that when only one pattern is supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)}, and the resulting filter is given an id + * whose name does not match that patten, that we get a reply of {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testIfSinglePatternDoesNotMatch() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*")); + Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } - /** - * Verify that when multiple patterns are supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, and the - * resulting filter is given an id whose name matches at least one of the patterns, that we get a reply of - * {@link MeterFilterReply#DENY}. - */ - @Test - public void testIfMultiplePatternsMatches() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); - Meter.Id id = new Meter.Id("aaaRight", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); - } + /** + * Verify that when multiple patterns are supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)}, and the resulting filter is given an id + * whose name matches at least one of the patterns, that we get a reply of + * {@link MeterFilterReply#DENY}. + */ + @Test + public void testIfMultiplePatternsMatches() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); + Meter.Id id = new Meter.Id("aaaRight", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); + } - /** - * Verify that when multiple patterns are supplied to {@link MeterRegistryFactory#getMeterFilter(String)}, and the - * resulting filter is given an id whose name matches none of the patterns, that we get a reply of - * {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testMultiplePatternsWithNoMatch() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); - Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } + /** + * Verify that when multiple patterns are supplied to + * {@link MeterRegistryFactory#getMeterFilter(String)}, and the resulting filter is given an id + * whose name matches none of the patterns, that we get a reply of + * {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testMultiplePatternsWithNoMatch() { + MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); + Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } } From 4e8aac62a02f9f04cf0145f5b9fdcbd4b161327e Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Wed, 4 Jun 2025 16:13:40 -0400 Subject: [PATCH 04/16] Used requireNonNull instead of Preconditions.checkNotNull --- .../accumulo/core/spi/metrics/MeterRegistryFactory.java | 4 +++- .../org/apache/accumulo/server/metrics/MetricsInfoImpl.java | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index 0b432252f5b..be8be2168b7 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -18,6 +18,8 @@ */ package org.apache.accumulo.core.spi.metrics; +import static java.util.Objects.requireNonNull; + import java.util.Map; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -83,7 +85,7 @@ interface InitParameters { * @return description of what this function returns, i.e. a predicate */ static MeterFilter getMeterFilter(String patternList) { - Preconditions.checkNotNull(patternList, "patternList must not be null"); + requireNonNull(patternList, "patternList must not be null"); Preconditions.checkArgument(!patternList.isEmpty(), "patternList must not be empty"); String[] patterns = patternList.split(","); diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index b1ba459f221..d850734858e 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.Objects; -import io.micrometer.core.instrument.config.MeterFilter; import org.apache.accumulo.core.classloader.ClassLoaderUtil; import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.metrics.MetricsInfo; @@ -50,6 +49,7 @@ import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.binder.system.ProcessorMetrics; +import io.micrometer.core.instrument.config.MeterFilter; public class MetricsInfoImpl implements MetricsInfo { @@ -162,12 +162,11 @@ public synchronized void init(Collection tags) { meterFilter = MeterRegistryFactory.getMeterFilter(filterPatterns); } - for (String factoryName : getTrimmedStrings(userRegistryFactories)) { try { MeterRegistry registry = getRegistryFromFactory(factoryName, context); registry.config().commonTags(commonTags); - if(meterFilter != null) { + if (meterFilter != null) { registry.config().meterFilter(meterFilter); } Metrics.globalRegistry.add(registry); From 97fa2e14d77326c2c8d9bf4cb8a76e6cc9e8d6ba Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Thu, 5 Jun 2025 09:23:08 -0400 Subject: [PATCH 05/16] Edited return case for getMeterFilter. Allow MeterFilter class in apilyzer configuration. --- core/pom.xml | 1 + .../apache/accumulo/core/spi/metrics/MeterRegistryFactory.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 028db73ef3d..481f309800d 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -299,6 +299,7 @@ io[.]micrometer[.]core[.]instrument[.]MeterRegistry + io[.]micrometer[.]core[.]instrument[.]config[.]MeterFilter io[.]opentelemetry[.]api[.]OpenTelemetry org[.]apache[.]hadoop[.]io[.]Text org[.]apache[.]accumulo[.]core[.]client[.].* diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index be8be2168b7..3365ba260a9 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull; import java.util.Map; +import java.util.Objects; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -110,6 +111,6 @@ static MeterFilter getMeterFilter(String patternList) { } // Assert that meter filter reply == MeterFilterReply.DENY; - return MeterFilter.deny(finalPredicate); + return MeterFilter.deny(Objects.requireNonNullElseGet(finalPredicate, () -> t -> false)); } } From d65453ec2a9fc858876afc5f37e70803fcdbec7e Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Thu, 5 Jun 2025 09:47:33 -0400 Subject: [PATCH 06/16] Edited return case for getMeterFilter. Allow MeterFilter class in apilyzer configuration. --- .../apache/accumulo/core/spi/metrics/MeterRegistryFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index 3365ba260a9..426c3a92246 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -111,6 +111,6 @@ static MeterFilter getMeterFilter(String patternList) { } // Assert that meter filter reply == MeterFilterReply.DENY; - return MeterFilter.deny(Objects.requireNonNullElseGet(finalPredicate, () -> t -> false)); + return MeterFilter.deny(Objects.requireNonNullElseGet(finalPredicate, () -> t -> false)); } } From 393fdb7ee424f59fbb873f1f482a96fe3619e10c Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Thu, 12 Jun 2025 14:05:11 -0400 Subject: [PATCH 07/16] Moved getMeterFilter function from MeterRegistryFactory.java to MetricsInfoImpl.java. Moved MeterRegistryFactoryTest.java test cases into the MetricsInfoImplTest.java file and changed variable types to reflect the new location of the code. --- .../spi/metrics/MeterRegistryFactory.java | 34 ----- .../spi/metrics/MeterRegistryFactoryTest.java | 124 ------------------ .../server/metrics/MetricsInfoImpl.java | 42 +++++- .../server/metrics/MetricsInfoImplTest.java | 97 ++++++++++++++ 4 files changed, 138 insertions(+), 159 deletions(-) delete mode 100644 core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index 426c3a92246..1869e810cd5 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -79,38 +79,4 @@ interface InitParameters { */ MeterRegistry create(final InitParameters params); - /** - * Description of what the function does. - * - * @param patternList Description of what this variable is, i.e. comma-delimited regext patterns - * @return description of what this function returns, i.e. a predicate - */ - static MeterFilter getMeterFilter(String patternList) { - requireNonNull(patternList, "patternList must not be null"); - Preconditions.checkArgument(!patternList.isEmpty(), "patternList must not be empty"); - - String[] patterns = patternList.split(","); - Predicate finalPredicate = null; - - for (String pattern : patterns) { - // Compile the pattern. - // Will throw PatternSyntaxException if invalid pattern. - Pattern compiledPattern = Pattern.compile(pattern); - - // Create a predicate that will return true if the ID's name matches the pattern. - Predicate predicate = id -> compiledPattern.matcher(id.getName()).matches(); - - if (finalPredicate == null) { - // This is the first pattern. Establish the initial predicate. - finalPredicate = predicate; - } else { - // Conjoin the pattern into the final predicates. The final predicate will return true if - // the name of the ID matches any of its conjoined predicates. - finalPredicate = finalPredicate.or(predicate); - } - } - - // Assert that meter filter reply == MeterFilterReply.DENY; - return MeterFilter.deny(Objects.requireNonNullElseGet(finalPredicate, () -> t -> false)); - } } diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java deleted file mode 100644 index 56781d8f760..00000000000 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactoryTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.accumulo.core.spi.metrics; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.util.regex.PatternSyntaxException; - -import org.junit.jupiter.api.Test; - -import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.Tags; -import io.micrometer.core.instrument.config.MeterFilter; -import io.micrometer.core.instrument.config.MeterFilterReply; - -public class MeterRegistryFactoryTest { - - /** - * Verify that when a Null pattern is supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)}, that we catch a NullPointerException and - * receive the errorMessage: "patternList must not be null" - */ - @Test - public void testNullPatternList() { - Throwable exception = assertThrows(NullPointerException.class, - () -> MeterRegistryFactory.getMeterFilter(null), "Expected an NPE"); - assertEquals("patternList must not be null", exception.getMessage()); - } - - /** - * Verify that when an empty pattern is supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)}, that we catch an IllegalArgumentException - * and receive the errorMessage: "patternList must not be empty" - */ - @Test - public void testIfEmptyPattern() { - Throwable exception = assertThrows(IllegalArgumentException.class, - () -> MeterRegistryFactory.getMeterFilter(""), "Expected an IllegalArgumentException"); - assertEquals("patternList must not be empty", exception.getMessage()); - - } - - /** - * Verify that when an invalid regex pattern is supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)}, that a PatternSyntaxException is thrown. - */ - @Test - public void testIfPatternListInvalid() { - assertThrows(PatternSyntaxException.class, () -> MeterRegistryFactory.getMeterFilter("[\\]"), - "Expected an PatternSyntaxException"); - - } - - /** - * Verify that when only one pattern is supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)} and the resulting filter is given an id - * whose name matches that pattern, that we get a reply of {@link MeterFilterReply#DENY}. - */ - @Test - public void testIfSinglePatternMatchesId() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter("aaa.*"); - Meter.Id id = new Meter.Id("aaaName", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); - } - - /** - * Verify that when only one pattern is supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)}, and the resulting filter is given an id - * whose name does not match that patten, that we get a reply of {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testIfSinglePatternDoesNotMatch() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*")); - Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } - - /** - * Verify that when multiple patterns are supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)}, and the resulting filter is given an id - * whose name matches at least one of the patterns, that we get a reply of - * {@link MeterFilterReply#DENY}. - */ - @Test - public void testIfMultiplePatternsMatches() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); - Meter.Id id = new Meter.Id("aaaRight", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); - } - - /** - * Verify that when multiple patterns are supplied to - * {@link MeterRegistryFactory#getMeterFilter(String)}, and the resulting filter is given an id - * whose name matches none of the patterns, that we get a reply of - * {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testMultiplePatternsWithNoMatch() { - MeterFilter filter = MeterRegistryFactory.getMeterFilter(("aaa.*,bbb.*,ccc.*")); - Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } -} diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index d850734858e..d1a030df885 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -18,6 +18,7 @@ */ package org.apache.accumulo.server.metrics; +import static java.util.Objects.requireNonNull; import static org.apache.hadoop.util.StringUtils.getTrimmedStrings; import java.util.ArrayList; @@ -25,7 +26,11 @@ import java.util.Collection; import java.util.List; import java.util.Objects; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import com.google.common.base.Preconditions; +import io.micrometer.core.instrument.Meter; import org.apache.accumulo.core.classloader.ClassLoaderUtil; import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.metrics.MetricsInfo; @@ -159,7 +164,7 @@ public synchronized void init(Collection tags) { String filterPatterns = context.getConfiguration().get(Property.GENERAL_MICROMETER_ID_FILTERS); MeterFilter meterFilter = null; if (StringUtils.isNotEmpty(filterPatterns)) { - meterFilter = MeterRegistryFactory.getMeterFilter(filterPatterns); + meterFilter = getMeterFilter(filterPatterns); } for (String factoryName : getTrimmedStrings(userRegistryFactories)) { @@ -248,6 +253,41 @@ public synchronized void close() { Metrics.globalRegistry.close(); } + /** + * Description of what the function does. + * + * @param patternList Description of what this variable is, i.e. comma-delimited regext patterns + * @return description of what this function returns, i.e. a predicate + */ + public static MeterFilter getMeterFilter(String patternList) { + requireNonNull(patternList, "patternList must not be null"); + Preconditions.checkArgument(!patternList.isEmpty(), "patternList must not be empty"); + + String[] patterns = patternList.split(","); + Predicate finalPredicate = null; + + for (String pattern : patterns) { + // Compile the pattern. + // Will throw PatternSyntaxException if invalid pattern. + Pattern compiledPattern = Pattern.compile(pattern); + + // Create a predicate that will return true if the ID's name matches the pattern. + Predicate predicate = id -> compiledPattern.matcher(id.getName()).matches(); + + if (finalPredicate == null) { + // This is the first pattern. Establish the initial predicate. + finalPredicate = predicate; + } else { + // Conjoin the pattern into the final predicates. The final predicate will return true if + // the name of the ID matches any of its conjoined predicates. + finalPredicate = finalPredicate.or(predicate); + } + } + + // Assert that meter filter reply == MeterFilterReply.DENY; + return MeterFilter.deny(Objects.requireNonNullElseGet(finalPredicate, () -> t -> false)); + } + @Override public synchronized String toString() { return "MetricsCommonTags{tags=" + commonTags + '}'; diff --git a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java index f3bb320c3bc..8664cec04c9 100644 --- a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java +++ b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java @@ -23,12 +23,19 @@ import static org.easymock.EasyMock.mock; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Map; +import java.util.regex.PatternSyntaxException; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.Tags; +import io.micrometer.core.instrument.config.MeterFilter; +import io.micrometer.core.instrument.config.MeterFilterReply; import org.apache.accumulo.core.conf.AccumuloConfiguration; +import org.apache.accumulo.core.spi.metrics.MeterRegistryFactory; import org.apache.accumulo.server.ServerContext; import org.junit.jupiter.api.Test; @@ -64,4 +71,94 @@ public MeterRegistry create(final InitParameters params) { return new SimpleMeterRegistry(); } } + + /** + * Verify that when a Null pattern is supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, that we catch a NullPointerException and + * receive the errorMessage: "patternList must not be null" + */ + @Test + public void testNullPatternList() { + Throwable exception = assertThrows(NullPointerException.class, + () -> MetricsInfoImpl.getMeterFilter(null), "Expected an NPE"); + assertEquals("patternList must not be null", exception.getMessage()); + } + + /** + * Verify that when an empty pattern is supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, that we catch an IllegalArgumentException + * and receive the errorMessage: "patternList must not be empty" + */ + @Test + public void testIfEmptyPattern() { + Throwable exception = assertThrows(IllegalArgumentException.class, + () -> MetricsInfoImpl.getMeterFilter(""), "Expected an IllegalArgumentException"); + assertEquals("patternList must not be empty", exception.getMessage()); + + } + + /** + * Verify that when an invalid regex pattern is supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, that a PatternSyntaxException is thrown. + */ + @Test + public void testIfPatternListInvalid() { + assertThrows(PatternSyntaxException.class, () -> MetricsInfoImpl.getMeterFilter("[\\]"), + "Expected an PatternSyntaxException"); + + } + + /** + * Verify that when only one pattern is supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)} and the resulting filter is given an id + * whose name matches that pattern, that we get a reply of {@link MeterFilterReply#DENY}. + */ + @Test + public void testIfSinglePatternMatchesId() { + MeterFilter filter = MetricsInfoImpl.getMeterFilter("aaa.*"); + Meter.Id id = new Meter.Id("aaaName", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); + } + + /** + * Verify that when only one pattern is supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id + * whose name does not match that patten, that we get a reply of {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testIfSinglePatternDoesNotMatch() { + MeterFilter filter = MetricsInfoImpl.getMeterFilter(("aaa.*")); + Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } + + /** + * Verify that when multiple patterns are supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id + * whose name matches at least one of the patterns, that we get a reply of + * {@link MeterFilterReply#DENY}. + */ + @Test + public void testIfMultiplePatternsMatches() { + MeterFilter filter = MetricsInfoImpl.getMeterFilter(("aaa.*,bbb.*,ccc.*")); + Meter.Id id = new Meter.Id("aaaRight", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); + } + + /** + * Verify that when multiple patterns are supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id + * whose name matches none of the patterns, that we get a reply of + * {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testMultiplePatternsWithNoMatch() { + MeterFilter filter = MetricsInfoImpl.getMeterFilter(("aaa.*,bbb.*,ccc.*")); + Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } } From 5c6cda83513c7db8e3cc073a1044706dacb73b00 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Thu, 12 Jun 2025 14:14:36 -0400 Subject: [PATCH 08/16] Moved getMeterFilter function from MeterRegistryFactory.java to MetricsInfoImpl.java. Moved MeterRegistryFactoryTest.java test cases into the MetricsInfoImplTest.java file and changed variable types to reflect the new location of the code. --- .../spi/metrics/MeterRegistryFactory.java | 9 ---- .../server/metrics/MetricsInfoImpl.java | 4 +- .../server/metrics/MetricsInfoImplTest.java | 43 +++++++++---------- 3 files changed, 23 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index 1869e810cd5..a584f046921 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -18,20 +18,11 @@ */ package org.apache.accumulo.core.spi.metrics; -import static java.util.Objects.requireNonNull; - import java.util.Map; -import java.util.Objects; -import java.util.function.Predicate; -import java.util.regex.Pattern; import org.apache.accumulo.core.spi.common.ServiceEnvironment; -import com.google.common.base.Preconditions; - -import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.config.MeterFilter; /** * The Micrometer metrics allows for different monitoring systems. and can be enabled within diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index d1a030df885..308dfdf10aa 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -29,8 +29,6 @@ import java.util.function.Predicate; import java.util.regex.Pattern; -import com.google.common.base.Preconditions; -import io.micrometer.core.instrument.Meter; import org.apache.accumulo.core.classloader.ClassLoaderUtil; import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.metrics.MetricsInfo; @@ -43,7 +41,9 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; diff --git a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java index 8664cec04c9..91c146bdeb8 100644 --- a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java +++ b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java @@ -30,16 +30,16 @@ import java.util.Map; import java.util.regex.PatternSyntaxException; -import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.Tags; -import io.micrometer.core.instrument.config.MeterFilter; -import io.micrometer.core.instrument.config.MeterFilterReply; import org.apache.accumulo.core.conf.AccumuloConfiguration; import org.apache.accumulo.core.spi.metrics.MeterRegistryFactory; import org.apache.accumulo.server.ServerContext; import org.junit.jupiter.api.Test; +import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; +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.simple.SimpleMeterRegistry; public class MetricsInfoImplTest { @@ -73,26 +73,26 @@ public MeterRegistry create(final InitParameters params) { } /** - * Verify that when a Null pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, that we catch a NullPointerException and - * receive the errorMessage: "patternList must not be null" + * Verify that when a Null pattern is supplied to {@link MetricsInfoImpl#getMeterFilter(String)}, + * that we catch a NullPointerException and receive the errorMessage: "patternList must not be + * null" */ @Test public void testNullPatternList() { Throwable exception = assertThrows(NullPointerException.class, - () -> MetricsInfoImpl.getMeterFilter(null), "Expected an NPE"); + () -> MetricsInfoImpl.getMeterFilter(null), "Expected an NPE"); assertEquals("patternList must not be null", exception.getMessage()); } /** * Verify that when an empty pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, that we catch an IllegalArgumentException - * and receive the errorMessage: "patternList must not be empty" + * {@link MetricsInfoImpl#getMeterFilter(String)}, that we catch an IllegalArgumentException and + * receive the errorMessage: "patternList must not be empty" */ @Test public void testIfEmptyPattern() { Throwable exception = assertThrows(IllegalArgumentException.class, - () -> MetricsInfoImpl.getMeterFilter(""), "Expected an IllegalArgumentException"); + () -> MetricsInfoImpl.getMeterFilter(""), "Expected an IllegalArgumentException"); assertEquals("patternList must not be empty", exception.getMessage()); } @@ -104,14 +104,14 @@ public void testIfEmptyPattern() { @Test public void testIfPatternListInvalid() { assertThrows(PatternSyntaxException.class, () -> MetricsInfoImpl.getMeterFilter("[\\]"), - "Expected an PatternSyntaxException"); + "Expected an PatternSyntaxException"); } /** - * Verify that when only one pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)} and the resulting filter is given an id - * whose name matches that pattern, that we get a reply of {@link MeterFilterReply#DENY}. + * Verify that when only one pattern is supplied to {@link MetricsInfoImpl#getMeterFilter(String)} + * and the resulting filter is given an id whose name matches that pattern, that we get a reply of + * {@link MeterFilterReply#DENY}. */ @Test public void testIfSinglePatternMatchesId() { @@ -123,8 +123,8 @@ public void testIfSinglePatternMatchesId() { /** * Verify that when only one pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id - * whose name does not match that patten, that we get a reply of {@link MeterFilterReply#NEUTRAL}. + * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose + * name does not match that patten, that we get a reply of {@link MeterFilterReply#NEUTRAL}. */ @Test public void testIfSinglePatternDoesNotMatch() { @@ -136,8 +136,8 @@ public void testIfSinglePatternDoesNotMatch() { /** * Verify that when multiple patterns are supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id - * whose name matches at least one of the patterns, that we get a reply of + * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose + * name matches at least one of the patterns, that we get a reply of * {@link MeterFilterReply#DENY}. */ @Test @@ -150,9 +150,8 @@ public void testIfMultiplePatternsMatches() { /** * Verify that when multiple patterns are supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id - * whose name matches none of the patterns, that we get a reply of - * {@link MeterFilterReply#NEUTRAL}. + * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose + * name matches none of the patterns, that we get a reply of {@link MeterFilterReply#NEUTRAL}. */ @Test public void testMultiplePatternsWithNoMatch() { From b67af87f8ab6066db935902dc5fd0115149d88b6 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Mon, 23 Jun 2025 11:15:49 -0400 Subject: [PATCH 09/16] Changed line 370 in Propety.java from "4.0" to "4.0.0". In the getMeterFilter function in MetricsInfoImpl, trimmed whitespace from patternList, set finalPredicate to id->false instead of null to OR the predicates together without having to set the first predicate equal to finalPredicate and so that the return statement doesn't have to include reuireNonNullElseGet --- .../apache/accumulo/core/conf/Property.java | 2 +- .../server/metrics/MetricsInfoImpl.java | 25 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java b/core/src/main/java/org/apache/accumulo/core/conf/Property.java index fa6a7c622e1..cd854ef02b2 100644 --- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java +++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java @@ -367,7 +367,7 @@ public enum Property { "4.0.0"), GENERAL_MICROMETER_ID_FILTERS("general.micrometer.id.filters", "", PropertyType.STRING, "A comma separated list of patterns to deny meters with matching id names. Example: \"foo.*,bar\".", - "4.0"), + "4.0.0"), // TODO: Make sure to backport this to 3.1, then remove here in 4.0 @Deprecated(since = "3.1.0") @ReplacedBy(property = RPC_PROCESS_BIND_ADDRESS) diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index 59b9d3cc380..cea9ff5003a 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -255,17 +255,21 @@ public synchronized void close() { } /** - * Description of what the function does. + * This function uses patterns specified in the patternList parameter to filter out specific metrics that the user + * doesn't want. * - * @param patternList Description of what this variable is, i.e. comma-delimited regext patterns - * @return description of what this function returns, i.e. a predicate + * @param patternList, a comma-delimited String of regext patterns that getMeterFilter uses to filter metrics. + * @return a predicate with the type of MeterFilter, that describes which metrics to filter. */ public static MeterFilter getMeterFilter(String patternList) { requireNonNull(patternList, "patternList must not be null"); Preconditions.checkArgument(!patternList.isEmpty(), "patternList must not be empty"); + // Trims whitespace and all other non-visible characters. + patternList = patternList.replaceAll("\\s+",""); String[] patterns = patternList.split(","); - Predicate finalPredicate = null; + Predicate finalPredicate = id->false; + for (String pattern : patterns) { // Compile the pattern. @@ -275,18 +279,13 @@ public static MeterFilter getMeterFilter(String patternList) { // Create a predicate that will return true if the ID's name matches the pattern. Predicate predicate = id -> compiledPattern.matcher(id.getName()).matches(); - if (finalPredicate == null) { - // This is the first pattern. Establish the initial predicate. - finalPredicate = predicate; - } else { - // Conjoin the pattern into the final predicates. The final predicate will return true if - // the name of the ID matches any of its conjoined predicates. - finalPredicate = finalPredicate.or(predicate); - } + // Conjoin the pattern into the final predicates. The final predicate will return true if + // the name of the ID matches any of its conjoined predicates. + finalPredicate = finalPredicate.or(predicate); } // Assert that meter filter reply == MeterFilterReply.DENY; - return MeterFilter.deny(Objects.requireNonNullElseGet(finalPredicate, () -> t -> false)); + return MeterFilter.deny(finalPredicate); } @Override From ea7edd2c0055f544d69e7f6ed6ee63c30fb50ca7 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Tue, 24 Jun 2025 12:26:13 -0400 Subject: [PATCH 10/16] Allowed an empty pattern to be supplied to the getMeterFilter function, which results in no filters being applied. Changed JUnit tests to test this case, and deleted the previous JUnit test that tests if an empty pattern throws an exception (that no longer applies). Changed code formatting. --- .../server/metrics/MetricsInfoImpl.java | 15 +++++----- .../server/metrics/MetricsInfoImplTest.java | 30 +++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index cea9ff5003a..5f9253a2060 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -41,7 +41,6 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Preconditions; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; @@ -255,21 +254,21 @@ public synchronized void close() { } /** - * This function uses patterns specified in the patternList parameter to filter out specific metrics that the user - * doesn't want. + * This function uses patterns specified in the patternList parameter to filter out specific + * metrics that the user doesn't want. * - * @param patternList, a comma-delimited String of regext patterns that getMeterFilter uses to filter metrics. + * @param patternList, a comma-delimited String of regext patterns that getMeterFilter uses to + * filter metrics. * @return a predicate with the type of MeterFilter, that describes which metrics to filter. */ public static MeterFilter getMeterFilter(String patternList) { requireNonNull(patternList, "patternList must not be null"); - Preconditions.checkArgument(!patternList.isEmpty(), "patternList must not be empty"); + // Trims whitespace and all other non-visible characters. - patternList = patternList.replaceAll("\\s+",""); + patternList = patternList.replaceAll("\\s+", ""); String[] patterns = patternList.split(","); - Predicate finalPredicate = id->false; - + Predicate finalPredicate = id -> false; for (String pattern : patterns) { // Compile the pattern. diff --git a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java index 91c146bdeb8..7b810672518 100644 --- a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java +++ b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java @@ -31,7 +31,6 @@ import java.util.regex.PatternSyntaxException; import org.apache.accumulo.core.conf.AccumuloConfiguration; -import org.apache.accumulo.core.spi.metrics.MeterRegistryFactory; import org.apache.accumulo.server.ServerContext; import org.junit.jupiter.api.Test; @@ -84,19 +83,6 @@ public void testNullPatternList() { assertEquals("patternList must not be null", exception.getMessage()); } - /** - * Verify that when an empty pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, that we catch an IllegalArgumentException and - * receive the errorMessage: "patternList must not be empty" - */ - @Test - public void testIfEmptyPattern() { - Throwable exception = assertThrows(IllegalArgumentException.class, - () -> MetricsInfoImpl.getMeterFilter(""), "Expected an IllegalArgumentException"); - assertEquals("patternList must not be empty", exception.getMessage()); - - } - /** * Verify that when an invalid regex pattern is supplied to * {@link MetricsInfoImpl#getMeterFilter(String)}, that a PatternSyntaxException is thrown. @@ -121,10 +107,24 @@ public void testIfSinglePatternMatchesId() { assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); } + /** + * Verify that when an empty pattern is supplied to + * {@link MetricsInfoImpl#getMeterFilter(String)}, then no matter what the id is we get a reply of + * {@link MeterFilterReply#NEUTRAL}. + */ + @Test + public void testThatEmptyPatternDoesNotMatchId() { + MeterFilter filter = MetricsInfoImpl.getMeterFilter(""); + Meter.Id id = + new Meter.Id("shouldnotmatch", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); + MeterFilterReply reply = filter.accept(id); + assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); + } + /** * Verify that when only one pattern is supplied to * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose - * name does not match that patten, that we get a reply of {@link MeterFilterReply#NEUTRAL}. + * name does not match that pattern, that we get a reply of {@link MeterFilterReply#NEUTRAL}. */ @Test public void testIfSinglePatternDoesNotMatch() { From e3b105c61b2374c493064105121791da1955e736 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Thu, 26 Jun 2025 15:45:01 -0400 Subject: [PATCH 11/16] Build should be successful --- .../org/apache/accumulo/server/metrics/MetricsInfoImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index 5f9253a2060..26b79ef5c9f 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -274,10 +274,8 @@ public static MeterFilter getMeterFilter(String patternList) { // Compile the pattern. // Will throw PatternSyntaxException if invalid pattern. Pattern compiledPattern = Pattern.compile(pattern); - // Create a predicate that will return true if the ID's name matches the pattern. Predicate predicate = id -> compiledPattern.matcher(id.getName()).matches(); - // Conjoin the pattern into the final predicates. The final predicate will return true if // the name of the ID matches any of its conjoined predicates. finalPredicate = finalPredicate.or(predicate); From 40f3da5085a95d6d4adabca6786ec0432c2f224a Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Mon, 30 Jun 2025 15:57:31 -0400 Subject: [PATCH 12/16] Moved getMeterFilter into LoggingMeterRegistryFactory.java and created tests. --- .../apache/accumulo/core/conf/Property.java | 3 - .../metrics/LoggingMeterRegistryFactory.java | 65 +++++++++- .../LoggingMeterRegistryFactoryTest.java | 119 +++++++++++++++++- .../server/metrics/MetricsInfoImpl.java | 47 ------- .../server/metrics/MetricsInfoImplTest.java | 96 -------------- 5 files changed, 181 insertions(+), 149 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java b/core/src/main/java/org/apache/accumulo/core/conf/Property.java index cd854ef02b2..1e2220dc3a5 100644 --- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java +++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java @@ -365,9 +365,6 @@ public enum Property { "A comma separated list of tags to emit with all metrics from the process. Example:" + "\"tag1=value1,tag2=value2\".", "4.0.0"), - GENERAL_MICROMETER_ID_FILTERS("general.micrometer.id.filters", "", PropertyType.STRING, - "A comma separated list of patterns to deny meters with matching id names. Example: \"foo.*,bar\".", - "4.0.0"), // TODO: Make sure to backport this to 3.1, then remove here in 4.0 @Deprecated(since = "3.1.0") @ReplacedBy(property = RPC_PROCESS_BIND_ADDRESS) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java index 2e24726e869..46d9e9a19b6 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java @@ -18,14 +18,19 @@ */ package org.apache.accumulo.core.spi.metrics; +import static java.util.Objects.requireNonNull; + import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Predicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.config.MeterFilter; import io.micrometer.core.instrument.logging.LoggingMeterRegistry; import io.micrometer.core.instrument.logging.LoggingRegistryConfig; @@ -49,6 +54,21 @@ *
  *     general.custom.metrics.opts.logging.step = 10s
  * 
+ * + * To filter out meters that start with any particular prefix, set + * {@code general.custom.metrics.opts.meter.id.filters} in the Accumulo configuration. + * + *
+ *      general.custom.metrics.opts.meter.id.filters = prefix1,prefix2,prefix3
+ *
+ * 
+ * + * To assign a custom delimiter to filters, set + * {@code general.custom.metrics.opts.meter.id.delimiter} in the Accumulo configuration. + * + *
+ * general.custom.metrics.opts.meter.id.delimiter = delimiter
+ * 
*/ public class LoggingMeterRegistryFactory implements MeterRegistryFactory { @@ -76,6 +96,49 @@ public MeterRegistry create(final InitParameters params) { LOG.info("Creating logging metrics registry with params: {}", params); metricsProps.putAll(params.getOptions()); - return LoggingMeterRegistry.builder(lconf).loggingSink(metricConsumer).build(); + + MeterRegistry registry = + LoggingMeterRegistry.builder(lconf).loggingSink(metricConsumer).build(); + String filters = metricsProps.get("meter.id.filters"); + // Sets the default delimiter if none is specified + String delimiter = metricsProps.getOrDefault("meter.id.delimiter", ","); + + if (filters != null && delimiter != null) { + registry.config().meterFilter(getMeterFilter(filters, delimiter)); + } + return registry; + } + + /** + * This function uses terms specified in the patternList parameter to filter out specific metrics + * that the user doesn't want. + * + * @param patternList, a delimited set of terms that will filter out meters that start with any + * one of those terms. + * @param delimiter, that contains either a user specified delimiter, or the default comma + * delimiter to split the patternList. + * @return a predicate with the type of MeterFilter, that describes which metrics to deny and + * subsequently filter out. + */ + public static MeterFilter getMeterFilter(String patternList, String delimiter) { + requireNonNull(patternList, "patternList must not be null"); + + // Trims whitespace and all other non-visible characters. + patternList = patternList.replaceAll("\\s+", ""); + + // Gets the default delimiter or the delimiter the user supplied + String[] patterns = patternList.split(delimiter); + Predicate finalPredicate = id -> false; + + if (patternList.isEmpty()) { + return MeterFilter.deny(finalPredicate); + } + + for (String prefix : patterns) { + Predicate predicate = id -> id.getName().startsWith(prefix); + finalPredicate = finalPredicate.or(predicate); + + } + return MeterFilter.deny(finalPredicate); } } diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java index 9d628d27752..41951ffa6f3 100644 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java @@ -18,13 +18,17 @@ */ package org.apache.accumulo.core.spi.metrics; +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import java.util.List; import java.util.Map; import org.apache.accumulo.core.spi.common.ServiceEnvironment; import org.junit.jupiter.api.Test; +import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.logging.LoggingMeterRegistry; class LoggingMeterRegistryFactoryTest { @@ -32,16 +36,24 @@ class LoggingMeterRegistryFactoryTest { @Test public void createTest() { LoggingMeterRegistryFactory factory = new LoggingMeterRegistryFactory(); - var reg = factory.create(new LoggingMetricsParams()); + var reg = + factory.create(new LoggingMetricsParams(Map.of("prop1", "abc", "logging.step", "1s"))); assertInstanceOf(LoggingMeterRegistry.class, reg); } private static class LoggingMetricsParams implements MeterRegistryFactory.InitParameters { + private Map options; + + public LoggingMetricsParams(Map options) { + this.options = options; + } + @Override public Map getOptions() { + return options; // note: general.custom.metrics.opts. is expected to be stripped before passing the options. - return Map.of("prop1", "abc", "logging.step", "1s"); + // return Map.of("prop1", "abc", "logging.step", "1s", "meter.id.filters", "Foo,Bar,Hat"); } @Override @@ -49,4 +61,107 @@ public ServiceEnvironment getServiceEnv() { return null; } } + + /** + * Create a factory and test that the given filters are applied to all ID's that match the given + * meter.id.filters. + */ + @Test + public void createWithFilters() { + LoggingMeterRegistryFactory factory = new LoggingMeterRegistryFactory(); + var reg = factory.create(new LoggingMetricsParams( + Map.of("prop1", "abc", "logging.step", "1s", "meter.id.filters", "Foo,Bar,Hat"))); + reg.timer("FooTimer", "tag1", "tag2"); // Yes filters this out + reg.timer("ProperTimer", "tag1", "tag2"); + + List meterReg = reg.getMeters(); // Does this only contain ProperTimer? Yes + assertEquals("ProperTimer", meterReg.get(0).getId().getName()); + } + + /** + * Verify that the filters can be split by either the default or user-specified delimiter. + */ + @Test + public void testNonCommaDelimiter() { + LoggingMeterRegistryFactory factory = new LoggingMeterRegistryFactory(); + var reg = factory.create(new LoggingMetricsParams(Map.of("prop1", "abc", "logging.step", "1s", + "meter.id.filters", "Foo:Bar:Hat", "meter.id.delimiter", ":"))); + reg.timer("FooTimer", "tag1", "tag2"); + reg.timer("ProperTimer", "tag1", "tag2"); + reg.timer("BarTimer", "tag1", "tag2"); + reg.timer("HatTimer", "tag1", "tag2"); + reg.gauge("BarGauge", 10); + reg.gauge("ProperGauge", 10); + reg.counter("HatCounter", "tag1", "tag2"); + reg.counter("ProperCounter", "tag1", "tag2"); + + List meterReg = reg.getMeters(); + String allMeters = ""; + for (Meter m : meterReg) { + allMeters = allMeters + m.getId().getName(); + } + + assertFalse(allMeters.contains("Foo")); + assertFalse(allMeters.contains("Bar")); + assertFalse(allMeters.contains("Hat")); + } + + /** + * Verify that {@link LoggingMeterRegistryFactory#getMeterFilter(String, String)} only filters out + * meters where the filter terms are prefixes for the ID. + */ + @Test + public void testIfPatternIsNotFirst() { + LoggingMeterRegistryFactory factory = new LoggingMeterRegistryFactory(); + var reg = factory.create(new LoggingMetricsParams( + Map.of("prop1", "abc", "logging.step", "1s", "meter.id.filters", "Foo,Bar,Hat"))); + reg.timer("FooTimer", "tag1", "tag2"); + reg.timer("TimerFoo", "tag1", "tag2"); + + List meterReg = reg.getMeters(); + String allMeters = ""; + for (Meter m : meterReg) { + allMeters = allMeters + m.getId().getName(); + } + assertEquals("TimerFoo", allMeters); + } + + /** + * Test that {@link LoggingMeterRegistryFactory#getMeterFilter(String, String)} can filter out + * meters correctly even when given duplicates. + */ + @Test + public void testIfDuplicatePatterns() { + LoggingMeterRegistryFactory factory = new LoggingMeterRegistryFactory(); + var reg = factory.create(new LoggingMetricsParams( + Map.of("prop1", "abc", "logging.step", "1s", "meter.id.filters", "Foo,Foo,Foo"))); + reg.timer("FooTimer", "tag1", "tag2"); + + List meterReg = reg.getMeters(); + String allMeters = ""; + for (Meter m : meterReg) { + allMeters = allMeters + m.getId().getName(); + } + + assertEquals("", allMeters); + } + + /** + * Test that when {@link LoggingMeterRegistryFactory#getMeterFilter(String, String)} is given an + * empty string of filters, all IDs are still passed through. + */ + @Test + public void testEmptyPatternList() { + LoggingMeterRegistryFactory factory = new LoggingMeterRegistryFactory(); + var reg = factory.create(new LoggingMetricsParams( + Map.of("prop1", "abc", "logging.step", "1s", "meter.id.filters", ""))); + reg.timer("FooTimer", "tag1", "tag2"); + List meterReg = reg.getMeters(); + String allMeters = ""; + for (Meter m : meterReg) { + allMeters = allMeters + m.getId().getName(); + } + assertEquals("FooTimer", allMeters); + } + } diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index 26b79ef5c9f..512955fec5b 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -26,8 +26,6 @@ import java.util.Collection; import java.util.List; import java.util.Objects; -import java.util.function.Predicate; -import java.util.regex.Pattern; import org.apache.accumulo.core.classloader.ClassLoaderUtil; import org.apache.accumulo.core.conf.Property; @@ -36,13 +34,11 @@ import org.apache.accumulo.core.spi.metrics.MeterRegistryFactory; import org.apache.accumulo.core.util.threads.ThreadPools; import org.apache.accumulo.server.ServerContext; -import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; -import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; @@ -53,7 +49,6 @@ import io.micrometer.core.instrument.binder.logging.Log4j2Metrics; import io.micrometer.core.instrument.binder.logging.LogbackMetrics; import io.micrometer.core.instrument.binder.system.ProcessorMetrics; -import io.micrometer.core.instrument.config.MeterFilter; public class MetricsInfoImpl implements MetricsInfo { @@ -160,20 +155,10 @@ public synchronized void init(Collection tags) { String userRegistryFactories = context.getConfiguration().get(Property.GENERAL_MICROMETER_FACTORY); - // Fetch the patterns to filter from the meter registry. - String filterPatterns = context.getConfiguration().get(Property.GENERAL_MICROMETER_ID_FILTERS); - MeterFilter meterFilter = null; - if (StringUtils.isNotEmpty(filterPatterns)) { - meterFilter = getMeterFilter(filterPatterns); - } - for (String factoryName : getTrimmedStrings(userRegistryFactories)) { try { MeterRegistry registry = getRegistryFromFactory(factoryName, context); registry.config().commonTags(commonTags); - if (meterFilter != null) { - registry.config().meterFilter(meterFilter); - } Metrics.globalRegistry.add(registry); } catch (ReflectiveOperationException ex) { LOG.warn("Could not load registry {}", factoryName, ex); @@ -253,38 +238,6 @@ public synchronized void close() { Metrics.globalRegistry.close(); } - /** - * This function uses patterns specified in the patternList parameter to filter out specific - * metrics that the user doesn't want. - * - * @param patternList, a comma-delimited String of regext patterns that getMeterFilter uses to - * filter metrics. - * @return a predicate with the type of MeterFilter, that describes which metrics to filter. - */ - public static MeterFilter getMeterFilter(String patternList) { - requireNonNull(patternList, "patternList must not be null"); - - // Trims whitespace and all other non-visible characters. - patternList = patternList.replaceAll("\\s+", ""); - - String[] patterns = patternList.split(","); - Predicate finalPredicate = id -> false; - - for (String pattern : patterns) { - // Compile the pattern. - // Will throw PatternSyntaxException if invalid pattern. - Pattern compiledPattern = Pattern.compile(pattern); - // Create a predicate that will return true if the ID's name matches the pattern. - Predicate predicate = id -> compiledPattern.matcher(id.getName()).matches(); - // Conjoin the pattern into the final predicates. The final predicate will return true if - // the name of the ID matches any of its conjoined predicates. - finalPredicate = finalPredicate.or(predicate); - } - - // Assert that meter filter reply == MeterFilterReply.DENY; - return MeterFilter.deny(finalPredicate); - } - @Override public synchronized String toString() { return "MetricsCommonTags{tags=" + commonTags + '}'; diff --git a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java index 7b810672518..f3bb320c3bc 100644 --- a/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java +++ b/server/base/src/test/java/org/apache/accumulo/server/metrics/MetricsInfoImplTest.java @@ -23,22 +23,16 @@ import static org.easymock.EasyMock.mock; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Map; -import java.util.regex.PatternSyntaxException; import org.apache.accumulo.core.conf.AccumuloConfiguration; import org.apache.accumulo.server.ServerContext; import org.junit.jupiter.api.Test; -import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; -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.simple.SimpleMeterRegistry; public class MetricsInfoImplTest { @@ -70,94 +64,4 @@ public MeterRegistry create(final InitParameters params) { return new SimpleMeterRegistry(); } } - - /** - * Verify that when a Null pattern is supplied to {@link MetricsInfoImpl#getMeterFilter(String)}, - * that we catch a NullPointerException and receive the errorMessage: "patternList must not be - * null" - */ - @Test - public void testNullPatternList() { - Throwable exception = assertThrows(NullPointerException.class, - () -> MetricsInfoImpl.getMeterFilter(null), "Expected an NPE"); - assertEquals("patternList must not be null", exception.getMessage()); - } - - /** - * Verify that when an invalid regex pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, that a PatternSyntaxException is thrown. - */ - @Test - public void testIfPatternListInvalid() { - assertThrows(PatternSyntaxException.class, () -> MetricsInfoImpl.getMeterFilter("[\\]"), - "Expected an PatternSyntaxException"); - - } - - /** - * Verify that when only one pattern is supplied to {@link MetricsInfoImpl#getMeterFilter(String)} - * and the resulting filter is given an id whose name matches that pattern, that we get a reply of - * {@link MeterFilterReply#DENY}. - */ - @Test - public void testIfSinglePatternMatchesId() { - MeterFilter filter = MetricsInfoImpl.getMeterFilter("aaa.*"); - Meter.Id id = new Meter.Id("aaaName", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); - } - - /** - * Verify that when an empty pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, then no matter what the id is we get a reply of - * {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testThatEmptyPatternDoesNotMatchId() { - MeterFilter filter = MetricsInfoImpl.getMeterFilter(""); - Meter.Id id = - new Meter.Id("shouldnotmatch", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } - - /** - * Verify that when only one pattern is supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose - * name does not match that pattern, that we get a reply of {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testIfSinglePatternDoesNotMatch() { - MeterFilter filter = MetricsInfoImpl.getMeterFilter(("aaa.*")); - Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } - - /** - * Verify that when multiple patterns are supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose - * name matches at least one of the patterns, that we get a reply of - * {@link MeterFilterReply#DENY}. - */ - @Test - public void testIfMultiplePatternsMatches() { - MeterFilter filter = MetricsInfoImpl.getMeterFilter(("aaa.*,bbb.*,ccc.*")); - Meter.Id id = new Meter.Id("aaaRight", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.DENY, reply, "Expected a reply of DENY"); - } - - /** - * Verify that when multiple patterns are supplied to - * {@link MetricsInfoImpl#getMeterFilter(String)}, and the resulting filter is given an id whose - * name matches none of the patterns, that we get a reply of {@link MeterFilterReply#NEUTRAL}. - */ - @Test - public void testMultiplePatternsWithNoMatch() { - MeterFilter filter = MetricsInfoImpl.getMeterFilter(("aaa.*,bbb.*,ccc.*")); - Meter.Id id = new Meter.Id("Wrong", Tags.of("tag", "tag"), null, null, Meter.Type.OTHER); - MeterFilterReply reply = filter.accept(id); - assertEquals(MeterFilterReply.NEUTRAL, reply, "Expected a reply of NEUTRAL"); - } } From 20d5c9b0a85a230ddb0c6c15cc597108e11c7d08 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Tue, 1 Jul 2025 09:38:33 -0400 Subject: [PATCH 13/16] Revert changes for MetricsInfoImpl.java and MeterRegistryFactory.java --- .../apache/accumulo/core/spi/metrics/MeterRegistryFactory.java | 1 - .../java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java | 1 - 2 files changed, 2 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java index a584f046921..3e57cc200a1 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/MeterRegistryFactory.java @@ -69,5 +69,4 @@ interface InitParameters { * @return a Micrometer registry that will be added to the metrics configuration. */ MeterRegistry create(final InitParameters params); - } diff --git a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java index 512955fec5b..60f48b6b292 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java +++ b/server/base/src/main/java/org/apache/accumulo/server/metrics/MetricsInfoImpl.java @@ -18,7 +18,6 @@ */ package org.apache.accumulo.server.metrics; -import static java.util.Objects.requireNonNull; import static org.apache.hadoop.util.StringUtils.getTrimmedStrings; import java.util.ArrayList; From bd9b1d255995b5bc738e18e47ef76105e26a2844 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Tue, 1 Jul 2025 11:08:51 -0400 Subject: [PATCH 14/16] Using correct JUnit API --- .../LoggingMeterRegistryFactoryTest.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java index 41951ffa6f3..e06bf2e3480 100644 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java @@ -18,7 +18,6 @@ */ package org.apache.accumulo.core.spi.metrics; -import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; @@ -26,6 +25,7 @@ import java.util.Map; import org.apache.accumulo.core.spi.common.ServiceEnvironment; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import io.micrometer.core.instrument.Meter; @@ -43,7 +43,7 @@ public void createTest() { private static class LoggingMetricsParams implements MeterRegistryFactory.InitParameters { - private Map options; + private final Map options; public LoggingMetricsParams(Map options) { this.options = options; @@ -75,7 +75,7 @@ public void createWithFilters() { reg.timer("ProperTimer", "tag1", "tag2"); List meterReg = reg.getMeters(); // Does this only contain ProperTimer? Yes - assertEquals("ProperTimer", meterReg.get(0).getId().getName()); + Assertions.assertEquals("ProperTimer", meterReg.get(0).getId().getName()); } /** @@ -96,14 +96,14 @@ public void testNonCommaDelimiter() { reg.counter("ProperCounter", "tag1", "tag2"); List meterReg = reg.getMeters(); - String allMeters = ""; + StringBuilder allMeters = new StringBuilder(); for (Meter m : meterReg) { - allMeters = allMeters + m.getId().getName(); + allMeters.append(m.getId().getName()); } - assertFalse(allMeters.contains("Foo")); - assertFalse(allMeters.contains("Bar")); - assertFalse(allMeters.contains("Hat")); + assertFalse(allMeters.toString().contains("Foo")); + assertFalse(allMeters.toString().contains("Bar")); + assertFalse(allMeters.toString().contains("Hat")); } /** @@ -119,11 +119,11 @@ public void testIfPatternIsNotFirst() { reg.timer("TimerFoo", "tag1", "tag2"); List meterReg = reg.getMeters(); - String allMeters = ""; + StringBuilder allMeters = new StringBuilder(); for (Meter m : meterReg) { - allMeters = allMeters + m.getId().getName(); + allMeters.append(m.getId().getName()); } - assertEquals("TimerFoo", allMeters); + Assertions.assertEquals("TimerFoo", allMeters.toString()); } /** @@ -138,12 +138,12 @@ public void testIfDuplicatePatterns() { reg.timer("FooTimer", "tag1", "tag2"); List meterReg = reg.getMeters(); - String allMeters = ""; + StringBuilder allMeters = new StringBuilder(); for (Meter m : meterReg) { - allMeters = allMeters + m.getId().getName(); + allMeters.append(m.getId().getName()); } - assertEquals("", allMeters); + Assertions.assertEquals("", allMeters.toString()); } /** @@ -157,11 +157,11 @@ public void testEmptyPatternList() { Map.of("prop1", "abc", "logging.step", "1s", "meter.id.filters", ""))); reg.timer("FooTimer", "tag1", "tag2"); List meterReg = reg.getMeters(); - String allMeters = ""; + StringBuilder allMeters = new StringBuilder(); for (Meter m : meterReg) { - allMeters = allMeters + m.getId().getName(); + allMeters.append(m.getId().getName()); } - assertEquals("FooTimer", allMeters); + Assertions.assertEquals("FooTimer", allMeters.toString()); } } From 68017f169d01959926e16048a71984bf926f0a9f Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Tue, 1 Jul 2025 11:25:56 -0400 Subject: [PATCH 15/16] Corrected assertions for Tests. Corrected java docs. --- .../core/spi/metrics/LoggingMeterRegistryFactory.java | 4 ++-- .../spi/metrics/LoggingMeterRegistryFactoryTest.java | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java index 46d9e9a19b6..7d19309fc87 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java @@ -113,9 +113,9 @@ public MeterRegistry create(final InitParameters params) { * This function uses terms specified in the patternList parameter to filter out specific metrics * that the user doesn't want. * - * @param patternList, a delimited set of terms that will filter out meters that start with any + * @param patternList a delimited set of terms that will filter out meters that start with any * one of those terms. - * @param delimiter, that contains either a user specified delimiter, or the default comma + * @param delimiter that contains either a user specified delimiter, or the default comma * delimiter to split the patternList. * @return a predicate with the type of MeterFilter, that describes which metrics to deny and * subsequently filter out. diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java index e06bf2e3480..9e6ef5999a6 100644 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java @@ -19,13 +19,13 @@ package org.apache.accumulo.core.spi.metrics; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import java.util.List; import java.util.Map; import org.apache.accumulo.core.spi.common.ServiceEnvironment; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import io.micrometer.core.instrument.Meter; @@ -75,7 +75,7 @@ public void createWithFilters() { reg.timer("ProperTimer", "tag1", "tag2"); List meterReg = reg.getMeters(); // Does this only contain ProperTimer? Yes - Assertions.assertEquals("ProperTimer", meterReg.get(0).getId().getName()); + assertEquals("ProperTimer", meterReg.get(0).getId().getName()); } /** @@ -123,7 +123,7 @@ public void testIfPatternIsNotFirst() { for (Meter m : meterReg) { allMeters.append(m.getId().getName()); } - Assertions.assertEquals("TimerFoo", allMeters.toString()); + assertEquals("TimerFoo", allMeters.toString()); } /** @@ -143,7 +143,7 @@ public void testIfDuplicatePatterns() { allMeters.append(m.getId().getName()); } - Assertions.assertEquals("", allMeters.toString()); + assertEquals("", allMeters.toString()); } /** @@ -161,7 +161,7 @@ public void testEmptyPatternList() { for (Meter m : meterReg) { allMeters.append(m.getId().getName()); } - Assertions.assertEquals("FooTimer", allMeters.toString()); + assertEquals("FooTimer", allMeters.toString()); } } From 0529cd1d4091f86910e6e3b39b5eba2756dad291 Mon Sep 17 00:00:00 2001 From: ibilley7 Date: Tue, 1 Jul 2025 12:00:07 -0400 Subject: [PATCH 16/16] Formatting code. --- .../core/spi/metrics/LoggingMeterRegistryFactory.java | 4 ++-- .../core/spi/metrics/LoggingMeterRegistryFactoryTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java b/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java index 7d19309fc87..5d73d5a5563 100644 --- a/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java +++ b/core/src/main/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactory.java @@ -113,8 +113,8 @@ public MeterRegistry create(final InitParameters params) { * This function uses terms specified in the patternList parameter to filter out specific metrics * that the user doesn't want. * - * @param patternList a delimited set of terms that will filter out meters that start with any - * one of those terms. + * @param patternList a delimited set of terms that will filter out meters that start with any one + * of those terms. * @param delimiter that contains either a user specified delimiter, or the default comma * delimiter to split the patternList. * @return a predicate with the type of MeterFilter, that describes which metrics to deny and diff --git a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java index 9e6ef5999a6..f57b5abe7cd 100644 --- a/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java +++ b/core/src/test/java/org/apache/accumulo/core/spi/metrics/LoggingMeterRegistryFactoryTest.java @@ -18,8 +18,8 @@ */ package org.apache.accumulo.core.spi.metrics; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import java.util.List;