Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use micrometer noop classes for default meter initialization #4542

Merged
merged 8 commits into from
May 28, 2024

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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);
dlmarion marked this conversation as resolved.
Show resolved Hide resolved
}

private static String uniqueName() {
return "noop" + idCount.incrementAndGet();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@

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() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

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 {
Expand All @@ -54,7 +55,7 @@ void registerMetrics() {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
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;
Expand All @@ -36,9 +37,9 @@

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
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;
Expand All @@ -34,13 +34,13 @@
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
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;
Expand All @@ -30,13 +30,13 @@

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);
Expand Down
20 changes: 14 additions & 6 deletions test/src/main/java/org/apache/accumulo/test/metrics/MetricsIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,22 @@ public void confirmMetricsPublished() throws Exception {

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
Expand Down