Comprehensive metrics collection and monitoring library providing counters, gauges, histograms, meters, and timers for Java applications.
npx @tessl/cli install tessl/maven-io-dropwizard-metrics--metrics-core@4.2.0Metrics Core is the foundational component of the Dropwizard Metrics library, providing comprehensive application-level metrics collection and monitoring capabilities for Java applications. It offers a rich toolkit of metric types including counters, gauges, histograms, meters, and timers that enable developers to measure and monitor the behavior of critical components in production environments.
The library features thread-safe metric collection, configurable sampling reservoirs for histograms, exponential decay algorithms for time-based metrics, and flexible reporting mechanisms including JMX, console, CSV, and SLF4J outputs. Designed for high-performance production use with minimal overhead, metrics-core supports custom metric implementations, metric filtering, and integration with various monitoring systems.
pom.xml:<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>4.2.33</version>
</dependency>For Gradle:
implementation 'io.dropwizard.metrics:metrics-core:4.2.33'import com.codahale.metrics.*;Common specific imports:
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Timer;
import com.codahale.metrics.ConsoleReporter;import com.codahale.metrics.*;
import java.util.concurrent.TimeUnit;
// Create a metric registry - the central repository for metrics
MetricRegistry registry = new MetricRegistry();
// Create different types of metrics
Counter requests = registry.counter("requests");
Histogram responseSizes = registry.histogram("response-sizes");
Meter requestMeter = registry.meter("request-rate");
Timer timer = registry.timer("request-duration");
// Use the metrics
requests.inc(); // Increment counter
responseSizes.update(responseSize); // Record response size
requestMeter.mark(); // Mark an event occurrence
Timer.Context context = timer.time(); // Start timing
// ... do work ...
context.stop(); // Stop timing and record
// Set up reporting to console every 30 seconds
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
reporter.start(30, TimeUnit.SECONDS);
// Or report once immediately
reporter.report();Metrics Core is built around several key architectural components:
Central metric management and the primary metric types for application monitoring.
// Central metric registry - primary entry point
public class MetricRegistry implements MetricSet {
public Counter counter(String name);
public Counter counter(String name, MetricSupplier<Counter> supplier);
public Histogram histogram(String name);
public Histogram histogram(String name, MetricSupplier<Histogram> supplier);
public Meter meter(String name);
public Meter meter(String name, MetricSupplier<Meter> supplier);
public Timer timer(String name);
public Timer timer(String name, MetricSupplier<Timer> supplier);
public <T extends Gauge> T gauge(String name);
public <T extends Gauge> T gauge(String name, MetricSupplier<T> supplier);
public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException;
public <T> Gauge<T> registerGauge(String name, Gauge<T> metric) throws IllegalArgumentException;
public void registerAll(MetricSet metrics) throws IllegalArgumentException;
public void registerAll(String prefix, MetricSet metrics) throws IllegalArgumentException;
public boolean remove(String name);
public void removeMatching(MetricFilter filter);
public SortedSet<String> getNames();
public SortedMap<String, Gauge> getGauges();
public SortedMap<String, Gauge> getGauges(MetricFilter filter);
public SortedMap<String, Counter> getCounters();
public SortedMap<String, Counter> getCounters(MetricFilter filter);
public SortedMap<String, Histogram> getHistograms();
public SortedMap<String, Histogram> getHistograms(MetricFilter filter);
public SortedMap<String, Meter> getMeters();
public SortedMap<String, Meter> getMeters(MetricFilter filter);
public SortedMap<String, Timer> getTimers();
public SortedMap<String, Timer> getTimers(MetricFilter filter);
public Map<String, Metric> getMetrics();
public static String name(String name, String... names);
public static String name(Class<?> klass, String... names);
}
// Thread-safe incrementing/decrementing counter
public class Counter implements Metric, Counting {
public void inc();
public void inc(long n);
public void dec();
public void dec(long n);
public long getCount();
}
// Instantaneous value reading (functional interface)
@FunctionalInterface
public interface Gauge<T> extends Metric {
T getValue();
}
// Rate measurement with moving averages
public class Meter implements Metered {
public Meter();
public Meter(Clock clock);
public Meter(MovingAverages movingAverages);
public Meter(MovingAverages movingAverages, Clock clock);
public void mark();
public void mark(long n);
public double getMeanRate();
public double getOneMinuteRate();
public double getFiveMinuteRate();
public double getFifteenMinuteRate();
public long getCount();
}
// Statistical distribution measurement
public class Histogram implements Metric, Sampling, Counting {
public Histogram(Reservoir reservoir);
public void update(int value);
public void update(long value);
public long getCount();
public Snapshot getSnapshot();
}
// Combined timing and rate measurement
public class Timer implements Metered, Sampling {
public Timer();
public Timer(Reservoir reservoir);
public Timer(Reservoir reservoir, Clock clock);
public void update(long duration, TimeUnit unit);
public void update(Duration duration);
public <T> T time(Callable<T> event) throws Exception;
public void time(Runnable event);
public Context time();
public <T> T timeSupplier(Supplier<T> event);
public long getCount();
public double getMeanRate();
public double getOneMinuteRate();
public double getFiveMinuteRate();
public double getFifteenMinuteRate();
public Snapshot getSnapshot();
public static class Context implements AutoCloseable {
public long stop();
public void close();
}
}Specialized gauge implementations for caching, derivation, and settable values.
// Cache gauge values for performance
public abstract class CachedGauge<T> implements Gauge<T> {
public CachedGauge(long timeout, TimeUnit timeoutUnit);
public CachedGauge(Clock clock, long timeout, TimeUnit timeoutUnit);
protected abstract T loadValue();
}
// Derive values from another gauge
public abstract class DerivativeGauge<F, T> implements Gauge<T> {
public DerivativeGauge(Gauge<F> base);
protected abstract T transform(F value);
}
// Calculate ratios with NaN handling
public abstract class RatioGauge implements Gauge<Double> {
protected abstract Ratio getRatio();
public static class Ratio {
public static Ratio of(double numerator, double denominator);
}
}
// Gauges that can be explicitly set
public interface SettableGauge<T> extends Gauge<T> {
void setValue(T value);
}
public class DefaultSettableGauge<T> implements SettableGauge<T> {
public DefaultSettableGauge();
public DefaultSettableGauge(T initialValue);
public void setValue(T value);
public T getValue();
}Statistical sampling strategies for histograms and timers to manage memory usage while preserving statistical accuracy.
// Base interface for sampling strategies
public interface Reservoir {
int size();
void update(long value);
Snapshot getSnapshot();
}
// Random sampling using Vitter's Algorithm R
public class UniformReservoir implements Reservoir {
public UniformReservoir();
public UniformReservoir(int size);
}
// Time-biased sampling favoring recent values
public class ExponentiallyDecayingReservoir implements Reservoir {
public ExponentiallyDecayingReservoir();
public ExponentiallyDecayingReservoir(int size, double alpha);
public ExponentiallyDecayingReservoir(int size, double alpha, Clock clock);
public void update(long value, long timestamp);
}
// Fixed-size sliding window of most recent values
public class SlidingWindowReservoir implements Reservoir {
public SlidingWindowReservoir(int size);
}
// Time-based sliding window
public class SlidingTimeWindowReservoir implements Reservoir {
public SlidingTimeWindowReservoir(long window, TimeUnit windowUnit);
public SlidingTimeWindowReservoir(long window, TimeUnit windowUnit, Clock clock);
}Flexible reporting system for outputting metrics to various destinations on configurable schedules.
// Abstract base for all scheduled reporters
public abstract class ScheduledReporter implements Closeable, Reporter {
public void start(long period, TimeUnit unit);
public void start(long initialDelay, long period, TimeUnit unit);
public void stop();
public void report();
protected abstract void report(
SortedMap<String, Gauge> gauges,
SortedMap<String, Counter> counters,
SortedMap<String, Histogram> histograms,
SortedMap<String, Meter> meters,
SortedMap<String, Timer> timers);
}
// Console/PrintStream output reporter
public class ConsoleReporter extends ScheduledReporter {
public static Builder forRegistry(MetricRegistry registry);
public static class Builder {
public Builder outputTo(PrintStream output);
public Builder convertRatesTo(TimeUnit rateUnit);
public Builder convertDurationsTo(TimeUnit durationUnit);
public Builder filter(MetricFilter filter);
public ConsoleReporter build();
}
}
// CSV file output reporter
public class CsvReporter extends ScheduledReporter {
public static Builder forRegistry(MetricRegistry registry);
public static class Builder {
public Builder convertRatesTo(TimeUnit rateUnit);
public Builder convertDurationsTo(TimeUnit durationUnit);
public Builder filter(MetricFilter filter);
public CsvReporter build(File directory);
}
}
// SLF4J logging reporter
public class Slf4jReporter extends ScheduledReporter {
public static Builder forRegistry(MetricRegistry registry);
public static class Builder {
public Builder outputTo(Logger logger);
public Builder markWith(Marker marker);
public Builder withLoggingLevel(LoggingLevel loggingLevel);
public Slf4jReporter build();
}
public enum LoggingLevel { TRACE, DEBUG, INFO, WARN, ERROR }
}Helper classes for filtering, instrumentation, and extended functionality.
// Global registry management
public class SharedMetricRegistries {
public static MetricRegistry getOrCreate(String name);
public static void setDefault(String name);
public static MetricRegistry getDefault();
public static void add(String name, MetricRegistry registry);
public static void remove(String name);
}
// Filtering metrics for reporting
@FunctionalInterface
public interface MetricFilter {
boolean matches(String name, Metric metric);
MetricFilter ALL = (name, metric) -> true;
static MetricFilter startsWith(String prefix);
static MetricFilter endsWith(String suffix);
static MetricFilter contains(String substring);
}
// ExecutorService with automatic metrics
public class InstrumentedExecutorService implements ExecutorService {
public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry registry);
public InstrumentedExecutorService(ExecutorService delegate, MetricRegistry registry, String name);
}
// Registry event listener
public interface MetricRegistryListener extends EventListener {
void onGaugeAdded(String name, Gauge<?> gauge);
void onCounterAdded(String name, Counter counter);
void onHistogramAdded(String name, Histogram histogram);
void onMeterAdded(String name, Meter meter);
void onTimerAdded(String name, Timer timer);
// ... corresponding removal methods
abstract class Base implements MetricRegistryListener {
// No-op base implementation
}
}
// Supplier interface for metric factory methods
@FunctionalInterface
public interface MetricSupplier<T extends Metric> {
T newMetric();
}MetricRegistry instance (or use SharedMetricRegistries for global access)counter(), meter(), etc.)Use specific reservoir implementations to control sampling behavior for histograms and timers based on your data characteristics and memory constraints.
All core metric types are thread-safe. Use SharedMetricRegistries to access the same metrics across different application components.
Combine multiple reporters (console for debugging, CSV for analysis, SLF4J for log aggregation) to get comprehensive visibility into application behavior.
Use the Clock abstraction and custom implementations for deterministic testing of time-based metrics like meters and timers.