aboutsummaryrefslogtreecommitdiffstats
path: root/zkfacade/src/main/java/com/yahoo/vespa/curator/stats/LatencyMetrics.java
blob: fd6008ac4f9f4bde6f90cc3e229b23f6edd84ae1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// 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 <em>time interval</em> associated with e.g. the acquiring of a lock.
 *
 * <p>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.</p>
 *
 * @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<String, Double> 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<String, Double> 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 period, for each thread with non-zero load, with 3 decimal places precision. */
    public Map<String, Double> loadByThread() {
        Map<String, Double> 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; }
}