
no.mnemonic.commons.metrics.TimerContext Maven / Gradle / Ivy
package no.mnemonic.commons.metrics;
import no.mnemonic.commons.logging.Logger;
import no.mnemonic.commons.logging.Logging;
import java.time.Clock;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* A timer context is a helper to register timing metrics for your code.
*
* Example:
*
* LongAdder executionTimeInMillis = new LongAdder();
* try (TimerContext ignored = TimerContext.timerMillis(executionTimeInMillis::add) {
* //do some work
* }
* System.out.println("Milliseconds required for work: " + executionTimeInMillis);
*
*
* For long-living worker components, a good use case is to define a LongAdder in your component instance
* for measuring accumulated time for an operation, by appending to it for every execution.
*/
public class TimerContext implements AutoCloseable {
private static final Logger LOGGER = Logging.getLogger(TimerContext.class);
private static Clock clock = Clock.systemUTC();
enum MetricType {
millis(clock::millis),
nanos(() -> TimeUnit.MILLISECONDS.toNanos(clock.millis())),
seconds(() -> TimeUnit.MILLISECONDS.toSeconds(clock.millis()));
private final Supplier currentSupplier;
MetricType(Supplier currentSupplier) {
this.currentSupplier = currentSupplier;
}
public long getCurrent() {
return currentSupplier.get();
}
}
private final Consumer metric;
private final MetricType type;
private final long startTime;
private TimerContext(Consumer metric, MetricType type) {
if (metric == null) throw new IllegalArgumentException("Metric not set");
if (type == null) throw new IllegalArgumentException("Type not set");
this.metric = metric;
this.type = type;
this.startTime = type.getCurrent();
}
@Override
public void close() {
try {
metric.accept(type.getCurrent() - startTime);
} catch (Throwable e) {
LOGGER.warning(e, "Error updating timer metric");
}
}
public static TimerContext timerMillis(Consumer metric) {
return new TimerContext(metric, MetricType.millis);
}
public static TimerContext timerNanos(Consumer metric) {
return new TimerContext(metric, MetricType.nanos);
}
public static TimerContext timerSeconds(Consumer metric) {
return new TimerContext(metric, MetricType.seconds);
}
static void setClock(Clock clock) {
TimerContext.clock = clock;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy