ai.vespa.feed.client.OperationStats Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package ai.vespa.feed.client;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Statistics for feed operations over HTTP against a Vespa cluster.
*
* @author jonmv
*/
public class OperationStats {
private final double duration;
private final long requests;
private final Map responsesByCode;
private final long inflight;
private final long targetInflight;
private final long exceptions;
private final long averageLatencyMillis;
private final long minLatencyMillis;
private final long maxLatencyMillis;
private final long bytesSent;
private final long bytesReceived;
public OperationStats(double duration, long requests, Map responsesByCode, long exceptions,
long inflight, long targetInFlight, long averageLatencyMillis, long minLatencyMillis,
long maxLatencyMillis, long bytesSent, long bytesReceived) {
this.duration = duration;
this.requests = requests;
this.responsesByCode = responsesByCode;
this.exceptions = exceptions;
this.inflight = inflight;
this.targetInflight = targetInFlight;
this.averageLatencyMillis = averageLatencyMillis;
this.minLatencyMillis = minLatencyMillis;
this.maxLatencyMillis = maxLatencyMillis;
this.bytesSent = bytesSent;
this.bytesReceived = bytesReceived;
}
/** Returns the difference between this and the initial.
* Min and max latency, inflight and targetInflight are not modified.
*/
public OperationStats since(OperationStats initial) {
return new OperationStats(duration - initial.duration,
requests - initial.requests,
responsesByCode.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> entry.getValue() - initial.responsesByCode.getOrDefault(entry.getKey(), 0L))),
exceptions - initial.exceptions,
inflight,
targetInflight,
responsesByCode.size() == initial.responsesByCode.size() ? 0 :
(averageLatencyMillis * responsesByCode.size() - initial.averageLatencyMillis * initial.responsesByCode.size())
/ (responsesByCode.size() - initial.responsesByCode.size()),
minLatencyMillis,
maxLatencyMillis,
bytesSent - initial.bytesSent,
bytesReceived - initial.bytesReceived);
}
/** Number of HTTP requests attempted. */
public long requests() {
return requests;
}
/** Number of HTTP responses received. */
public long responses() {
return requests - inflight - exceptions;
}
/** Number of 200 OK HTTP responses received. */
public long successes() {
return responsesByCode.getOrDefault(200, 0L);
}
/** Number of HTTP responses by status code. */
public Map responsesByCode() {
return responsesByCode;
}
/** Number of exceptions (instead of responses). */
public long exceptions() {
return exceptions;
}
/** Number of attempted requests which haven't yielded a response or exception yet. */
public long inflight() {
return inflight;
}
/** Average request-response latency, or -1. */
public long averageLatencyMillis() {
return averageLatencyMillis;
}
/** Minimum request-response latency, or -1. */
public long minLatencyMillis() {
return minLatencyMillis;
}
/** Maximum request-response latency, or -1. */
public long maxLatencyMillis() {
return maxLatencyMillis;
}
/** Number of bytes sent, for HTTP requests with a response. */
public long bytesSent() {
return bytesSent;
}
/** Number of bytes received in HTTP responses. */
public long bytesReceived() {
return bytesReceived;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OperationStats that = (OperationStats) o;
return requests == that.requests && inflight == that.inflight && exceptions == that.exceptions && averageLatencyMillis == that.averageLatencyMillis && minLatencyMillis == that.minLatencyMillis && maxLatencyMillis == that.maxLatencyMillis && bytesSent == that.bytesSent && bytesReceived == that.bytesReceived && responsesByCode.equals(that.responsesByCode);
}
@Override
public int hashCode() {
return Objects.hash(requests, responsesByCode, inflight, exceptions, averageLatencyMillis, minLatencyMillis, maxLatencyMillis, bytesSent, bytesReceived);
}
@Override
public String toString() {
Map rateByCode = responsesByCode.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue()/duration));
return "Stats{" +
"requests=" + requests +
", responsesByCode=" + responsesByCode +
", responseRateByCode=" + rateByCode +
", exceptions=" + exceptions +
", inflight=" + inflight +
", targetInflight=" + targetInflight +
", averageLatencyMillis=" + averageLatencyMillis +
", minLatencyMillis=" + minLatencyMillis +
", maxLatencyMillis=" + maxLatencyMillis +
", bytesSent=" + bytesSent +
", bytesReceived=" + bytesReceived +
'}';
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy