mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
provide a fully constructed metric type which can be registered as-is
This commit is contained in:
@@ -63,14 +63,15 @@ public class AtomicInput implements Input, ActivityDefObserver, Gauge<Long>, NBL
|
||||
this.parent = parent;
|
||||
this.activityDef = activityDef;
|
||||
onActivityDefUpdate(activityDef);
|
||||
ActivityMetrics.gauge(this, "input_cycles_first", new NBFunctionGauge(this, () -> (double)this.cycles_min.get()));
|
||||
ActivityMetrics.gauge(this, "input_cycles_last", new NBFunctionGauge(this, () -> (double)this.cycles_max.get()));
|
||||
ActivityMetrics.gauge(this, "input_cycle", new NBFunctionGauge(this, () -> (double)this.cycle_value.get()));
|
||||
ActivityMetrics.gauge(this, "input_cycles_total", new NBFunctionGauge(this, this::getTotalCycles));
|
||||
ActivityMetrics.gauge(this, "input_recycles_first", new NBFunctionGauge(this, () -> (double)this.recycles_min.get()));
|
||||
ActivityMetrics.gauge(this, "input_recycles_last", new NBFunctionGauge(this, () -> (double)this.recycles_max.get()));
|
||||
ActivityMetrics.gauge(this, "input_recycle", new NBFunctionGauge(this, () -> (double) this.recycle_value.get()));
|
||||
ActivityMetrics.gauge(this, "input_recycles_total", new NBFunctionGauge(this, this::getTotalRecycles));
|
||||
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, () -> (double)this.cycles_min.get(),"input_cycles_first"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, () -> (double)this.cycles_max.get(), "input_cycles_last"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, () -> (double)this.cycle_value.get(), "input_cycle"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, this::getTotalCycles, "input_cycles_total"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, () -> (double)this.recycles_min.get(), "input_recycles_first"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, () -> (double)this.recycles_max.get(), "input_recycles_last"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, () -> (double) this.recycle_value.get(),"input_recycle"));
|
||||
ActivityMetrics.register(new NBFunctionGauge(this, this::getTotalRecycles,"input_recycles_total"));
|
||||
}
|
||||
|
||||
private double getTotalRecycles() {
|
||||
|
||||
@@ -98,7 +98,7 @@ public class StandardActivity<R extends Op, S> extends SimpleActivity implements
|
||||
for (OpTemplate ot : opTemplates) {
|
||||
ParsedOp incompleteOpDef = new ParsedOp(ot, NBConfiguration.empty(), List.of(), this);
|
||||
String driverName = incompleteOpDef.takeOptionalStaticValue("driver", String.class)
|
||||
.or(() -> incompleteOpDef.takeOptionalStaticValue("type",String.class))
|
||||
.or(() -> incompleteOpDef.takeOptionalStaticValue("type", String.class))
|
||||
.or(() -> defaultDriverOption)
|
||||
.orElseThrow(() -> new OpConfigError("Unable to identify driver name for op template:\n" + ot));
|
||||
|
||||
@@ -152,12 +152,14 @@ public class StandardActivity<R extends Op, S> extends SimpleActivity implements
|
||||
throw new OpConfigError("Error mapping workload template to operations: " + e.getMessage(), null, e);
|
||||
}
|
||||
|
||||
this.pendingOpsGauge= ActivityMetrics.gauge(this,"ops_pending",
|
||||
new NBFunctionGauge(this,() -> this.getProgressMeter().getSummary().pending()));
|
||||
this.activeOpsGauge = ActivityMetrics.gauge(this,"ops_active",
|
||||
new NBFunctionGauge(this,() -> this.getProgressMeter().getSummary().current()));
|
||||
this.completeOpsGauge= ActivityMetrics.gauge(this,"ops_complete",
|
||||
new NBFunctionGauge(this,() -> this.getProgressMeter().getSummary().complete()));
|
||||
this.pendingOpsGauge = ActivityMetrics.register(
|
||||
new NBFunctionGauge(this, () -> this.getProgressMeter().getSummary().pending(), "ops_pending")
|
||||
);
|
||||
this.activeOpsGauge = ActivityMetrics.register(
|
||||
new NBFunctionGauge(this, () -> this.getProgressMeter().getSummary().current(),"ops_active")
|
||||
);
|
||||
this.completeOpsGauge = ActivityMetrics.register(
|
||||
new NBFunctionGauge(this, () -> this.getProgressMeter().getSummary().complete(),"ops_complete"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,7 +219,7 @@ public class StandardActivity<R extends Op, S> extends SimpleActivity implements
|
||||
public void shutdownActivity() {
|
||||
for (Map.Entry<String, DriverAdapter> entry : adapters.entrySet()) {
|
||||
String adapterName = entry.getKey();
|
||||
DriverAdapter<?,?> adapter = entry.getValue();
|
||||
DriverAdapter<?, ?> adapter = entry.getValue();
|
||||
adapter.getSpaceCache().getElements().forEach((spaceName, space) -> {
|
||||
if (space instanceof AutoCloseable autocloseable) {
|
||||
try {
|
||||
|
||||
@@ -76,10 +76,10 @@ public class ActivityMetrics {
|
||||
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||
private static Metric register(NBLabels labels, MetricProvider metricProvider) {
|
||||
|
||||
labels = labelFilter!=null ? labelFilter.apply(labels) : labels;
|
||||
labels = labelFilter != null ? labelFilter.apply(labels) : labels;
|
||||
labels = labelValidator != null ? labelValidator.apply(labels) : labels;
|
||||
|
||||
final String graphiteName = labels.linearizeValues('.',"[activity]","[space]","[op]","name");
|
||||
final String graphiteName = labels.linearizeValues('.', "[activity]", "[space]", "[op]", "name");
|
||||
Metric metric = get().getMetrics().get(graphiteName);
|
||||
|
||||
if (null == metric) {
|
||||
@@ -96,6 +96,45 @@ public class ActivityMetrics {
|
||||
return metric;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls to this version of register must be done with a pre-built metric instrument.
|
||||
* This means that it is not suitable for lazily creating metric objects directly on
|
||||
* instances which are one of many. Instead, call this to register metrics at the start
|
||||
* of an owning element.
|
||||
*
|
||||
* This version of register expects that you have fully labeled a metric, including
|
||||
* addint the 'name' field, also known as the <em>metric family name</em> in some specifications.
|
||||
*
|
||||
* It is due to be replaced by a different registry format soon.
|
||||
*
|
||||
* @param labeledMetric
|
||||
* @return the metric instance
|
||||
*/
|
||||
public static <M extends NBLabeledMetric> M register(M labeledMetric) {
|
||||
NBLabels labels = labeledMetric.getLabels();
|
||||
labels = labelFilter != null ? labelFilter.apply(labels) : labels;
|
||||
labels = labelValidator != null ? labelValidator.apply(labels) : labels;
|
||||
|
||||
final String graphiteName = labels.linearizeValues('.', "[activity]", "[space]", "[op]", "name");
|
||||
Metric metric = get().getMetrics().get(graphiteName);
|
||||
|
||||
metric = get().getMetrics().get(graphiteName);
|
||||
if (metric!=null) {
|
||||
logger.warn("Metric already registered for '" + graphiteName + "', probably logic error which could invalidate metric values.");
|
||||
} else {
|
||||
get().register(graphiteName, labeledMetric);
|
||||
}
|
||||
return labeledMetric;
|
||||
}
|
||||
|
||||
public static void unregister(NBLabeledElement element) {
|
||||
final String graphiteName = element.getLabels().linearizeValues('.', "[activity]", "[space]", "[op]", "name");
|
||||
if (!get().getMetrics().containsKey(graphiteName)) {
|
||||
logger.warn("Removing non-extant metric by name: '"+ graphiteName + "'");
|
||||
}
|
||||
get().remove(graphiteName);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Create a timer associated with an activity.</p>
|
||||
*
|
||||
@@ -112,7 +151,7 @@ public class ActivityMetrics {
|
||||
* @return the timer, perhaps a different one if it has already been registered
|
||||
*/
|
||||
public static Timer timer(NBLabeledElement parent, String metricFamilyName, int hdrdigits) {
|
||||
final NBLabels labels = parent.getLabels().and("name",sanitize(metricFamilyName));
|
||||
final NBLabels labels = parent.getLabels().and("name", sanitize(metricFamilyName));
|
||||
|
||||
|
||||
Timer registeredTimer = (Timer) register(labels, () ->
|
||||
@@ -164,7 +203,7 @@ public class ActivityMetrics {
|
||||
* @return the counter, perhaps a different one if it has already been registered
|
||||
*/
|
||||
public static Counter counter(NBLabeledElement parent, String metricFamilyName) {
|
||||
final NBLabels labels = parent.getLabels().and("name",metricFamilyName);
|
||||
final NBLabels labels = parent.getLabels().and("name", metricFamilyName);
|
||||
return (Counter) register(labels, () -> new NBMetricCounter(labels));
|
||||
}
|
||||
|
||||
@@ -180,7 +219,7 @@ public class ActivityMetrics {
|
||||
* @return the meter, perhaps a different one if it has already been registered
|
||||
*/
|
||||
public static Meter meter(NBLabeledElement parent, String metricFamilyName) {
|
||||
final NBLabels labels = parent.getLabels().and("name",sanitize(metricFamilyName));
|
||||
final NBLabels labels = parent.getLabels().and("name", sanitize(metricFamilyName));
|
||||
return (Meter) register(labels, () -> new NBMetricMeter(labels));
|
||||
}
|
||||
|
||||
@@ -201,27 +240,30 @@ public class ActivityMetrics {
|
||||
* 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
|
||||
*
|
||||
* @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()){
|
||||
for (DoubleSummaryGauge.Stat statName : DoubleSummaryGauge.Stat.values()) {
|
||||
final NBLabels labels = parent.getLabels()
|
||||
.and("name",sanitize(metricFamilyName))
|
||||
.modifyValue("name", n -> n+"_"+statName.name().toLowerCase());
|
||||
anyGauge= (DoubleSummaryGauge) register(labels, () -> new DoubleSummaryGauge(labels,statName,stats));
|
||||
.and("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().and("name",sanitize(metricFamilyName));
|
||||
|
||||
return (Gauge<T>) register(labels, () -> new NBMetricGaugeWrapper<>(labels,gauge));
|
||||
final NBLabels labels = parent.getLabels().and("name", sanitize(metricFamilyName));
|
||||
return (Gauge<T>) register(labels, () -> new NBMetricGaugeWrapper<>(labels, gauge));
|
||||
}
|
||||
|
||||
private static MetricRegistry lookupRegistry() {
|
||||
@@ -375,10 +417,11 @@ public class ActivityMetrics {
|
||||
.forEach(get()::remove);
|
||||
}
|
||||
|
||||
|
||||
public static String sanitize(String word) {
|
||||
String sanitized = word;
|
||||
sanitized = sanitized.replaceAll("\\..+$", "");
|
||||
sanitized = sanitized.replaceAll("-","_");
|
||||
sanitized = sanitized.replaceAll("-", "_");
|
||||
sanitized = sanitized.replaceAll("[^a-zA-Z0-9_]+", "");
|
||||
|
||||
if (!word.equals(sanitized)) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package io.nosqlbench.api.engine.metrics.instruments;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class NBFunctionGauge implements NBMetricGauge<Double> {
|
||||
@@ -27,11 +28,14 @@ public class NBFunctionGauge implements NBMetricGauge<Double> {
|
||||
private final NBLabeledElement parent;
|
||||
private final NBLabels labels;
|
||||
|
||||
public NBFunctionGauge(NBLabeledElement parent, Supplier<Double> source, Object... labels) {
|
||||
public NBFunctionGauge(NBLabeledElement parent, Supplier<Double> source, String metricFamilyName, Map<String,String> additionalLabels) {
|
||||
this.parent = parent;
|
||||
this.labels = NBLabels.forKV(labels);
|
||||
this.labels = NBLabels.forMap(additionalLabels).and("name",metricFamilyName);
|
||||
this.source = source;
|
||||
}
|
||||
public NBFunctionGauge(NBLabeledElement parent, Supplier<Double> source, String metricFamilyName) {
|
||||
this(parent, source, metricFamilyName,Map.of());
|
||||
}
|
||||
@Override
|
||||
public Double getValue() {
|
||||
return source.get();
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.Metric;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
|
||||
public interface NBLabeledMetric extends Metric, NBLabeledElement {
|
||||
}
|
||||
@@ -17,10 +17,9 @@
|
||||
package io.nosqlbench.api.engine.metrics.instruments;
|
||||
|
||||
import com.codahale.metrics.Counter;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
|
||||
public class NBMetricCounter extends Counter implements NBLabeledElement {
|
||||
public class NBMetricCounter extends Counter implements NBLabeledMetric {
|
||||
|
||||
private final NBLabels labels;
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
package io.nosqlbench.api.engine.metrics.instruments;
|
||||
|
||||
import com.codahale.metrics.Gauge;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
|
||||
public interface NBMetricGauge<T> extends Gauge<T>, NBLabeledElement {
|
||||
public interface NBMetricGauge<T> extends Gauge<T>, NBLabeledMetric {
|
||||
|
||||
}
|
||||
|
||||
@@ -17,15 +17,14 @@
|
||||
package io.nosqlbench.api.engine.metrics.instruments;
|
||||
|
||||
import com.codahale.metrics.Histogram;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
import io.nosqlbench.api.engine.metrics.*;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
public class NBMetricHistogram extends Histogram implements DeltaSnapshotter, HdrDeltaHistogramAttachment, HistogramAttachment, NBLabeledElement {
|
||||
public class NBMetricHistogram extends Histogram implements DeltaSnapshotter, HdrDeltaHistogramAttachment, HistogramAttachment, NBLabeledMetric {
|
||||
|
||||
private final DeltaHdrHistogramReservoir hdrDeltaReservoir;
|
||||
private final NBLabels labels;
|
||||
|
||||
@@ -17,10 +17,9 @@
|
||||
package io.nosqlbench.api.engine.metrics.instruments;
|
||||
|
||||
import com.codahale.metrics.Meter;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
|
||||
public class NBMetricMeter extends Meter implements NBLabeledElement {
|
||||
public class NBMetricMeter extends Meter implements NBLabeledMetric {
|
||||
|
||||
private final NBLabels labels;
|
||||
|
||||
|
||||
@@ -17,16 +17,15 @@
|
||||
package io.nosqlbench.api.engine.metrics.instruments;
|
||||
|
||||
import com.codahale.metrics.Timer;
|
||||
import io.nosqlbench.api.labels.NBLabeledElement;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
import io.nosqlbench.api.engine.metrics.*;
|
||||
import io.nosqlbench.api.labels.NBLabels;
|
||||
import org.HdrHistogram.Histogram;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class NBMetricTimer extends Timer implements DeltaSnapshotter, HdrDeltaHistogramAttachment, TimerAttachment, NBLabeledElement {
|
||||
public class NBMetricTimer extends Timer implements DeltaSnapshotter, HdrDeltaHistogramAttachment, TimerAttachment, NBLabeledMetric {
|
||||
private final DeltaHdrHistogramReservoir deltaHdrHistogramReservoir;
|
||||
private long cacheExpiry;
|
||||
private List<Timer> mirrors;
|
||||
|
||||
Reference in New Issue
Block a user