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");
+// String sanitized = sanitize(graphiteName);
+// if (!graphiteName.equals(sanitized)) {
+// throw new RuntimeException("Attempted to register a metric which was not compatible with labeled metric forms. Submitted as '" + graphiteName + "', but should likely be '" + sanitized + "'");
+// }
+ 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);
+ }
+
/**
* Create a timer associated with an activity.
*
@@ -112,7 +156,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 +208,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 +224,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 +245,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 Gauge gauge(NBLabeledElement parent, String metricFamilyName, Gauge gauge) {
- final NBLabels labels = parent.getLabels().and("name",sanitize(metricFamilyName));
-
- return (Gauge) register(labels, () -> new NBMetricGaugeWrapper<>(labels,gauge));
+ final NBLabels labels = parent.getLabels().and("name", sanitize(metricFamilyName));
+ return (Gauge) register(labels, () -> new NBMetricGaugeWrapper<>(labels, gauge));
}
private static MetricRegistry lookupRegistry() {
@@ -375,10 +422,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("-", "_");
sanitized = sanitized.replaceAll("[^a-zA-Z0-9_]+", "");
if (!word.equals(sanitized)) {
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBFunctionGauge.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBFunctionGauge.java
index 72841e246..5f5913e68 100644
--- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBFunctionGauge.java
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBFunctionGauge.java
@@ -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 {
@@ -27,11 +28,14 @@ public class NBFunctionGauge implements NBMetricGauge {
private final NBLabeledElement parent;
private final NBLabels labels;
- public NBFunctionGauge(NBLabeledElement parent, Supplier source, Object... labels) {
+ public NBFunctionGauge(NBLabeledElement parent, Supplier source, String metricFamilyName, Map 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 source, String metricFamilyName) {
+ this(parent, source, metricFamilyName,Map.of());
+ }
@Override
public Double getValue() {
return source.get();
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBLabeledMetric.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBLabeledMetric.java
new file mode 100644
index 000000000..62c0caeb0
--- /dev/null
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBLabeledMetric.java
@@ -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 {
+}
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java
index 809e2207e..5e4013702 100644
--- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricCounter.java
@@ -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;
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java
index 1d3ebd51c..e9e018e0c 100644
--- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricGauge.java
@@ -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 extends Gauge, NBLabeledElement {
+public interface NBMetricGauge extends Gauge, NBLabeledMetric {
}
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java
index 2247a3c79..f495de6d9 100644
--- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricHistogram.java
@@ -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;
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java
index a374a889a..3a3afb47c 100644
--- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricMeter.java
@@ -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;
diff --git a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java
index 0802c0eb8..bbcd16fe2 100644
--- a/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java
+++ b/nb-api/src/main/java/io/nosqlbench/api/engine/metrics/instruments/NBMetricTimer.java
@@ -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 mirrors;