add double summary gauge to track statistics directly

This commit is contained in:
Jonathan Shook 2023-08-30 00:57:32 -05:00
parent 4951949a19
commit 2949075b20
4 changed files with 137 additions and 20 deletions

View File

@ -29,6 +29,7 @@ import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.ServiceLoader;
import java.util.concurrent.TimeUnit;
@ -189,11 +190,32 @@ public class ActivityMetrics {
return registry;
}
/**
* This variant creates a named metric for all of the stats which may be needed, name with metricname_average,
* and so on. It uses the same data reservoir for all views, but only returns one of them as a handle to the metric.
* This has the effect of leaving some of the metric objects unreferencable from the caller side. This may need
* to be changed in a future update in the even that full inventory management is required on metric objects here.
* @param parent The labeled element the metric pertains to
* @param metricFamilyName The name of the measurement
* @return One of the created metrics, suitable for calling {@link DoubleSummaryGauge#accept(double)} on.
*/
public static DoubleSummaryGauge summaryGauge(NBLabeledElement parent, String metricFamilyName) {
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
DoubleSummaryGauge anyGauge = null;
for (DoubleSummaryGauge.Stat statName: DoubleSummaryGauge.Stat.values()){
final NBLabels labels = parent.getLabels()
.andTypes("name",sanitize(metricFamilyName))
.modifyValue("name", n -> n+"_"+statName.name().toLowerCase());
anyGauge= (DoubleSummaryGauge) register(labels, () -> new DoubleSummaryGauge(labels,statName,stats));
}
return anyGauge;
}
@SuppressWarnings("unchecked")
public static <T> Gauge<T> gauge(NBLabeledElement parent, String metricFamilyName, Gauge<T> gauge) {
final NBLabels labels = parent.getLabels().andTypes("name",sanitize(metricFamilyName));
return (Gauge<T>) register(labels, () -> new NBMetricGauge(labels,gauge));
return (Gauge<T>) register(labels, () -> new NBMetricGaugeWrapper<>(labels,gauge));
}
private static MetricRegistry lookupRegistry() {

View File

@ -0,0 +1,72 @@
/*
* 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;
import io.nosqlbench.api.config.NBLabels;
import io.nosqlbench.api.engine.metrics.instruments.NBMetricGauge;
import java.util.DoubleSummaryStatistics;
/**
* Create a discrete stat reservoir as a gauge.
*/
public class DoubleSummaryGauge implements NBMetricGauge<Double> {
private final NBLabels labels;
private final Stat stat;
private final DoubleSummaryStatistics stats;
public enum Stat {
Min,
Max,
Average,
Count,
Sum
}
public DoubleSummaryGauge(NBLabels labels, Stat stat, DoubleSummaryStatistics stats) {
this.labels = labels;
this.stat = stat;
this.stats = stats;
}
public DoubleSummaryGauge(NBLabels labels, Stat stat) {
this.labels = labels;
this.stat = stat;
this.stats = new DoubleSummaryStatistics();
}
public synchronized void accept(double value) {
stats.accept(value);
}
@Override
public synchronized Double getValue() {
return switch(stat) {
case Min -> stats.getMin();
case Max -> stats.getMax();
case Average -> stats.getAverage();
case Count -> (double) stats.getCount();
case Sum -> stats.getSum();
};
}
@Override
public NBLabels getLabels() {
return labels;
}
}

View File

@ -18,25 +18,7 @@ package io.nosqlbench.api.engine.metrics.instruments;
import com.codahale.metrics.Gauge;
import io.nosqlbench.api.config.NBLabeledElement;
import io.nosqlbench.api.config.NBLabels;
public class NBMetricGauge<T> implements Gauge<T>, NBLabeledElement {
public interface NBMetricGauge<T> extends Gauge<T>, NBLabeledElement {
private final Gauge<? extends T> gauge;
private final NBLabels labels;
public NBMetricGauge(NBLabels labels, Gauge<? extends T> gauge) {
this.gauge = gauge;
this.labels = labels;
}
@Override
public T getValue() {
return gauge.getValue();
}
@Override
public NBLabels getLabels() {
return labels;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.instruments;
import com.codahale.metrics.Gauge;
import io.nosqlbench.api.config.NBLabels;
public class NBMetricGaugeWrapper<T> implements NBMetricGauge<T> {
private final Gauge<? extends T> gauge;
private final NBLabels labels;
public NBMetricGaugeWrapper(NBLabels labels, Gauge<? extends T> gauge) {
this.gauge = gauge;
this.labels = labels;
}
@Override
public T getValue() {
return gauge.getValue();
}
@Override
public NBLabels getLabels() {
return labels;
}
}