Migrate remaining custom metrics from Dropwizard to Micrometer

And remove some that are obsolete or duplicative.
This commit is contained in:
Chris Eager
2024-04-17 15:35:04 -05:00
committed by GitHub
parent 419ec6e308
commit a38bf25e68
20 changed files with 234 additions and 536 deletions

View File

@@ -1,29 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import static com.codahale.metrics.MetricRegistry.name;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import java.lang.management.BufferPoolMXBean;
import java.lang.management.ManagementFactory;
import java.util.List;
public class BufferPoolGauges {
private BufferPoolGauges() {}
public static void registerMetrics() {
for (final BufferPoolMXBean bufferPoolMXBean : ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class)) {
final List<Tag> tags = List.of(Tag.of("bufferPoolName", bufferPoolMXBean.getName()));
Metrics.gauge(name(BufferPoolGauges.class, "count"), tags, bufferPoolMXBean, BufferPoolMXBean::getCount);
Metrics.gauge(name(BufferPoolGauges.class, "memory_used"), tags, bufferPoolMXBean, BufferPoolMXBean::getMemoryUsed);
Metrics.gauge(name(BufferPoolGauges.class, "total_capacity"), tags, bufferPoolMXBean, BufferPoolMXBean::getTotalCapacity);
}
}
}

View File

@@ -1,29 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import com.codahale.metrics.CachedGauge;
import com.sun.management.OperatingSystemMXBean;
import java.lang.management.ManagementFactory;
import java.util.concurrent.TimeUnit;
public class CpuUsageGauge extends CachedGauge<Integer> {
private final OperatingSystemMXBean operatingSystemMXBean;
public CpuUsageGauge(final long timeout, final TimeUnit timeoutUnit) {
super(timeout, timeoutUnit);
this.operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean)
ManagementFactory.getOperatingSystemMXBean();
}
@Override
protected Integer loadValue() {
return (int) Math.ceil(operatingSystemMXBean.getCpuLoad() * 100);
}
}

View File

@@ -1,24 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import com.codahale.metrics.Gauge;
import java.io.File;
public class FileDescriptorGauge implements Gauge<Integer> {
@Override
public Integer getValue() {
File file = new File("/proc/self/fd");
if (file.isDirectory() && file.exists()) {
return file.list().length;
}
return 0;
}
}

View File

@@ -5,21 +5,20 @@
package org.whispersystems.textsecuregcm.metrics;
import com.codahale.metrics.Gauge;
import com.sun.management.OperatingSystemMXBean;
import java.lang.management.ManagementFactory;
public class FreeMemoryGauge implements Gauge<Long> {
public class FreeMemoryGauge implements Gauge {
private final OperatingSystemMXBean operatingSystemMXBean;
public FreeMemoryGauge() {
this.operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean)
ManagementFactory.getOperatingSystemMXBean();
ManagementFactory.getOperatingSystemMXBean();
}
@Override
public Long getValue() {
public double getValue() {
return operatingSystemMXBean.getFreeMemorySize();
}
}

View File

@@ -5,7 +5,7 @@
package org.whispersystems.textsecuregcm.metrics;
import static com.codahale.metrics.MetricRegistry.name;
import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
@@ -15,14 +15,17 @@ import java.util.List;
public class GarbageCollectionGauges {
private GarbageCollectionGauges() {}
private GarbageCollectionGauges() {
}
public static void registerMetrics() {
for (final GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) {
final List<Tag> tags = List.of(Tag.of("memoryManagerName", garbageCollectorMXBean.getName()));
public static void registerMetrics() {
for (final GarbageCollectorMXBean garbageCollectorMXBean : ManagementFactory.getGarbageCollectorMXBeans()) {
final List<Tag> tags = List.of(Tag.of("memoryManagerName", garbageCollectorMXBean.getName()));
Metrics.gauge(name(GarbageCollectionGauges.class, "collection_count"), tags, garbageCollectorMXBean, GarbageCollectorMXBean::getCollectionCount);
Metrics.gauge(name(GarbageCollectionGauges.class, "collection_time"), tags, garbageCollectorMXBean, GarbageCollectorMXBean::getCollectionTime);
}
Metrics.gauge(name(GarbageCollectionGauges.class, "collectionCount"), tags, garbageCollectorMXBean,
GarbageCollectorMXBean::getCollectionCount);
Metrics.gauge(name(GarbageCollectionGauges.class, "collectionTime"), tags, garbageCollectorMXBean,
GarbageCollectorMXBean::getCollectionTime);
}
}
}

View File

@@ -0,0 +1,11 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
interface Gauge {
double getValue();
}

View File

@@ -1,28 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import com.codahale.metrics.Gauge;
import com.sun.management.UnixOperatingSystemMXBean;
import java.lang.management.ManagementFactory;
/**
* A gauge that reports the maximum number of file descriptors allowed by the operating system.
*/
public class MaxFileDescriptorGauge implements Gauge<Long> {
private final UnixOperatingSystemMXBean unixOperatingSystemMXBean;
public MaxFileDescriptorGauge() {
this.unixOperatingSystemMXBean = (UnixOperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
}
@Override
public Long getValue() {
return unixOperatingSystemMXBean.getMaxFileDescriptorCount();
}
}

View File

@@ -12,10 +12,13 @@ import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics;
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics;
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
import io.micrometer.statsd.StatsdMeterRegistry;
import java.util.concurrent.TimeUnit;
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
import org.whispersystems.textsecuregcm.WhisperServerVersion;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
@@ -101,19 +104,20 @@ public class MetricsUtil {
}
public static void registerSystemResourceMetrics(final Environment environment) {
environment.metrics().register(name(CpuUsageGauge.class, "cpu"), new CpuUsageGauge(3, TimeUnit.SECONDS));
environment.metrics().register(name(FreeMemoryGauge.class, "free_memory"), new FreeMemoryGauge());
environment.metrics().register(name(NetworkSentGauge.class, "bytes_sent"), new NetworkSentGauge());
environment.metrics().register(name(NetworkReceivedGauge.class, "bytes_received"), new NetworkReceivedGauge());
environment.metrics().register(name(FileDescriptorGauge.class, "fd_count"), new FileDescriptorGauge());
environment.metrics().register(name(MaxFileDescriptorGauge.class, "max_fd_count"), new MaxFileDescriptorGauge());
environment.metrics()
.register(name(OperatingSystemMemoryGauge.class, "buffers"), new OperatingSystemMemoryGauge("Buffers"));
environment.metrics()
.register(name(OperatingSystemMemoryGauge.class, "cached"), new OperatingSystemMemoryGauge("Cached"));
new ProcessorMetrics().bindTo(Metrics.globalRegistry);
registerGauge(name(FreeMemoryGauge.class, "freeMemory"), new FreeMemoryGauge());
new FileDescriptorMetrics().bindTo(Metrics.globalRegistry);
registerGauge(name(OperatingSystemMemoryGauge.class, "buffers"), new OperatingSystemMemoryGauge("Buffers"));
registerGauge(name(OperatingSystemMemoryGauge.class, "cached"), new OperatingSystemMemoryGauge("Cached"));
new JvmMemoryMetrics().bindTo(Metrics.globalRegistry);
new JvmThreadMetrics().bindTo(Metrics.globalRegistry);
BufferPoolGauges.registerMetrics();
GarbageCollectionGauges.registerMetrics();
}
private static void registerGauge(final String name, final Gauge gauge) {
Metrics.gauge(name, gauge, Gauge::getValue);
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import com.codahale.metrics.Gauge;
import org.whispersystems.textsecuregcm.util.Pair;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public abstract class NetworkGauge implements Gauge<Double> {
protected Pair<Long, Long> getSentReceived() throws IOException {
File proc = new File("/proc/net/dev");
BufferedReader reader = new BufferedReader(new FileReader(proc));
String header = reader.readLine();
String header2 = reader.readLine();
long bytesSent = 0;
long bytesReceived = 0;
String interfaceStats;
while ((interfaceStats = reader.readLine()) != null) {
String[] stats = interfaceStats.split("\\s+");
if (!stats[1].equals("lo:")) {
bytesReceived += Long.parseLong(stats[2]);
bytesSent += Long.parseLong(stats[10]);
}
}
return new Pair<>(bytesSent, bytesReceived);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.util.Pair;
import java.io.IOException;
public class NetworkReceivedGauge extends NetworkGauge {
private final Logger logger = LoggerFactory.getLogger(NetworkReceivedGauge.class);
private long lastTimestamp;
private long lastReceived;
public NetworkReceivedGauge() {
try {
this.lastTimestamp = System.currentTimeMillis();
this.lastReceived = getSentReceived().second();
} catch (IOException e) {
logger.warn(NetworkReceivedGauge.class.getSimpleName(), e);
}
}
@Override
public Double getValue() {
try {
long timestamp = System.currentTimeMillis();
Pair<Long, Long> sentAndReceived = getSentReceived();
double bytesReceived = sentAndReceived.second() - lastReceived;
double secondsElapsed = (timestamp - this.lastTimestamp) / 1000;
double result = bytesReceived / secondsElapsed;
this.lastTimestamp = timestamp;
this.lastReceived = sentAndReceived.second();
return result;
} catch (IOException e) {
logger.warn("NetworkReceivedGauge", e);
return -1D;
}
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.metrics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.util.Pair;
import java.io.IOException;
public class NetworkSentGauge extends NetworkGauge {
private final Logger logger = LoggerFactory.getLogger(NetworkSentGauge.class);
private long lastTimestamp;
private long lastSent;
public NetworkSentGauge() {
try {
this.lastTimestamp = System.currentTimeMillis();
this.lastSent = getSentReceived().first();
} catch (IOException e) {
logger.warn(NetworkSentGauge.class.getSimpleName(), e);
}
}
@Override
public Double getValue() {
try {
long timestamp = System.currentTimeMillis();
Pair<Long, Long> sentAndReceived = getSentReceived();
double bytesTransmitted = sentAndReceived.first() - lastSent;
double secondsElapsed = (timestamp - this.lastTimestamp) / 1000;
double result = bytesTransmitted / secondsElapsed;
this.lastSent = sentAndReceived.first();
this.lastTimestamp = timestamp;
return result;
} catch (IOException e) {
logger.warn("NetworkSentGauge", e);
return -1D;
}
}
}

View File

@@ -5,9 +5,7 @@
package org.whispersystems.textsecuregcm.metrics;
import com.codahale.metrics.Gauge;
import com.google.common.annotations.VisibleForTesting;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -16,33 +14,33 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class OperatingSystemMemoryGauge implements Gauge<Long> {
public class OperatingSystemMemoryGauge implements Gauge {
private final String metricName;
private final String metricName;
private static final File MEMINFO_FILE = new File("/proc/meminfo");
private static final Pattern MEMORY_METRIC_PATTERN = Pattern.compile("^([^:]+):\\s+([0-9]+).*$");
private static final File MEMINFO_FILE = new File("/proc/meminfo");
private static final Pattern MEMORY_METRIC_PATTERN = Pattern.compile("^([^:]+):\\s+([0-9]+).*$");
public OperatingSystemMemoryGauge(final String metricName) {
this.metricName = metricName;
public OperatingSystemMemoryGauge(final String metricName) {
this.metricName = metricName;
}
@Override
public double getValue() {
try (final BufferedReader bufferedReader = new BufferedReader(new FileReader(MEMINFO_FILE))) {
return getValue(bufferedReader.lines());
} catch (final IOException e) {
return 0L;
}
}
@Override
public Long getValue() {
try (final BufferedReader bufferedReader = new BufferedReader(new FileReader(MEMINFO_FILE))) {
return getValue(bufferedReader.lines());
} catch (final IOException e) {
return 0L;
}
}
@VisibleForTesting
long getValue(final Stream<String> lines) {
return lines.map(MEMORY_METRIC_PATTERN::matcher)
.filter(Matcher::matches)
.filter(matcher -> this.metricName.equalsIgnoreCase(matcher.group(1)))
.map(matcher -> Long.parseLong(matcher.group(2), 10))
.findFirst()
.orElse(0L);
}
@VisibleForTesting
double getValue(final Stream<String> lines) {
return lines.map(MEMORY_METRIC_PATTERN::matcher)
.filter(Matcher::matches)
.filter(matcher -> this.metricName.equalsIgnoreCase(matcher.group(1)))
.map(matcher -> Double.parseDouble(matcher.group(2)))
.findFirst()
.orElse(0d);
}
}