This is an automated email from the ASF dual-hosted git repository.

edcoleman pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/2.1 by this push:
     new 38d9da710b Use micrometer noop classes for default meter 
initialization (#4542)
38d9da710b is described below

commit 38d9da710b13ab7e81770ca015055da9a8b3d755
Author: EdColeman <d...@etcoleman.com>
AuthorDate: Tue May 28 18:50:05 2024 -0400

    Use micrometer noop classes for default meter initialization (#4542)
    
    * Use micrometer noop classes for default meter initialization
     - removes custom NoOpDistributionSummary
     - adds default initializations for other meter types
     -organize MetricsIT excludes to ease future merging.
---
 .../server/metrics/NoOpDistributionSummary.java    | 83 ----------------------
 .../accumulo/server/metrics/NoopMetrics.java       | 79 ++++++++++++++++++++
 .../accumulo/server/metrics/ThriftMetrics.java     |  4 +-
 ...butionSummaryTest.java => NoopMetricsTest.java} | 20 +++++-
 .../accumulo/server/metrics/ThriftMetricsTest.java |  3 +-
 .../manager/metrics/ReplicationMetrics.java        |  3 +-
 .../apache/accumulo/tserver/ScanServerMetrics.java |  7 +-
 .../tserver/metrics/TabletServerMinCMetrics.java   |  5 +-
 .../tserver/metrics/TabletServerScanMetrics.java   | 16 ++---
 .../tserver/metrics/TabletServerUpdateMetrics.java | 16 ++---
 .../apache/accumulo/test/metrics/MetricsIT.java    | 20 ++++--
 11 files changed, 140 insertions(+), 116 deletions(-)

diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/metrics/NoOpDistributionSummary.java
 
b/server/base/src/main/java/org/apache/accumulo/server/metrics/NoOpDistributionSummary.java
deleted file mode 100644
index 262dc0802a..0000000000
--- 
a/server/base/src/main/java/org/apache/accumulo/server/metrics/NoOpDistributionSummary.java
+++ /dev/null
@@ -1,83 +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.server.metrics;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.micrometer.core.instrument.DistributionSummary;
-import io.micrometer.core.instrument.Tag;
-import io.micrometer.core.instrument.Tags;
-import io.micrometer.core.instrument.distribution.HistogramSnapshot;
-
-/**
- * Provides a default DistributionSummary that does not do anything. This can 
be used to prevent NPE
- * if metrics have not been initialized when a DistributionSummary is expected.
- * <p>
- * Normally DistributionSummaries are created using a builder that takes a 
registry.
- *
- * <pre>
- *   DistributionSummary distSum;
- *   ...
- *   public void registerMetrics(MeterRegistry registry) {
- *      ...
- *      distSum = DistributionSummary.builder("metric 
name").description("...").register(registry);
- *      ...
- *   }
- * </pre>
- *
- * Until the registration is called, the instance variable is null. If code 
then tries to update the
- * metric, a NPE is thrown. Using this class to provide a default value 
prevents this from occurring
- * and on registration, it is replaced with a valid instance.
- */
-public class NoOpDistributionSummary implements DistributionSummary {
-
-  private static final Logger LOG = 
LoggerFactory.getLogger(NoOpDistributionSummary.class);
-
-  @Override
-  public void record(double v) {
-    LOG.debug("record ignored - distribution summary will not be available.");
-  }
-
-  @Override
-  public long count() {
-    return 0;
-  }
-
-  @Override
-  public double totalAmount() {
-    return 0;
-  }
-
-  @Override
-  public double max() {
-    return 0;
-  }
-
-  @Override
-  public HistogramSnapshot takeSnapshot() {
-    return new HistogramSnapshot(0L, 0.0, 0.0, null, null, null);
-  }
-
-  @Override
-  public Id getId() {
-    return new Id("thrift.metrics.uninitialized", Tags.of(Tag.of("none", 
"uninitialized")), null,
-        "placeholder for uninitialized thrift metrics", Type.OTHER);
-  }
-}
diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/metrics/NoopMetrics.java 
b/server/base/src/main/java/org/apache/accumulo/server/metrics/NoopMetrics.java
new file mode 100644
index 0000000000..065106e2bb
--- /dev/null
+++ 
b/server/base/src/main/java/org/apache/accumulo/server/metrics/NoopMetrics.java
@@ -0,0 +1,79 @@
+/*
+ * 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.server.metrics;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.DistributionSummary;
+import io.micrometer.core.instrument.FunctionTimer;
+import io.micrometer.core.instrument.Gauge;
+import io.micrometer.core.instrument.Meter;
+import io.micrometer.core.instrument.Tags;
+import io.micrometer.core.instrument.Timer;
+import io.micrometer.core.instrument.noop.NoopCounter;
+import io.micrometer.core.instrument.noop.NoopDistributionSummary;
+import io.micrometer.core.instrument.noop.NoopFunctionTimer;
+import io.micrometer.core.instrument.noop.NoopGauge;
+import io.micrometer.core.instrument.noop.NoopTimer;
+
+/**
+ * Convenience utility class to return micrometer noop metrics. Initialization 
of the metrics system
+ * registry can be delayed so that common tags with values determined at 
runtime (for example, port
+ * numbers). Initializing meters that are created from the registry at 
initialization with a noop
+ * implementation prevents NPEs if something tries to record a metric value 
before the
+ * initialization has run.
+ */
+public class NoopMetrics {
+  private final static AtomicInteger idCount = new AtomicInteger(0);
+
+  private NoopMetrics() {}
+
+  public static Counter useNoopCounter() {
+    return new NoopCounter(noopId(Meter.Type.COUNTER));
+  }
+
+  public static Gauge useNoopGauge() {
+    return new NoopGauge(noopId(Meter.Type.GAUGE));
+  }
+
+  public static DistributionSummary useNoopDistributionSummary() {
+    return new 
NoopDistributionSummary(noopId(Meter.Type.DISTRIBUTION_SUMMARY));
+  }
+
+  public static Timer useNoopTimer() {
+    return new NoopTimer(noopId(Meter.Type.TIMER));
+  }
+
+  public static FunctionTimer useNoopFunctionTimer() {
+    return new NoopFunctionTimer(noopId(Meter.Type.TIMER));
+  }
+
+  /**
+   * provide a unique id to guard against the id being used as a key.
+   */
+  private static Meter.Id noopId(final Meter.Type type) {
+    return new Meter.Id(uniqueName(), Tags.of("noop", "none"), "", "", type);
+  }
+
+  private static String uniqueName() {
+    return "noop" + idCount.incrementAndGet();
+  }
+
+}
diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/metrics/ThriftMetrics.java
 
b/server/base/src/main/java/org/apache/accumulo/server/metrics/ThriftMetrics.java
index 1d113d3e1e..c6288752ad 100644
--- 
a/server/base/src/main/java/org/apache/accumulo/server/metrics/ThriftMetrics.java
+++ 
b/server/base/src/main/java/org/apache/accumulo/server/metrics/ThriftMetrics.java
@@ -25,8 +25,8 @@ import io.micrometer.core.instrument.MeterRegistry;
 
 public class ThriftMetrics implements MetricsProducer {
 
-  private DistributionSummary idle = new NoOpDistributionSummary();
-  private DistributionSummary execute = new NoOpDistributionSummary();
+  private DistributionSummary idle = NoopMetrics.useNoopDistributionSummary();
+  private DistributionSummary execute = 
NoopMetrics.useNoopDistributionSummary();
 
   public ThriftMetrics() {}
 
diff --git 
a/server/base/src/test/java/org/apache/accumulo/server/metrics/NoOpDistributionSummaryTest.java
 
b/server/base/src/test/java/org/apache/accumulo/server/metrics/NoopMetricsTest.java
similarity index 67%
rename from 
server/base/src/test/java/org/apache/accumulo/server/metrics/NoOpDistributionSummaryTest.java
rename to 
server/base/src/test/java/org/apache/accumulo/server/metrics/NoopMetricsTest.java
index d374791d02..073e467b18 100644
--- 
a/server/base/src/test/java/org/apache/accumulo/server/metrics/NoOpDistributionSummaryTest.java
+++ 
b/server/base/src/test/java/org/apache/accumulo/server/metrics/NoopMetricsTest.java
@@ -19,13 +19,29 @@
 package org.apache.accumulo.server.metrics;
 
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import org.junit.jupiter.api.Test;
 
-class NoOpDistributionSummaryTest {
+import io.micrometer.core.instrument.Counter;
+import io.micrometer.core.instrument.DistributionSummary;
+import io.micrometer.core.instrument.Gauge;
+
+public class NoopMetricsTest {
+  @Test
+  public void testNames() {
+    Counter c1 = NoopMetrics.useNoopCounter();
+    Counter c2 = NoopMetrics.useNoopCounter();
+
+    Gauge g1 = NoopMetrics.useNoopGauge();
+
+    assertNotEquals(c1.getId(), c2.getId());
+    assertNotEquals(c1.getId(), g1.getId());
+  }
+
   @Test
   public void testNoOp() {
-    NoOpDistributionSummary noop = new NoOpDistributionSummary();
+    DistributionSummary noop = NoopMetrics.useNoopDistributionSummary();
     assertDoesNotThrow(() -> noop.getId());
     assertDoesNotThrow(() -> noop.takeSnapshot());
     assertDoesNotThrow(() -> noop.max());
diff --git 
a/server/base/src/test/java/org/apache/accumulo/server/metrics/ThriftMetricsTest.java
 
b/server/base/src/test/java/org/apache/accumulo/server/metrics/ThriftMetricsTest.java
index 0225095976..91730d0582 100644
--- 
a/server/base/src/test/java/org/apache/accumulo/server/metrics/ThriftMetricsTest.java
+++ 
b/server/base/src/test/java/org/apache/accumulo/server/metrics/ThriftMetricsTest.java
@@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
 
 import io.micrometer.core.instrument.DistributionSummary;
 import io.micrometer.core.instrument.MeterRegistry;
+import io.micrometer.core.instrument.noop.NoopDistributionSummary;
 import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
 
 class ThriftMetricsTest {
@@ -54,7 +55,7 @@ class ThriftMetricsTest {
     registry.forEachMeter(m -> {
       LOG.trace("meter: {}", m.getId());
       assertInstanceOf(DistributionSummary.class, m);
-      assertFalse(m instanceof NoOpDistributionSummary);
+      assertFalse(m instanceof NoopDistributionSummary);
     });
     assertTrue(registry.get(METRICS_THRIFT_IDLE).summary().count() > 0);
     assertTrue(registry.get(METRICS_THRIFT_EXECUTE).summary().count() > 0);
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/metrics/ReplicationMetrics.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/metrics/ReplicationMetrics.java
index 931fb30215..181df66c69 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/metrics/ReplicationMetrics.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/metrics/ReplicationMetrics.java
@@ -36,6 +36,7 @@ import org.apache.accumulo.core.replication.ReplicationTable;
 import org.apache.accumulo.core.replication.ReplicationTarget;
 import org.apache.accumulo.core.util.threads.ThreadPools;
 import org.apache.accumulo.manager.Manager;
+import org.apache.accumulo.server.metrics.NoopMetrics;
 import org.apache.accumulo.server.replication.ReplicationUtil;
 import org.apache.hadoop.fs.Path;
 import org.slf4j.Logger;
@@ -53,7 +54,7 @@ public class ReplicationMetrics implements MetricsProducer {
   private final ReplicationUtil replicationUtil;
   private final Map<Path,Long> pathModTimes;
 
-  private Timer replicationQueueTimer;
+  private Timer replicationQueueTimer = NoopMetrics.useNoopTimer();
   private AtomicLong pendingFiles;
   private AtomicInteger numPeers;
   private AtomicInteger maxReplicationThreads;
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/ScanServerMetrics.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/ScanServerMetrics.java
index 1ba7de6e33..b56bc20b1a 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/ScanServerMetrics.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/ScanServerMetrics.java
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.accumulo.core.dataImpl.KeyExtent;
 import org.apache.accumulo.core.metadata.schema.TabletMetadata;
 import org.apache.accumulo.core.metrics.MetricsProducer;
+import org.apache.accumulo.server.metrics.NoopMetrics;
 
 import com.github.benmanes.caffeine.cache.LoadingCache;
 import com.google.common.base.Preconditions;
@@ -36,9 +37,9 @@ import 
io.micrometer.core.instrument.binder.cache.CaffeineCacheMetrics;
 
 public class ScanServerMetrics implements MetricsProducer {
 
-  private Timer totalReservationTimer;
-  private Timer writeOutReservationTimer;
-  private Counter busyTimeoutCount;
+  private Timer totalReservationTimer = NoopMetrics.useNoopTimer();
+  private Timer writeOutReservationTimer = NoopMetrics.useNoopTimer();
+  private Counter busyTimeoutCount = NoopMetrics.useNoopCounter();
   private final AtomicLong reservationConflictCount = new AtomicLong(0);
 
   private final LoadingCache<KeyExtent,TabletMetadata> tabletMetadataCache;
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerMinCMetrics.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerMinCMetrics.java
index a7f402343c..bf95b00262 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerMinCMetrics.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerMinCMetrics.java
@@ -21,14 +21,15 @@ package org.apache.accumulo.tserver.metrics;
 import java.time.Duration;
 
 import org.apache.accumulo.core.metrics.MetricsProducer;
+import org.apache.accumulo.server.metrics.NoopMetrics;
 
 import io.micrometer.core.instrument.MeterRegistry;
 import io.micrometer.core.instrument.Timer;
 
 public class TabletServerMinCMetrics implements MetricsProducer {
 
-  private Timer activeMinc;
-  private Timer queuedMinc;
+  private Timer activeMinc = NoopMetrics.useNoopTimer();
+  private Timer queuedMinc = NoopMetrics.useNoopTimer();
 
   public void addActive(long value) {
     activeMinc.record(Duration.ofMillis(value));
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerScanMetrics.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerScanMetrics.java
index bf22d1d297..c2c8dd0d32 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerScanMetrics.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerScanMetrics.java
@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.LongAdder;
 
 import org.apache.accumulo.core.metrics.MetricsProducer;
-import org.apache.accumulo.server.metrics.NoOpDistributionSummary;
+import org.apache.accumulo.server.metrics.NoopMetrics;
 
 import io.micrometer.core.instrument.Counter;
 import io.micrometer.core.instrument.DistributionSummary;
@@ -34,13 +34,13 @@ import io.micrometer.core.instrument.Timer;
 public class TabletServerScanMetrics implements MetricsProducer {
 
   private final AtomicInteger openFiles = new AtomicInteger(0);
-  private Timer scans;
-  private DistributionSummary resultsPerScan = new NoOpDistributionSummary();
-  private DistributionSummary yields = new NoOpDistributionSummary();
-  private Counter startScanCalls;
-  private Counter continueScanCalls;
-  private Counter closeScanCalls;
-  private Counter busyTimeoutCount;
+  private Timer scans = NoopMetrics.useNoopTimer();
+  private DistributionSummary resultsPerScan = 
NoopMetrics.useNoopDistributionSummary();
+  private DistributionSummary yields = 
NoopMetrics.useNoopDistributionSummary();
+  private Counter startScanCalls = NoopMetrics.useNoopCounter();
+  private Counter continueScanCalls = NoopMetrics.useNoopCounter();;
+  private Counter closeScanCalls = NoopMetrics.useNoopCounter();;
+  private Counter busyTimeoutCount = NoopMetrics.useNoopCounter();;
 
   private final LongAdder lookupCount = new LongAdder();
   private final LongAdder queryResultCount = new LongAdder();
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerUpdateMetrics.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerUpdateMetrics.java
index 09ad197b6d..a369458b6c 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerUpdateMetrics.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/metrics/TabletServerUpdateMetrics.java
@@ -21,7 +21,7 @@ package org.apache.accumulo.tserver.metrics;
 import java.time.Duration;
 
 import org.apache.accumulo.core.metrics.MetricsProducer;
-import org.apache.accumulo.server.metrics.NoOpDistributionSummary;
+import org.apache.accumulo.server.metrics.NoopMetrics;
 
 import io.micrometer.core.instrument.Counter;
 import io.micrometer.core.instrument.DistributionSummary;
@@ -30,13 +30,13 @@ import io.micrometer.core.instrument.Timer;
 
 public class TabletServerUpdateMetrics implements MetricsProducer {
 
-  private Counter permissionErrorsCounter;
-  private Counter unknownTabletErrorsCounter;
-  private Counter constraintViolationsCounter;
-  private Timer commitPrepStat;
-  private Timer walogWriteTimeStat;
-  private Timer commitTimeStat;
-  private DistributionSummary mutationArraySizeStat = new 
NoOpDistributionSummary();
+  private Counter permissionErrorsCounter = NoopMetrics.useNoopCounter();
+  private Counter unknownTabletErrorsCounter = NoopMetrics.useNoopCounter();
+  private Counter constraintViolationsCounter = NoopMetrics.useNoopCounter();
+  private Timer commitPrepStat = NoopMetrics.useNoopTimer();
+  private Timer walogWriteTimeStat = NoopMetrics.useNoopTimer();;
+  private Timer commitTimeStat = NoopMetrics.useNoopTimer();;
+  private DistributionSummary mutationArraySizeStat = 
NoopMetrics.useNoopDistributionSummary();
 
   public void addPermissionErrors(long value) {
     permissionErrorsCounter.increment(value);
diff --git a/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java 
b/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java
index 5d9c833be5..f0b53992b4 100644
--- a/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java
@@ -98,14 +98,22 @@ public class MetricsIT extends ConfigurableMacBase 
implements MetricsProducer {
 
     doWorkToGenerateMetrics();
     cluster.stop();
+    // meter names sorted and formatting disabled to make it easier to diff 
changes
+    // @formatter:off
+    Set<String> unexpectedMetrics =
+            Set.of(METRICS_COMPACTOR_MAJC_STUCK,
+                    METRICS_REPLICATION_QUEUE,
+                    METRICS_SCAN_YIELDS,
+                    METRICS_UPDATE_ERRORS);
 
-    Set<String> unexpectedMetrics = Set.of(METRICS_SCAN_YIELDS, 
METRICS_UPDATE_ERRORS,
-        METRICS_REPLICATION_QUEUE, METRICS_COMPACTOR_MAJC_STUCK, 
METRICS_SCAN_BUSY_TIMEOUT_COUNTER);
     // add sserver as flaky until scan server included in mini tests.
-    Set<String> flakyMetrics = Set.of(METRICS_GC_WAL_ERRORS, 
METRICS_FATE_TYPE_IN_PROGRESS,
-        METRICS_SCAN_BUSY_TIMEOUT_COUNTER, 
METRICS_SCAN_RESERVATION_TOTAL_TIMER,
-        METRICS_SCAN_RESERVATION_WRITEOUT_TIMER, 
METRICS_SCAN_RESERVATION_CONFLICT_COUNTER,
-        METRICS_SCAN_TABLET_METADATA_CACHE);
+    Set<String> flakyMetrics = Set.of(METRICS_FATE_TYPE_IN_PROGRESS,
+            METRICS_SCAN_BUSY_TIMEOUT_COUNTER,
+            METRICS_SCAN_RESERVATION_CONFLICT_COUNTER,
+            METRICS_SCAN_RESERVATION_TOTAL_TIMER,
+            METRICS_SCAN_RESERVATION_WRITEOUT_TIMER,
+            METRICS_SCAN_TABLET_METADATA_CACHE);
+    // @formatter:on
 
     Map<String,String> expectedMetricNames = this.getMetricFields();
     flakyMetrics.forEach(expectedMetricNames::remove); // might not see these

Reply via email to