// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.curator.stats;
import java.time.Duration;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import static java.lang.Math.round;
/**
* Metrics on the time interval associated with e.g. the acquiring of a lock.
*
*
In the language of {@link LatencyStats}, these metrics relate to time intervals associated
* with e.g. the acquiring of a lock, collected over time period.
*
* @see LatencyStats
* @author hakon
*/
// @Immutable
public class LatencyMetrics {
private final Duration latency;
private final Duration maxLatency;
private final Duration maxActiveLatency;
private final double startHz;
private final double endHz;
private final Map loadByThread;
private final double load;
private final int maxLoad;
private final int currentLoad;
public LatencyMetrics(Duration latency, Duration maxLatency, Duration maxActiveLatency,
double startHz, double endHz, Map loadByThread,
double load, int maxLoad, int currentLoad) {
this.latency = latency;
this.maxLatency = maxLatency;
this.maxActiveLatency = maxActiveLatency;
this.startHz = startHz;
this.endHz = endHz;
this.loadByThread = new TreeMap<>(loadByThread);
this.load = load;
this.maxLoad = maxLoad;
this.currentLoad = currentLoad;
}
/** Returns the average latency of all intervals that ended in the period. */
public double latencySeconds() { return secondsWithMillis(latency); }
/** Returns the maximum latency of any interval that ended in the period. */
public double maxLatencySeconds() { return secondsWithMillis(maxLatency); }
/** Return the maximum latency of any interval that ended in the period, or is still active. */
public double maxActiveLatencySeconds() { return secondsWithMillis(maxActiveLatency); }
/** Returns the average number of intervals that started in the period per second. */
public double startHz() { return roundTo3DecimalPlaces(startHz); }
/** Returns the average number of intervals that ended in the period per second. */
public double endHz() { return roundTo3DecimalPlaces(endHz); }
/** Returns the average load of the implied time periond, for each thread with non-zero load, with 3 decimal places precision. */
public Map loadByThread() {
Map result = new TreeMap<>();
loadByThread.forEach((name, load) -> result.put(name, roundTo3DecimalPlaces(load)));
return Collections.unmodifiableMap(result);
}
/** The average load of the implied time period, with 3 decimal places precision. */
public double load() { return roundTo3DecimalPlaces(load); }
/** Returns the maximum number of concurrently active intervals in the period. */
public int maxLoad() { return maxLoad; }
/** Returns the number of active intervals right now. */
public int currentLoad() { return currentLoad; }
@Override
public String toString() {
return "LatencyMetrics{" +
"averageLatency=" + latency +
", maxLatency=" + maxLatency +
", maxActiveLatency=" + maxActiveLatency +
", numIntervalsStarted=" + startHz +
", numIntervalsEnded=" + endHz +
", load=" + load +
", maxLoad=" + maxLoad +
", currentLoad=" + currentLoad +
'}';
}
private double secondsWithMillis(Duration duration) { return duration.toMillis() / 1000.0; }
private double roundTo3DecimalPlaces(double value) { return round(value * 1000) / 1000.0; }
}