下面列出了怎么用com.codahale.metrics.Snapshot的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testSkipBigValues() {
Reservoir reservoir = new HdrBuilder().withHighestTrackableValue(100, OverflowResolver.SKIP).buildReservoir();
reservoir.update(101);
Snapshot snapshot = reservoir.getSnapshot();
assertEquals(0, snapshot.getMax());
reservoir.update(100);
snapshot = reservoir.getSnapshot();
assertEquals(100, snapshot.getMax());
reservoir.update(99);
snapshot = reservoir.getSnapshot();
assertEquals(99, snapshot.getMin());
}
Future<Snapshot> getNextHistogramSnapshot(String name) {
synchronized (histogramSnapshotFutures) {
List<CompletableFuture<Snapshot>> futures;
if (histogramSnapshotFutures.containsKey(name)) {
futures = histogramSnapshotFutures.get(name);
} else {
futures = new ArrayList<>();
histogramSnapshotFutures.put(name, futures);
}
CompletableFuture<Snapshot> future = new CompletableFuture<>();
futures.add(future);
return future;
}
}
/**
* @param rescale the submitted sum by this multiplier. 1.0 is the identity (no rescale).
*/
void reportSampling(Map.Entry<String, ? extends Sampling> entry, String typeDimValue, double rescale, List<MetricDatum> data) {
Sampling metric = entry.getValue();
Snapshot snapshot = metric.getSnapshot();
double scaledSum = sum(snapshot.getValues()) * rescale;
final StatisticSet statisticSet = new StatisticSet()
.withSum(scaledSum)
.withSampleCount((double) snapshot.size())
.withMinimum((double) snapshot.getMin() * rescale)
.withMaximum((double) snapshot.getMax() * rescale);
DemuxedKey key = new DemuxedKey(appendGlobalDimensions(entry.getKey()));
Iterables.addAll(data, key.newDatums(typeDimName, typeDimValue, new Function<MetricDatum, MetricDatum>() {
@Override
public MetricDatum apply(MetricDatum datum) {
return datum.withStatisticValues(statisticSet);
}
}));
}
private Set<Metric> buildHistograms(String name, Histogram histogram, long timestamp, Map<String, String> tags) {
final MetricsCollector collector = MetricsCollector.createNew(name, tags, timestamp);
final Snapshot snapshot = histogram.getSnapshot();
if (getChangeCount(name, histogram.getCount()) == 0) {
return Collections.emptySet();
}
return collector.addMetric("count", histogram.getCount())
.addMetric("max", snapshot.getMax())
.addMetric("min", snapshot.getMin())
.addMetric("mean", snapshot.getMean())
.addMetric("stddev", snapshot.getStdDev())
.addMetric("median", snapshot.getMedian())
.addMetric("p75", snapshot.get75thPercentile())
.addMetric("p95", snapshot.get95thPercentile())
.addMetric("p98", snapshot.get98thPercentile())
.addMetric("p99", snapshot.get99thPercentile())
.addMetric("p999", snapshot.get999thPercentile())
.build();
}
private Set<Metric> buildHistograms(String name, Histogram histogram, long timestamp, Map<String, String> tags) {
final MetricsCollector collector = MetricsCollector.createNew(name, tags, timestamp);
final Snapshot snapshot = histogram.getSnapshot();
if (getChangeCount(name, histogram.getCount()) == 0) {
return Collections.emptySet();
}
return collector.addMetric("count", histogram.getCount())
.addMetric("max", snapshot.getMax())
.addMetric("min", snapshot.getMin())
.addMetric("mean", snapshot.getMean())
.addMetric("stddev", snapshot.getStdDev())
.addMetric("median", snapshot.getMedian())
.addMetric("p75", snapshot.get75thPercentile())
.addMetric("p95", snapshot.get95thPercentile())
.addMetric("p98", snapshot.get98thPercentile())
.addMetric("p99", snapshot.get99thPercentile())
.addMetric("p999", snapshot.get999thPercentile())
.build();
}
private Set<Metric> buildHistograms(String name, Histogram histogram, long timestamp, Map<String, String> tags) {
final MetricsCollector collector = MetricsCollector.createNew(name, tags, timestamp);
final Snapshot snapshot = histogram.getSnapshot();
if (getChangeCount(name, histogram.getCount()) == 0) {
return Collections.emptySet();
}
return collector.addMetric("count", histogram.getCount())
.addMetric("max", snapshot.getMax())
.addMetric("min", snapshot.getMin())
.addMetric("mean", snapshot.getMean())
.addMetric("stddev", snapshot.getStdDev())
.addMetric("median", snapshot.getMedian())
.addMetric("p75", snapshot.get75thPercentile())
.addMetric("p95", snapshot.get95thPercentile())
.addMetric("p98", snapshot.get98thPercentile())
.addMetric("p99", snapshot.get99thPercentile())
.addMetric("p999", snapshot.get999thPercentile())
.build();
}
private Set<Metric> buildTimers(String name, Timer timer, long timestamp, Map<String, String> tags) {
final MetricsCollector collector = MetricsCollector.createNew(name, tags, timestamp);
final Snapshot snapshot = timer.getSnapshot();
if (getChangeCount(name, timer.getCount()) == 0) {
return Collections.emptySet();
}
return collector.addMetric("count", timer.getCount())
// convert rate
.addMetric("m15", convertRate(timer.getFifteenMinuteRate()))
.addMetric("m5", convertRate(timer.getFiveMinuteRate()))
.addMetric("m1", convertRate(timer.getOneMinuteRate()))
.addMetric("mean_rate", convertRate(timer.getMeanRate()))
// convert duration
.addMetric("max", convertDuration(snapshot.getMax()))
.addMetric("min", convertDuration(snapshot.getMin()))
.addMetric("mean", convertDuration(snapshot.getMean()))
.addMetric("stddev", convertDuration(snapshot.getStdDev()))
.addMetric("median", convertDuration(snapshot.getMedian()))
.addMetric("p75", convertDuration(snapshot.get75thPercentile()))
.addMetric("p95", convertDuration(snapshot.get95thPercentile()))
.addMetric("p98", convertDuration(snapshot.get98thPercentile()))
.addMetric("p99", convertDuration(snapshot.get99thPercentile()))
.addMetric("p999", convertDuration(snapshot.get999thPercentile())).build();
}
Future<Snapshot> getNextHistogramSnapshot(String name) {
synchronized (histogramSnapshotFutures) {
List<CompletableFuture<Snapshot>> futures;
if (histogramSnapshotFutures.containsKey(name)) {
futures = histogramSnapshotFutures.get(name);
} else {
futures = new ArrayList<>();
histogramSnapshotFutures.put(name, futures);
}
CompletableFuture<Snapshot> future = new CompletableFuture<>();
futures.add(future);
return future;
}
}
@Test
public void testReduceBigValuesToMax() {
Reservoir reservoir = new HdrBuilder().withHighestTrackableValue(100, OverflowResolver.REDUCE_TO_HIGHEST_TRACKABLE).buildReservoir();
reservoir.update(101);
Snapshot snapshot = reservoir.getSnapshot();
assertEquals(100, snapshot.getMax());
reservoir.update(100);
snapshot = reservoir.getSnapshot();
assertEquals(100, snapshot.getMax());
reservoir.update(99);
snapshot = reservoir.getSnapshot();
assertEquals(99, snapshot.getMin());
}
public static JsonObject toJson(String name, long count, Snapshot snap, List<TagValue> tags, double factor) {
return toJson(
name,
count,
snap.getMin()*factor,
snap.getMax()*factor,
snap.getMean()*factor,
snap.getStdDev()*factor,
snap.getMedian()*factor,
snap.get75thPercentile()*factor,
snap.get95thPercentile()*factor,
snap.get98thPercentile()*factor,
snap.get99thPercentile()*factor,
snap.get999thPercentile()*factor,
tags
);
}
/** @return pretty summary of {@code hist}. */
public static String getPrettyHistogramReport(final Histogram h) {
Snapshot sn = h.getSnapshot();
return
"Mean = " + DOUBLE_FORMAT.format(sn.getMean()) + "\n" +
"Min = " + DOUBLE_FORMAT.format(sn.getMin()) + "\n" +
"Max = " + DOUBLE_FORMAT.format(sn.getMax()) + "\n" +
"StdDev = " + DOUBLE_FORMAT.format(sn.getStdDev()) + "\n" +
"50th = " + DOUBLE_FORMAT.format(sn.getMedian()) + "\n" +
"75th = " + DOUBLE_FORMAT.format(sn.get75thPercentile()) + "\n" +
"95th = " + DOUBLE_FORMAT.format(sn.get95thPercentile()) + "\n" +
"99th = " + DOUBLE_FORMAT.format(sn.get99thPercentile()) + "\n" +
"99.9th = " + DOUBLE_FORMAT.format(sn.get999thPercentile()) + "\n" +
"99.99th = " + DOUBLE_FORMAT.format(sn.getValue(0.9999)) + "\n" +
"99.999th = " + DOUBLE_FORMAT.format(sn.getValue(0.99999));
}
private void reportTimer(String name, Timer timer, long timestamp) {
final Snapshot snapshot = timer.getSnapshot();
TimerPrefixes timerPrefixes = this.timerPrefixes.getUnchecked(name);
doSend(timerPrefixes.max, convertDuration(snapshot.getMax()), timestamp);
doSend(timerPrefixes.mean, convertDuration(snapshot.getMean()), timestamp);
doSend(timerPrefixes.min, convertDuration(snapshot.getMin()), timestamp);
doSend(timerPrefixes.stddev, convertDuration(snapshot.getStdDev()), timestamp);
doSend(timerPrefixes.p50, convertDuration(snapshot.getMedian()), timestamp);
doSend(timerPrefixes.p75, convertDuration(snapshot.get75thPercentile()), timestamp);
doSend(timerPrefixes.p95, convertDuration(snapshot.get95thPercentile()), timestamp);
doSend(timerPrefixes.p98, convertDuration(snapshot.get98thPercentile()), timestamp);
doSend(timerPrefixes.p99, convertDuration(snapshot.get99thPercentile()), timestamp);
doSend(timerPrefixes.p999, convertDuration(snapshot.get999thPercentile()), timestamp);
reportMetered(name, timer, timestamp);
}
private void reportHistogram(String name, Histogram histogram, long timestamp) {
final Snapshot snapshot = histogram.getSnapshot();
HistogramPrefixes histogramPrefixes = this.histogramPrefixes.getUnchecked(name);
doSend(histogramPrefixes.count, histogram.getCount(), timestamp);
doSend(histogramPrefixes.max, snapshot.getMax(), timestamp);
doSend(histogramPrefixes.mean, snapshot.getMean(), timestamp);
doSend(histogramPrefixes.min, snapshot.getMin(), timestamp);
doSend(histogramPrefixes.stddev, snapshot.getStdDev(), timestamp);
doSend(histogramPrefixes.p50, snapshot.getMedian(), timestamp);
doSend(histogramPrefixes.p75, snapshot.get75thPercentile(), timestamp);
doSend(histogramPrefixes.p95, snapshot.get95thPercentile(), timestamp);
doSend(histogramPrefixes.p98, snapshot.get98thPercentile(), timestamp);
doSend(histogramPrefixes.p99, snapshot.get99thPercentile(), timestamp);
doSend(histogramPrefixes.p999, snapshot.get999thPercentile(), timestamp);
}
@Test
public void invalidatesCachedSnapshotEverySlidingWindowTimeLength() {
TestClock clock = new TestClock();
SlidingWindowHistogram histogram = new SlidingWindowHistogram.Builder()
.numberOfIntervals(12)
.intervalDuration(10, SECONDS)
.autoResize(true)
.build();
SlidingWindowHistogramReservoir reservoir = new SlidingWindowHistogramReservoir(histogram, clock);
reservoir.update(5);
reservoir.update(6);
reservoir.update(7);
Snapshot snapshot1 = reservoir.getSnapshot();
Snapshot snapshot2 = reservoir.getSnapshot();
clock.forward(120 * 1000);
assertThat(snapshot1, sameInstance(snapshot2));
clock.forward(1);
assertThat(reservoir.getSnapshot(), not(sameInstance(snapshot2)));
}
private void writeSnapshotAndCount(String dropwizardName, Snapshot snapshot, long count, double factor, MetricType type, String helpMessage) throws IOException {
String name = sanitizeMetricName(dropwizardName);
writer.writeHelp(name, helpMessage);
writer.writeType(name, type);
writer.writeSample(name, mapOf("quantile", "0.5"), snapshot.getMedian() * factor);
writer.writeSample(name, mapOf("quantile", "0.75"), snapshot.get75thPercentile() * factor);
writer.writeSample(name, mapOf("quantile", "0.95"), snapshot.get95thPercentile() * factor);
writer.writeSample(name, mapOf("quantile", "0.98"), snapshot.get98thPercentile() * factor);
writer.writeSample(name, mapOf("quantile", "0.99"), snapshot.get99thPercentile() * factor);
writer.writeSample(name, mapOf("quantile", "0.999"), snapshot.get999thPercentile() * factor);
writer.writeSample(name + "_min", emptyMap(), snapshot.getMin());
writer.writeSample(name + "_max", emptyMap(), snapshot.getMax());
writer.writeSample(name + "_median", emptyMap(), snapshot.getMedian());
writer.writeSample(name + "_mean", emptyMap(), snapshot.getMean());
writer.writeSample(name + "_stddev", emptyMap(), snapshot.getStdDev());
writer.writeSample(name + "_count", emptyMap(), count);
}
private static JsonObject toJson(Timer timer, TimeUnit rateUnit, TimeUnit durationUnit) {
Snapshot snapshot = timer.getSnapshot();
JsonObject json = new JsonObject();
json.put("type", "timer");
if (timer instanceof ThroughputTimer) {
ThroughputTimer throughput = (ThroughputTimer) timer;
json.put("oneSecondRate", throughput.getValue());
}
// Meter
populateMetered(json, timer, rateUnit);
// Snapshot
double factor = 1.0 / durationUnit.toNanos(1);
populateSnapshot(json, snapshot, factor);
// Duration rate
String duration = durationUnit.toString().toLowerCase();
json.put("durationRate", duration);
return json;
}
/**
* The {@link Snapshot} values of {@link Histogram} are reported as {@link StatisticSet} raw. In other words, the
* conversion using the duration factor does NOT apply.
* <p>
* Please note, the reported values submitted only if they show some data (greater than zero) in order to:
* <p>
* 1. save some money
* 2. prevent com.amazonaws.services.cloudwatch.model.InvalidParameterValueException if empty {@link Snapshot}
* is submitted
* <p>
* If {@link Builder#withZeroValuesSubmission()} is {@code true}, then all values will be submitted
*
* @see Histogram#getSnapshot
*/
private void processHistogram(final String metricName, final Histogram histogram, final List<MetricDatum> metricData) {
final Snapshot snapshot = histogram.getSnapshot();
if (builder.withZeroValuesSubmission || snapshot.size() > 0) {
for (final Percentile percentile : builder.percentiles) {
final double value = snapshot.getValue(percentile.getQuantile());
stageMetricDatum(true, metricName, value, StandardUnit.NONE, percentile.getDesc(), metricData);
}
}
// prevent empty snapshot from causing InvalidParameterValueException
if (snapshot.size() > 0) {
stageMetricDatum(builder.withArithmeticMean, metricName, snapshot.getMean(), StandardUnit.NONE, DIMENSION_SNAPSHOT_MEAN, metricData);
stageMetricDatum(builder.withStdDev, metricName, snapshot.getStdDev(), StandardUnit.NONE, DIMENSION_SNAPSHOT_STD_DEV, metricData);
stageMetricDatumWithRawSnapshot(builder.withStatisticSet, metricName, snapshot, StandardUnit.NONE, metricData);
}
}
/**
* Convert an instance of {@link Histogram}. NOTE: it's assumed that histogram contains non-time
* based values that don't require unit conversion.
* @param name metric name
* @param histogram an instance of {@link Histogram}
* @param propertyFilter limit what properties of a metric are returned
* @param simple use simplified representation for complex metrics - instead of a (name, map)
* only the selected (name "." key, value) pairs will be produced.
* @param consumer consumer that accepts produced objects
*/
static void convertHistogram(String name, Histogram histogram, PropertyFilter propertyFilter,
boolean simple, String separator, BiConsumer<String, Object> consumer) {
Snapshot snapshot = histogram.getSnapshot();
if (simple) {
if (propertyFilter.accept(MEAN)) {
consumer.accept(name + separator + MEAN, snapshot.getMean());
}
} else {
Map<String, Object> response = new LinkedHashMap<>();
String prop = "count";
if (propertyFilter.accept(prop)) {
response.put(prop, histogram.getCount());
}
// non-time based values
addSnapshot(response, snapshot, propertyFilter, false);
if (!response.isEmpty()) {
consumer.accept(name, response);
}
}
}
private void reportTimer(List<Sample> samples, Timestamp timestamp, String name, Timer timer) {
final Snapshot snapshot = timer.getSnapshot();
Map<String, String> rateAttr = Maps.newHashMap();
rateAttr.put("rate_unit", getRateUnit());
Map<String, String> durationAttr = Maps.newHashMap();
durationAttr.put("duration_unit", getDurationUnit());
reportC(samples, timestamp, name, "count", timer.getCount());
reportG(samples, timestamp, name, "max", convertDuration(snapshot.getMax()), durationAttr);
reportG(samples, timestamp, name, "mean", convertDuration(snapshot.getMean()), durationAttr);
reportG(samples, timestamp, name, "min", convertDuration(snapshot.getMin()), durationAttr);
reportG(samples, timestamp, name, "stddev", convertDuration(snapshot.getStdDev()), durationAttr);
reportG(samples, timestamp, name, "p50", convertDuration(snapshot.getMedian()), durationAttr);
reportG(samples, timestamp, name, "p75", convertDuration(snapshot.get75thPercentile()), durationAttr);
reportG(samples, timestamp, name, "p95", convertDuration(snapshot.get95thPercentile()), durationAttr);
reportG(samples, timestamp, name, "p98", convertDuration(snapshot.get98thPercentile()), durationAttr);
reportG(samples, timestamp, name, "p99", convertDuration(snapshot.get99thPercentile()), durationAttr);
reportG(samples, timestamp, name, "p999", convertDuration(snapshot.get999thPercentile()), durationAttr);
reportG(samples, timestamp, name, "mean_rate", convertRate(timer.getMeanRate()), rateAttr);
reportG(samples, timestamp, name, "m1_rate", convertRate(timer.getOneMinuteRate()), rateAttr);
reportG(samples, timestamp, name, "m5_rate", convertRate(timer.getFiveMinuteRate()), rateAttr);
reportG(samples, timestamp, name, "m15_rate", convertRate(timer.getFifteenMinuteRate()), rateAttr);
}
@Override
protected List<Metric> convertMetricEntry(Entry<String, Histogram> metricEntry, long timestamp) {
List<Metric> result = new ArrayList<>();
Histogram histogram = metricEntry.getValue();
Snapshot snapshot = histogram.getSnapshot();
String key = metricEntry.getKey();
MetricType type = MetricType.HISTOGRAM;
result.add(buildCustomMetric(key + ".count", histogram.getCount(), type, timestamp));
result.add(buildCustomMetric(key + ".max", snapshot.getMax(), type, timestamp));
result.add(buildCustomMetric(key + ".min", snapshot.getMin(), type, timestamp));
result.add(buildCustomMetric(key + ".p50", snapshot.getMedian(), type, timestamp));
result.add(buildCustomMetric(key + ".p95", snapshot.get95thPercentile(), type, timestamp));
result.add(buildCustomMetric(key + ".p99", snapshot.get99thPercentile(), type, timestamp));
if (metricQuantiles) {
result.add(buildCustomMetric(key + ".mean", snapshot.getMean(), type, timestamp));
result.add(buildCustomMetric(key + ".p75", snapshot.get75thPercentile(), type, timestamp));
result.add(buildCustomMetric(key + ".p98", snapshot.get98thPercentile(), type, timestamp));
result.add(buildCustomMetric(key + ".p999", snapshot.get999thPercentile(), type, timestamp));
result.add(buildCustomMetric(key + ".stddev", snapshot.getStdDev(), type, timestamp));
}
return result;
}
@Test
public void shouldCacheSnapshot() {
Reservoir reservoir = new HdrBuilder().resetReservoirOnSnapshot().buildReservoir();
reservoir.update(10);
reservoir.update(20);
Snapshot firstSnapshot = reservoir.getSnapshot();
reservoir.update(30);
reservoir.update(40);
Snapshot secondSnapshot = reservoir.getSnapshot();
assertNotSame(firstSnapshot, secondSnapshot);
assertEquals(30, secondSnapshot.getMin());
assertEquals(40, secondSnapshot.getMax());
reservoir.update(50);
reservoir.update(60);
Snapshot thirdSnapshot = reservoir.getSnapshot();
assertNotSame(secondSnapshot, thirdSnapshot);
assertEquals(50, thirdSnapshot.getMin());
assertEquals(60, thirdSnapshot.getMax());
}
public static JsonObject calculateStatsFor(String type){
JsonObject j = new JsonObject();
Snapshot snap = METRICS.histogram(type).getSnapshot();
if(snap != null){
j.put("entryCount", snap.size());
j.put("min", snap.getMin());
j.put("max", snap.getMax());
j.put("mean", snap.getMean());
j.put("median", snap.getMedian());
j.put("75th", snap.get75thPercentile());
j.put("95th", snap.get95thPercentile());
j.put("99th", snap.get99thPercentile());
j.put("stdDev", snap.getStdDev());
}
return j;
}
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
Histogram histogram = (Histogram) object;
SerializeWriter writer = serializer.getWriter();
final Snapshot snapshot = histogram.getSnapshot();
writer.writeFieldValue('{', "count", histogram.getCount());
writer.writeFieldValue(',', "max", snapshot.getMax());
writer.writeFieldValue(',', "mean", snapshot.getMean());
writer.writeFieldValue(',', "min", snapshot.getMin());
writer.writeFieldValue(',', "p50", snapshot.getMedian());
writer.writeFieldValue(',', "p75", snapshot.get75thPercentile());
writer.writeFieldValue(',', "p95", snapshot.get95thPercentile());
writer.writeFieldValue(',', "p98", snapshot.get98thPercentile());
writer.writeFieldValue(',', "p99", snapshot.get99thPercentile());
writer.writeFieldValue(',', "p999", snapshot.get999thPercentile());
writer.writeFieldValue(',', "stddev", snapshot.getStdDev());
writer.write('}');
}
public MetricReport(String name, long counter, long traffic, Snapshot latency, long start, long end) {
this.counter = counter;
this.traffic = traffic;
this.latency = latency;
this.start = start;
this.end = end;
this.name = name;
}
private void printHistogram(Histogram histogram) {
this.outputBufferPrintStream.printf(locale, " count = %d%n", histogram.getCount());
Snapshot snapshot = histogram.getSnapshot();
this.outputBufferPrintStream.printf(locale, " min = %d%n", snapshot.getMin());
this.outputBufferPrintStream.printf(locale, " max = %d%n", snapshot.getMax());
this.outputBufferPrintStream.printf(locale, " mean = %2.2f%n", snapshot.getMean());
this.outputBufferPrintStream.printf(locale, " stddev = %2.2f%n", snapshot.getStdDev());
this.outputBufferPrintStream.printf(locale, " median = %2.2f%n", snapshot.getMedian());
this.outputBufferPrintStream.printf(locale, " 75%% <= %2.2f%n", snapshot.get75thPercentile());
this.outputBufferPrintStream.printf(locale, " 95%% <= %2.2f%n", snapshot.get95thPercentile());
this.outputBufferPrintStream.printf(locale, " 98%% <= %2.2f%n", snapshot.get98thPercentile());
this.outputBufferPrintStream.printf(locale, " 99%% <= %2.2f%n", snapshot.get99thPercentile());
this.outputBufferPrintStream.printf(locale, " 99.9%% <= %2.2f%n", snapshot.get999thPercentile());
}
protected void writeSnapshot(Snapshot snapshot, boolean duration, BufferedWriter writer) throws IOException {
writeWithIndent("min = " + getSnapshotValueString(snapshot.getMin(), duration), writer);
writeWithIndent("max = " + getSnapshotValueString(snapshot.getMax(), duration), writer);
writeWithIndent("mean = " + getSnapshotValueString(snapshot.getMean(), duration), writer);
writeWithIndent("stdDev = " + getSnapshotValueString(snapshot.getStdDev(), duration), writer);
writeWithIndent("median = " + getSnapshotValueString(snapshot.getMedian(), duration), writer);
writeWithIndent("75%% <= " + getSnapshotValueString(snapshot.get75thPercentile(), duration), writer);
writeWithIndent("95%% <= " + getSnapshotValueString(snapshot.get95thPercentile(), duration), writer);
writeWithIndent("98%% <= " + getSnapshotValueString(snapshot.get98thPercentile(), duration), writer);
writeWithIndent("99%% <= " + getSnapshotValueString(snapshot.get99thPercentile(), duration), writer);
writeWithIndent("99.9%% <= " + getSnapshotValueString(snapshot.get999thPercentile(), duration), writer);
if (duration) {
writeWithIndent("duration unit = " + durationUnit, writer);
}
}
private void printTimer(final Timer timer) {
final Snapshot snapshot = timer.getSnapshot();
printIfEnabled(MetricAttribute.COUNT, String.format(this.locale, " count = %d", timer.getCount()));
printIfEnabled(MetricAttribute.MEAN_RATE, String.format(this.locale, " mean rate = %2.2f calls/%s",
convertRate(timer.getMeanRate()), this.rateUnit));
printIfEnabled(MetricAttribute.M1_RATE, String.format(this.locale, " 1-minute rate = %2.2f calls/%s",
convertRate(timer.getOneMinuteRate()), this.rateUnit));
printIfEnabled(MetricAttribute.M5_RATE, String.format(this.locale, " 5-minute rate = %2.2f calls/%s",
convertRate(timer.getFiveMinuteRate()), this.rateUnit));
printIfEnabled(MetricAttribute.M15_RATE, String.format(this.locale, " 15-minute rate = %2.2f calls/%s",
convertRate(timer.getFifteenMinuteRate()), this.rateUnit));
printIfEnabled(MetricAttribute.MIN, String.format(this.locale, " min = %2.2f %s",
convertDuration(snapshot.getMin()), this.durationUnit));
printIfEnabled(MetricAttribute.MAX, String.format(this.locale, " max = %2.2f %s",
convertDuration(snapshot.getMax()), this.durationUnit));
printIfEnabled(MetricAttribute.MEAN, String.format(this.locale, " mean = %2.2f %s",
convertDuration(snapshot.getMean()), this.durationUnit));
printIfEnabled(MetricAttribute.STDDEV, String.format(this.locale, " stddev = %2.2f %s",
convertDuration(snapshot.getStdDev()), this.durationUnit));
printIfEnabled(MetricAttribute.P50, String.format(this.locale, " median = %2.2f %s",
convertDuration(snapshot.getMedian()), this.durationUnit));
printIfEnabled(MetricAttribute.P75, String.format(this.locale, " 75%% <= %2.2f %s",
convertDuration(snapshot.get75thPercentile()), this.durationUnit));
printIfEnabled(MetricAttribute.P95, String.format(this.locale, " 95%% <= %2.2f %s",
convertDuration(snapshot.get95thPercentile()), this.durationUnit));
printIfEnabled(MetricAttribute.P98, String.format(this.locale, " 98%% <= %2.2f %s",
convertDuration(snapshot.get98thPercentile()), this.durationUnit));
printIfEnabled(MetricAttribute.P99, String.format(this.locale, " 99%% <= %2.2f %s",
convertDuration(snapshot.get99thPercentile()), this.durationUnit));
printIfEnabled(MetricAttribute.P999, String.format(this.locale, " 99.9%% <= %2.2f %s",
convertDuration(snapshot.get999thPercentile()), this.durationUnit));
}
private void reportHistogram(JsonGenerator json, String name, Histogram histogram) throws IOException {
Snapshot snapshot = histogram.getSnapshot();
json.writeFieldName(sanitize(name));
json.writeStartObject();
json.writeNumberField("count", histogram.getCount());
writeSnapshot(json, snapshot);
json.writeEndObject();
}
private Set<Metric> buildHistograms(String name, Histogram histogram, long timestamp, Map<String, String> tags) {
final MetricsCollector collector = MetricsCollector.createNew(name, tags, timestamp);
final Snapshot snapshot = histogram.getSnapshot();
if (getChangeCount(name, histogram.getCount()) == 0) {
return Collections.emptySet();
}
return collector.addMetric("count", histogram.getCount()).addMetric("max", snapshot.getMax())
.addMetric("min", snapshot.getMin()).addMetric("mean", snapshot.getMean())
.addMetric("stddev", snapshot.getStdDev()).addMetric("median", snapshot.getMedian())
.addMetric("p75", snapshot.get75thPercentile()).addMetric("p95", snapshot.get95thPercentile())
.addMetric("p98", snapshot.get98thPercentile()).addMetric("p99", snapshot.get99thPercentile())
.addMetric("p999", snapshot.get999thPercentile()).build();
}
/**
* Shuts down the NettyPerfClient.
*/
protected void shutdown() {
if (shutdownCalled.compareAndSet(false, true)) {
logger.info("Shutting down NettyPerfClient");
isRunning = false;
group.shutdownGracefully();
long totalRunTimeInMs = System.currentTimeMillis() - perfClientStartTime;
try {
if (!group.awaitTermination(5, TimeUnit.SECONDS)) {
logger.error("Netty worker did not shutdown within timeout");
} else {
logger.info("NettyPerfClient shutdown complete");
}
if (backgroundScheduler != null) {
shutDownExecutorService(backgroundScheduler, 5, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
logger.error("NettyPerfClient shutdown interrupted", e);
} finally {
logger.info("Executed for approximately {} s and sent {} requests ({} requests/sec)",
(float) totalRunTimeInMs / (float) Time.MsPerSec, totalRequestCount.get(),
(float) totalRequestCount.get() * (float) Time.MsPerSec / (float) totalRunTimeInMs);
Snapshot rttStatsSnapshot = perfClientMetrics.requestRoundTripTimeInMs.getSnapshot();
logger.info("RTT stats: Min - {} ms, Mean - {} ms, Max - {} ms", rttStatsSnapshot.getMin(),
rttStatsSnapshot.getMean(), rttStatsSnapshot.getMax());
logger.info("RTT stats: 95th percentile - {} ms, 99th percentile - {} ms, 999th percentile - {} ms",
rttStatsSnapshot.get95thPercentile(), rttStatsSnapshot.get99thPercentile(),
rttStatsSnapshot.get999thPercentile());
reporter.stop();
shutdownLatch.countDown();
}
}
}