From 73698ee25eed5d69ade9a8f7634085470884c751 Mon Sep 17 00:00:00 2001 From: Mark Wolters Date: Sat, 7 Oct 2023 11:14:38 -0400 Subject: [PATCH] adding ConsoleReporter class --- .../metrics/reporters/ConsoleReporter.java | 213 ++++++++++++++++++ .../io/nosqlbench/components/NBBuilders.java | 40 ++++ pom.xml | 2 +- 3 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 nb-api/src/main/java/io/nosqlbench/api/engine/metrics/reporters/ConsoleReporter.java diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/reporters/ConsoleReporter.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/reporters/ConsoleReporter.java new file mode 100644 index 0000000000..dab1ae330f --- /dev/null +++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/reporters/ConsoleReporter.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2023 nosqlbench + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.nosqlbench.api.engine.metrics.reporters; + +import com.codahale.metrics.*; +import com.codahale.metrics.Timer; +import io.nosqlbench.api.labels.NBLabels; +import io.nosqlbench.components.NBComponent; +import io.nosqlbench.components.PeriodicTaskComponent; + +import java.io.PrintStream; +import java.text.DateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class ConsoleReporter extends PeriodicTaskComponent { + private static final int CONSOLE_WIDTH = 80; + + private final PrintStream output; + private final Locale locale = Locale.US;; + private final Clock clock = Clock.defaultClock(); + private final DateFormat dateFormat; + private final Set disabledMetricAttributes; + private final String rateUnit; + private final long rateFactor; + private final String durationUnit = TimeUnit.NANOSECONDS.toString().toLowerCase(Locale.US); + private final long durationFactor = TimeUnit.NANOSECONDS.toNanos(1); + public ConsoleReporter(NBComponent node, NBLabels extraLabels, int seconds, boolean oneLastTime, + PrintStream output, Set disabledMetricAttributes) { + super(node, extraLabels, seconds, oneLastTime); + this.output = output; + this.dateFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, + DateFormat.MEDIUM, + locale); + dateFormat.setTimeZone(TimeZone.getDefault()); + this.disabledMetricAttributes = disabledMetricAttributes; + String s = TimeUnit.NANOSECONDS.toString().toLowerCase(Locale.US); + rateUnit = s.substring(0, s.length() - 1); + this.rateFactor = TimeUnit.NANOSECONDS.toSeconds(1); + } + + @Override + protected void task() { + + } + + public void report(SortedMap gauges, + SortedMap counters, + SortedMap histograms, + SortedMap meters, + SortedMap timers) { + final String dateTime = dateFormat.format(new Date(clock.getTime())); + printWithBanner(dateTime, '='); + output.println(); + + if (!gauges.isEmpty()) { + printWithBanner("-- Gauges", '-'); + for (Map.Entry entry : gauges.entrySet()) { + output.println(entry.getKey()); + printGauge(entry.getValue()); + } + output.println(); + } + + if (!counters.isEmpty()) { + printWithBanner("-- Counters", '-'); + for (Map.Entry entry : counters.entrySet()) { + output.println(entry.getKey()); + printCounter(entry); + } + output.println(); + } + + if (!histograms.isEmpty()) { + printWithBanner("-- Histograms", '-'); + for (Map.Entry entry : histograms.entrySet()) { + output.println(entry.getKey()); + printHistogram(entry.getValue()); + } + output.println(); + } + + if (!meters.isEmpty()) { + printWithBanner("-- Meters", '-'); + for (Map.Entry entry : meters.entrySet()) { + output.println(entry.getKey()); + printMeter(entry.getValue()); + } + output.println(); + } + + if (!timers.isEmpty()) { + printWithBanner("-- Timers", '-'); + for (Map.Entry entry : timers.entrySet()) { + output.println(entry.getKey()); + printTimer(entry.getValue()); + } + output.println(); + } + + output.println(); + output.flush(); + } + + private void printMeter(Meter meter) { + printIfEnabled(MetricAttribute.COUNT, String.format(locale, " count = %d", meter.getCount())); + printIfEnabled(MetricAttribute.MEAN_RATE, String.format(locale, " mean rate = %2.2f events/%s", convertRate(meter.getMeanRate()), getRateUnit())); + printIfEnabled(MetricAttribute.M1_RATE, String.format(locale, " 1-minute rate = %2.2f events/%s", convertRate(meter.getOneMinuteRate()), getRateUnit())); + printIfEnabled(MetricAttribute.M5_RATE, String.format(locale, " 5-minute rate = %2.2f events/%s", convertRate(meter.getFiveMinuteRate()), getRateUnit())); + printIfEnabled(MetricAttribute.M15_RATE, String.format(locale, " 15-minute rate = %2.2f events/%s", convertRate(meter.getFifteenMinuteRate()), getRateUnit())); + } + + private void printCounter(Map.Entry entry) { + output.printf(locale, " count = %d%n", entry.getValue().getCount()); + } + + private void printGauge(Gauge gauge) { + output.printf(locale, " value = %s%n", gauge.getValue()); + } + + private void printHistogram(Histogram histogram) { + printIfEnabled(MetricAttribute.COUNT, String.format(locale, " count = %d", histogram.getCount())); + Snapshot snapshot = histogram.getSnapshot(); + printIfEnabled(MetricAttribute.MIN, String.format(locale, " min = %d", snapshot.getMin())); + printIfEnabled(MetricAttribute.MAX, String.format(locale, " max = %d", snapshot.getMax())); + printIfEnabled(MetricAttribute.MEAN, String.format(locale, " mean = %2.2f", snapshot.getMean())); + printIfEnabled(MetricAttribute.STDDEV, String.format(locale, " stddev = %2.2f", snapshot.getStdDev())); + printIfEnabled(MetricAttribute.P50, String.format(locale, " median = %2.2f", snapshot.getMedian())); + printIfEnabled(MetricAttribute.P75, String.format(locale, " 75%% <= %2.2f", snapshot.get75thPercentile())); + printIfEnabled(MetricAttribute.P95, String.format(locale, " 95%% <= %2.2f", snapshot.get95thPercentile())); + printIfEnabled(MetricAttribute.P98, String.format(locale, " 98%% <= %2.2f", snapshot.get98thPercentile())); + printIfEnabled(MetricAttribute.P99, String.format(locale, " 99%% <= %2.2f", snapshot.get99thPercentile())); + printIfEnabled(MetricAttribute.P999, String.format(locale, " 99.9%% <= %2.2f", snapshot.get999thPercentile())); + } + + private void printTimer(Timer timer) { + final Snapshot snapshot = timer.getSnapshot(); + printIfEnabled(MetricAttribute.COUNT, String.format(locale, " count = %d", timer.getCount())); + printIfEnabled(MetricAttribute.MEAN_RATE, String.format(locale, " mean rate = %2.2f calls/%s", convertRate(timer.getMeanRate()), getRateUnit())); + printIfEnabled(MetricAttribute.M1_RATE, String.format(locale, " 1-minute rate = %2.2f calls/%s", convertRate(timer.getOneMinuteRate()), getRateUnit())); + printIfEnabled(MetricAttribute.M5_RATE, String.format(locale, " 5-minute rate = %2.2f calls/%s", convertRate(timer.getFiveMinuteRate()), getRateUnit())); + printIfEnabled(MetricAttribute.M15_RATE, String.format(locale, " 15-minute rate = %2.2f calls/%s", convertRate(timer.getFifteenMinuteRate()), getRateUnit())); + + printIfEnabled(MetricAttribute.MIN, String.format(locale, " min = %2.2f %s", convertDuration(snapshot.getMin()), getDurationUnit())); + printIfEnabled(MetricAttribute.MAX, String.format(locale, " max = %2.2f %s", convertDuration(snapshot.getMax()), getDurationUnit())); + printIfEnabled(MetricAttribute.MEAN, String.format(locale, " mean = %2.2f %s", convertDuration(snapshot.getMean()), getDurationUnit())); + printIfEnabled(MetricAttribute.STDDEV, String.format(locale, " stddev = %2.2f %s", convertDuration(snapshot.getStdDev()), getDurationUnit())); + printIfEnabled(MetricAttribute.P50, String.format(locale, " median = %2.2f %s", convertDuration(snapshot.getMedian()), getDurationUnit())); + printIfEnabled(MetricAttribute.P75, String.format(locale, " 75%% <= %2.2f %s", convertDuration(snapshot.get75thPercentile()), getDurationUnit())); + printIfEnabled(MetricAttribute.P95, String.format(locale, " 95%% <= %2.2f %s", convertDuration(snapshot.get95thPercentile()), getDurationUnit())); + printIfEnabled(MetricAttribute.P98, String.format(locale, " 98%% <= %2.2f %s", convertDuration(snapshot.get98thPercentile()), getDurationUnit())); + printIfEnabled(MetricAttribute.P99, String.format(locale, " 99%% <= %2.2f %s", convertDuration(snapshot.get99thPercentile()), getDurationUnit())); + printIfEnabled(MetricAttribute.P999, String.format(locale, " 99.9%% <= %2.2f %s", convertDuration(snapshot.get999thPercentile()), getDurationUnit())); + } + + private void printWithBanner(String s, char c) { + output.print(s); + output.print(' '); + for (int i = 0; i < (CONSOLE_WIDTH - s.length() - 1); i++) { + output.print(c); + } + output.println(); + } + + /** + * Print only if the attribute is enabled + * + * @param type Metric attribute + * @param status Status to be logged + */ + private void printIfEnabled(MetricAttribute type, String status) { + if (getDisabledMetricAttributes().contains(type)) { + return; + } + + output.println(status); + } + + private Set getDisabledMetricAttributes() { + return disabledMetricAttributes; + } + + protected String getRateUnit() { + return rateUnit; + } + + protected double convertRate(double rate) { + return rate * rateFactor; + } + + protected String getDurationUnit() { + return durationUnit; + } + + protected double convertDuration(double duration) { + return duration / durationFactor; + } +} diff --git a/nb-api/src/main/java/io/nosqlbench/components/NBBuilders.java b/nb-api/src/main/java/io/nosqlbench/components/NBBuilders.java index 54eba261e9..c44d574cc2 100644 --- a/nb-api/src/main/java/io/nosqlbench/components/NBBuilders.java +++ b/nb-api/src/main/java/io/nosqlbench/components/NBBuilders.java @@ -16,6 +16,7 @@ package io.nosqlbench.components; +import com.codahale.metrics.MetricAttribute; import io.nosqlbench.api.csvoutput.CsvOutputPluginWriter; import com.codahale.metrics.Meter; import io.nosqlbench.api.engine.metrics.DeltaHdrHistogramReservoir; @@ -24,6 +25,7 @@ import io.nosqlbench.api.engine.metrics.instruments.NBMetricCounter; import io.nosqlbench.api.engine.metrics.instruments.NBMetricHistogram; import io.nosqlbench.api.engine.metrics.instruments.NBMetricTimer; +import io.nosqlbench.api.engine.metrics.reporters.ConsoleReporter; import io.nosqlbench.api.engine.metrics.reporters.CsvReporter; import io.nosqlbench.api.engine.metrics.reporters.MetricInstanceFilter; import io.nosqlbench.api.engine.metrics.instruments.*; @@ -38,10 +40,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.PrintStream; import java.nio.file.Path; import java.util.Arrays; import java.util.DoubleSummaryStatistics; import java.util.List; +import java.util.Set; import java.util.function.Supplier; public class NBBuilders { @@ -154,6 +158,42 @@ public NBShutdownHook shutdownHook(NBComponent component) { return new NBShutdownHook(component); } + public static class ConsoleReporterBuilder { + //NBComponent node, NBLabels extraLabels, int seconds, boolean oneLastTime, + // PrintStream output + + private final NBComponent component; + private final PrintStream output; + private NBLabels labels = null; + private int interval = 1; + private boolean oneLastTime = false; + private Set disabledMetricAttributes = Set.of(); + + public ConsoleReporterBuilder(NBComponent component, PrintStream output) { + this.component = component; + this.output = output; + } + public ConsoleReporterBuilder labels(NBLabels labels) { + this.labels = labels; + return this; + } + public ConsoleReporterBuilder interval(int interval) { + this.interval = interval; + return this; + } + public ConsoleReporterBuilder oneLastTime(boolean oneLastTime) { + this.oneLastTime = oneLastTime; + return this; + } + public ConsoleReporterBuilder disabledMetricAttributes(Set disabledMetricAttributes) { + this.disabledMetricAttributes = disabledMetricAttributes; + return this; + } + public ConsoleReporter build() { + return new ConsoleReporter(component, labels, interval, oneLastTime, output, disabledMetricAttributes); + } + } + public static class CsvOutputWriterBuilder { private final NBComponent component; diff --git a/pom.xml b/pom.xml index 9cbcbfe0c9..cf316005e5 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ nb5-proof nb5 nbr - nbr-examples + nb-api nb-annotations nb-spectest