add docs to metrics construction

This commit is contained in:
Jonathan Shook 2023-12-20 17:16:40 -06:00
parent b62c623143
commit 274b5b119b
32 changed files with 698 additions and 140 deletions

View File

@ -20,6 +20,7 @@ import com.codahale.metrics.Counter;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Timer;
import io.nosqlbench.adapter.amqp.dispensers.AmqpBaseOpDispenser;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabeledElement;
import io.nosqlbench.nb.api.labels.NBLabels;
import org.apache.logging.log4j.LogManager;
@ -55,17 +56,45 @@ public class AmqpAdapterMetrics {
public void initS4JAdapterInstrumentation() {
// Histogram metrics
messageSizeHistogram = amqpBaseOpDispenser.create().histogram("message_size");
messageSizeHistogram = amqpBaseOpDispenser.create().histogram(
"amqp_message_size",
MetricCategory.Driver,
"AMQP message size"
);
// Timer metrics
bindTimer = amqpBaseOpDispenser.create().timer("bind");
executeTimer = amqpBaseOpDispenser.create().timer("execute");
bindTimer = amqpBaseOpDispenser.create().timer(
"amqp_bind",
MetricCategory.Driver,
"AMQP bind timer"
);
executeTimer = amqpBaseOpDispenser.create().timer(
"amqp_execute",
MetricCategory.Driver,
"AMQP execute timer"
);
// End-to-end metrics
// Latency
e2eMsgProcLatencyHistogram = amqpBaseOpDispenser.create().histogram("e2e_msg_latency");
e2eMsgProcLatencyHistogram = amqpBaseOpDispenser.create().histogram(
"amqp_e2e_msg_latency",
MetricCategory.Driver,
"AMQP end-to-end message processing latency"
);
// Error metrics
msgErrOutOfSeqCounter = amqpBaseOpDispenser.create().counter("err_msg_oos");
msgErrLossCounter = amqpBaseOpDispenser.create().counter("err_msg_loss");
msgErrDuplicateCounter = amqpBaseOpDispenser.create().counter("err_msg_dup");
msgErrOutOfSeqCounter = amqpBaseOpDispenser.create().counter(
"amqp_err_msg_oos",
MetricCategory.Driver,
"AMQP out-of-sequence error count"
);
msgErrLossCounter = amqpBaseOpDispenser.create().counter(
"amqp_err_msg_loss",
MetricCategory.Driver,
"AMQP lost message error count"
);
msgErrDuplicateCounter = amqpBaseOpDispenser.create().counter(
"err_msg_dup",
MetricCategory.Driver,
"AMQP duplicate message count"
);
}
public Timer getBindTimer() { return bindTimer; }

View File

@ -31,6 +31,7 @@ import io.nosqlbench.adapters.api.activityimpl.BaseOpDispenser;
import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.templating.ParsedOp;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -57,9 +58,24 @@ public abstract class Cqld4BaseOpDispenser extends BaseOpDispenser<Cqld4CqlOp, C
this.maxpages = op.getStaticConfigOr("maxpages", 1);
this.isRetryReplace = op.getStaticConfigOr("retryreplace", false);
this.maxLwtRetries = op.getStaticConfigOr("maxlwtretries", 1);
this.rowsHistogram = create().histogram("rows", op.getStaticConfigOr("hdr_digits", 3));
this.pagesHistogram = create().histogram("pages", op.getStaticConfigOr("hdr_digits", 3));
this.payloadBytesHistogram = create().histogram("payload_bytes", op.getStaticConfigOr("hdr_digits", 3));
this.rowsHistogram = create().histogram(
"rows",
op.getStaticConfigOr("hdr_digits", 3),
MetricCategory.Payload,
"The number of rows returned in the CQL result"
);
this.pagesHistogram = create().histogram(
"pages",
op.getStaticConfigOr("hdr_digits", 3),
MetricCategory.Payload,
"The number of pages returned in the CQL result"
);
this.payloadBytesHistogram = create().histogram(
"payload_bytes",
op.getStaticConfigOr("hdr_digits", 3),
MetricCategory.Payload,
"The number of bytes returned in the CQL result"
);
}
public int getMaxPages() {

View File

@ -21,6 +21,7 @@ import io.nosqlbench.nb.api.config.standard.ConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfigModel;
import io.nosqlbench.nb.api.config.standard.NBConfiguration;
import io.nosqlbench.nb.api.config.standard.Param;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.components.core.NBParentComponentInjection;
import io.nosqlbench.nb.annotations.Service;
@ -136,7 +137,12 @@ public class DiagTask_gauge extends BaseDiagTask implements Gauge<Double>, NBPar
}
logger.info("Registering gauge for diag task with labels:" + getParentLabels().getLabels() + " label:" + label);
this.gauge=parent.create().gauge(label,() -> this.sampleValue);
this.gauge=parent.create().gauge(
label,
() -> this.sampleValue,
MetricCategory.Verification,
"a diagnostic gauge for the purposes of testing " + description()
);
}
@Override

View File

@ -17,6 +17,7 @@
package io.nosqlbench.adapter.http.core;
import com.codahale.metrics.Histogram;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabeledElement;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.components.core.NBComponent;
@ -29,7 +30,12 @@ public class HttpMetrics implements NBLabeledElement {
public HttpMetrics(NBComponent parent, HttpSpace space) {
this.parent = parent;
this.space = space;
statusCodeHistogram = parent.create().histogram("statuscode",space.getHdrDigits());
statusCodeHistogram = parent.create().histogram(
"statuscode",
space.getHdrDigits(),
MetricCategory.Payload,
"A histogram of status codes received by the HTTP client"
);
}
public String getName() {

View File

@ -20,8 +20,10 @@ import com.codahale.metrics.Counter;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Timer;
import io.nosqlbench.adapter.kafka.dispensers.KafkaBaseOpDispenser;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabeledElement;
import io.nosqlbench.nb.api.labels.NBLabels;
import org.apache.kafka.common.Metric;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -50,37 +52,70 @@ public class KafkaAdapterMetrics {
public KafkaAdapterMetrics(final KafkaBaseOpDispenser kafkaBaseOpDispenser, final NBLabeledElement labeledParent) {
this.kafkaBaseOpDispenser = kafkaBaseOpDispenser;
labels=labeledParent.getLabels().and("name",KafkaAdapterMetrics.class.getSimpleName());
labels = labeledParent.getLabels().and("name", KafkaAdapterMetrics.class.getSimpleName());
}
public void initS4JAdapterInstrumentation() {
// Histogram metrics
messageSizeHistogram = kafkaBaseOpDispenser.create().histogram("message_size");
messageSizeHistogram = kafkaBaseOpDispenser.create().histogram(
"kafka_message_size",
MetricCategory.Payload,
"kafka message size"
);
// Timer metrics
bindTimer =
this.kafkaBaseOpDispenser.create().timer(
"bind");
"kafka_bind",
MetricCategory.Payload,
"kafka bind timer");
executeTimer =
this.kafkaBaseOpDispenser.create().timer(
"execute");
"kafka_execute",
MetricCategory.Payload,
"kafka execute timer"
);
// End-to-end metrics
// Latency
e2eMsgProcLatencyHistogram =
kafkaBaseOpDispenser.create().histogram("e2e_msg_latency");
kafkaBaseOpDispenser.create().histogram(
"e2e_msg_latency",
MetricCategory.Driver,
"End-to-end kafka message latency"
);
// Error metrics
msgErrOutOfSeqCounter =
kafkaBaseOpDispenser.create().counter("err_msg_oos");
kafkaBaseOpDispenser.create().counter(
"kafka_err_msg_oos",
MetricCategory.Driver,
"kafka Out-of-sequence errors"
);
msgErrLossCounter =
kafkaBaseOpDispenser.create().counter("err_msg_loss");
kafkaBaseOpDispenser.create().counter(
"kafka_err_msg_loss",
MetricCategory.Driver,
"kafka message loss errors"
);
msgErrDuplicateCounter =
kafkaBaseOpDispenser.create().counter( "err_msg_dup");
kafkaBaseOpDispenser.create().counter(
"kafka_err_msg_dup",
MetricCategory.Driver,
"kafka duplicate message errors"
);
}
public Timer getBindTimer() { return bindTimer; }
public Timer getExecuteTimer() { return executeTimer; }
public Histogram getMessagesizeHistogram() { return messageSizeHistogram; }
public Timer getBindTimer() {
return bindTimer;
}
public Timer getExecuteTimer() {
return executeTimer;
}
public Histogram getMessagesizeHistogram() {
return messageSizeHistogram;
}
public Counter getMsgErrOutOfSeqCounter() {
return msgErrOutOfSeqCounter;

View File

@ -20,6 +20,7 @@ import com.codahale.metrics.Counter;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Timer;
import io.nosqlbench.adapter.pulsar.dispensers.PulsarBaseOpDispenser;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.pulsar.client.api.Consumer;
@ -66,22 +67,52 @@ public class PulsarAdapterMetrics {
public void initPulsarAdapterInstrumentation() {
// Counter metrics
msgErrOutOfSeqCounter =
pulsarBaseOpDispenser.create().counter("err_msg_oos");
pulsarBaseOpDispenser.create().counter("pulsar_err_msg_oos",
MetricCategory.Driver,
"pulsar out-of-sequence error counter"
);
msgErrLossCounter =
pulsarBaseOpDispenser.create().counter("err_msg_loss");
pulsarBaseOpDispenser.create().counter("pulsar_err_msg_loss",
MetricCategory.Driver,
"pulsar lost message error counter"
);
msgErrDuplicateCounter =
pulsarBaseOpDispenser.create().counter("err_msg_dup");
pulsarBaseOpDispenser.create().counter("pulsar_err_msg_dup",
MetricCategory.Driver,
"pulsar duplicate message error counter"
);
// Histogram metrics
messageSizeHistogram = pulsarBaseOpDispenser.create().histogram("message_size");
e2eMsgProcLatencyHistogram = pulsarBaseOpDispenser.create().histogram("e2e_msg_latency");
payloadRttHistogram = pulsarBaseOpDispenser.create().histogram("payload_rtt");
messageSizeHistogram = pulsarBaseOpDispenser.create().histogram("pulsar_message_size",
MetricCategory.Driver,
"pulsar message size"
);
e2eMsgProcLatencyHistogram = pulsarBaseOpDispenser.create().histogram("pulsar_e2e_msg_latency",
MetricCategory.Driver,
"pulsar end-to-end message latency"
);
payloadRttHistogram = pulsarBaseOpDispenser.create().histogram("pulsar_payload_rtt",
MetricCategory.Driver,
"pulsar payload round-trip-time"
);
// Timer metrics
bindTimer = pulsarBaseOpDispenser.create().timer("bind");
executeTimer = pulsarBaseOpDispenser.create().timer("execute");
createTransactionTimer = pulsarBaseOpDispenser.create().timer("create_transaction");
commitTransactionTimer = pulsarBaseOpDispenser.create().timer("commit_transaction");
bindTimer = pulsarBaseOpDispenser.create().timer("pulsar_bind",
MetricCategory.Driver,
"pulsar bind timer"
);
executeTimer = pulsarBaseOpDispenser.create().timer("pulsar_execute",
MetricCategory.Driver,
"pulsar execution timer"
);
createTransactionTimer = pulsarBaseOpDispenser.create().timer("pulsar_create_transaction",
MetricCategory.Driver,
"pulsar create transaction timer"
);
commitTransactionTimer = pulsarBaseOpDispenser.create().timer("pulsar_commit_transaction",
MetricCategory.Driver,
"pulsar commit transaction timer"
);
}
public Counter getMsgErrOutOfSeqCounter() {
@ -154,12 +185,36 @@ public class PulsarAdapterMetrics {
public void registerProducerApiMetrics(final Producer<?> producer) {
pulsarBaseOpDispenser.create().gauge("total_bytes_sent", PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalBytesSent() + s.getNumBytesSent()));
pulsarBaseOpDispenser.create().gauge("total_msg_sent", PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalMsgsSent() + s.getNumMsgsSent()));
pulsarBaseOpDispenser.create().gauge("total_send_failed", PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalSendFailed() + s.getNumSendFailed()));
pulsarBaseOpDispenser.create().gauge("total_ack_received", PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalAcksReceived() + s.getNumAcksReceived()));
pulsarBaseOpDispenser.create().gauge("send_bytes_rate", PulsarAdapterMetrics.producerSafeExtractMetric(producer, ProducerStats::getSendBytesRate));
pulsarBaseOpDispenser.create().gauge("send_msg_rate", PulsarAdapterMetrics.producerSafeExtractMetric(producer, ProducerStats::getSendMsgsRate));
pulsarBaseOpDispenser.create().gauge(
"pulsar_total_bytes_sent",
PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalBytesSent() + s.getNumBytesSent()),
MetricCategory.Driver,
"pulsar total bytes sent"
);
pulsarBaseOpDispenser.create().gauge(
"pulsar_total_msg_sent",
PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalMsgsSent() + s.getNumMsgsSent()),
MetricCategory.Driver,
"pulsar total message sent"
);
pulsarBaseOpDispenser.create().gauge(
"pulsar_total_send_failed",
PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalSendFailed() + s.getNumSendFailed()),
MetricCategory.Driver,
"pulsar message send failures"
);
pulsarBaseOpDispenser.create().gauge("pulsar_total_ack_received", PulsarAdapterMetrics.producerSafeExtractMetric(producer, s -> (double) s.getTotalAcksReceived() + s.getNumAcksReceived()),
MetricCategory.Driver,
"pulsar total acknowledgements received"
);
pulsarBaseOpDispenser.create().gauge("pulsar_send_bytes_rate", PulsarAdapterMetrics.producerSafeExtractMetric(producer, ProducerStats::getSendBytesRate),
MetricCategory.Driver,
"pulsar rate of bytes sent"
);
pulsarBaseOpDispenser.create().gauge("pulsar_send_msg_rate", PulsarAdapterMetrics.producerSafeExtractMetric(producer, ProducerStats::getSendMsgsRate),
MetricCategory.Driver,
"pulsar rate of messages sent"
);
}
@ -193,17 +248,38 @@ public class PulsarAdapterMetrics {
public void registerConsumerApiMetrics(final Consumer<?> consumer, final String pulsarApiMetricsPrefix) {
pulsarBaseOpDispenser.create().gauge("total_bytes_recv",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalBytesReceived() + s.getNumBytesReceived()));
pulsarBaseOpDispenser.create().gauge("total_msg_recv",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalMsgsReceived() + s.getNumMsgsReceived()));
pulsarBaseOpDispenser.create().gauge("total_recv_failed",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalReceivedFailed() + s.getNumReceiveFailed()));
pulsarBaseOpDispenser.create().gauge("total_acks_sent",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalAcksSent() + s.getNumAcksSent()));
pulsarBaseOpDispenser.create().gauge("recv_bytes_rate",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getRateBytesReceived()));
pulsarBaseOpDispenser.create().gauge("recv_msg_rate",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getRateMsgsReceived()));
pulsarBaseOpDispenser.create().gauge(
"pulsar_total_bytes_recv",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalBytesReceived() + s.getNumBytesReceived()),
MetricCategory.Driver,
"pulsar total bytes received"
);
pulsarBaseOpDispenser.create().gauge(
"pulsar_total_msg_recv",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalMsgsReceived() + s.getNumMsgsReceived()),
MetricCategory.Driver,
"pulsar total messages received"
);
pulsarBaseOpDispenser.create().gauge(
"pulsar_total_recv_failed",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalReceivedFailed() + s.getNumReceiveFailed()),
MetricCategory.Driver,
"pulsar total receive failures"
);
pulsarBaseOpDispenser.create().gauge("pulsar_total_acks_sent",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getTotalAcksSent() + s.getNumAcksSent()),
MetricCategory.Driver,
"pulsar total acknowledgements sent"
);
pulsarBaseOpDispenser.create().gauge("pulsar_recv_bytes_rate",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getRateBytesReceived()),
MetricCategory.Driver,
"pulsar rate of bytes received"
);
pulsarBaseOpDispenser.create().gauge("pulsar_recv_msg_rate",
PulsarAdapterMetrics.consumerSafeExtractMetric(consumer, s -> (double) s.getRateMsgsReceived()),
MetricCategory.Driver,
"pulsar rate of message received"
);
}
}

View File

@ -19,6 +19,7 @@ package io.nosqlbench.adapter.s4j.util;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Timer;
import io.nosqlbench.adapter.s4j.dispensers.S4JBaseOpDispenser;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -38,11 +39,23 @@ public class S4JAdapterMetrics {
public void initS4JAdapterInstrumentation() {
// Histogram metrics
this.messageSizeHistogram = s4jBaseOpDispenser.create().histogram("message_size");
this.messageSizeHistogram = s4jBaseOpDispenser.create().histogram(
"s4j_message_size",
MetricCategory.Driver,
"S4J message size"
);
// Timer metrics
this.bindTimer = s4jBaseOpDispenser.create().timer("bind");
this.executeTimer = s4jBaseOpDispenser.create().timer("execute");
this.bindTimer = s4jBaseOpDispenser.create().timer(
"s4j_bind",
MetricCategory.Driver,
"S4J bind timer"
);
this.executeTimer = s4jBaseOpDispenser.create().timer(
"s4j_execute",
MetricCategory.Driver,
"S4j execut timer"
);
}
public Timer getBindTimer() { return bindTimer; }

View File

@ -23,6 +23,7 @@ import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.adapters.api.evalctx.*;
import io.nosqlbench.adapters.api.metrics.ThreadLocalNamedTimers;
import io.nosqlbench.adapters.api.templating.ParsedOp;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.errors.OpConfigError;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
@ -99,7 +100,12 @@ public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent i
verifiers = configureVerifiers(op);
this._verifier = CycleFunctions.of((a, b) -> a && b, verifiers, true);
this.tlVerifier = ThreadLocal.withInitial(_verifier::newInstance);
this.verifierTimer = create().timer("verifier",3);
this.verifierTimer = create().timer(
"verifier",
3,
MetricCategory.Verification,
"Time verifier execution, if any."
);
}
private CycleFunction<Boolean> cloneVerifiers() {
@ -179,8 +185,18 @@ public abstract class BaseOpDispenser<T extends Op, S> extends NBBaseComponent i
if (this.instrument) {
final int hdrDigits = pop.getStaticConfigOr("hdr_digits", 4);
successTimer = create().timer("successfor_"+getOpName(),hdrDigits);
errorTimer = create().timer("errorsfor_"+getOpName(),hdrDigits);
successTimer = create().timer(
"successfor_"+getOpName(),
hdrDigits,
MetricCategory.Core,
"Successful result timer for specific operation '" + pop.getName() + "'"
);
errorTimer = create().timer(
"errorsfor_"+getOpName(),
hdrDigits,
MetricCategory.Core,
"Errored result timer for specific operation '" + pop.getName() + "'"
);
}
}

View File

@ -19,6 +19,7 @@ package io.nosqlbench.adapters.api.metrics;
import com.codahale.metrics.Timer;
import com.codahale.metrics.Timer.Context;
import io.nosqlbench.adapters.api.templating.ParsedOp;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricTimer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -41,7 +42,12 @@ public class ThreadLocalNamedTimers {
public static void addTimer(final ParsedOp pop, final String name) {
if (ThreadLocalNamedTimers.timers.containsKey("name"))
ThreadLocalNamedTimers.logger.warn("A timer named '{}' was already defined and initialized.", name);
NBMetricTimer timer = pop.create().timer(name, 3);
NBMetricTimer timer = pop.create().timer(
name,
3,
MetricCategory.User,
"User-provided metric, defined on op '" + pop.getName() + "'"
);
ThreadLocalNamedTimers.timers.put(name, timer);
}

View File

@ -77,8 +77,6 @@ public interface ActivityInstrumentation {
*/
Counter getOrCreatePendingOpCounter();
Counter getOrCreateOpTrackerBlockedCounter();
/**
* The bind timer keeps track of how long it takes for NoSQLBench to create an instance
* of an executable operation, given the cycle. This is usually done by using an

View File

@ -21,6 +21,7 @@ import com.codahale.metrics.Histogram;
import com.codahale.metrics.Timer;
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
import io.nosqlbench.nb.api.engine.activityimpl.ParameterMap;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricCounter;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricHistogram;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricTimer;
@ -57,33 +58,90 @@ public class ComponentActivityInstrumentation implements ActivityInstrumentation
}
private void initMetrics() {
readInputTimer=activity.create().timer("read_input",this.hdrdigits);
stridesServiceTimer=activity.create().timer("strides",this.hdrdigits);
readInputTimer=activity.create().timer(
"read_input",
this.hdrdigits,
MetricCategory.Internals,
"measures overhead of acquiring a cycle range for an activity thread"
);
stridesServiceTimer=activity.create().timer(
"strides",
this.hdrdigits,
MetricCategory.Core,
"service timer for a stride, which is the same as the op sequence length by default"
);
if (null != activity.getStrideLimiter()) {
this.stridesResponseTimer = activity.create().timer(
"strides" + ComponentActivityInstrumentation.RESPONSE_TIME,
hdrdigits
hdrdigits,
MetricCategory.Core,
"response timer for a stride, which is the same as the op sequence length by default;" +
" response timers include scheduling delays which occur when an activity falls behind its target rate"
);
}
this.cyclesServiceTimer = activity.create().timer(
"cycles"+ComponentActivityInstrumentation.SERVICE_TIME,
hdrdigits
hdrdigits,
MetricCategory.Core,
"service timer for a cycle, including all of bind, execute, result and result_success;" +
" service timers measure the time between submitting a request and receiving the response"
);
if (null != activity.getCycleLimiter()) {
this.cyclesResponseTimer = activity.create().timer(
"cycles" + ComponentActivityInstrumentation.RESPONSE_TIME,
hdrdigits
hdrdigits,
MetricCategory.Core,
"response timer for a cycle, including all of bind, execut, result and result_success;" +
" response timers include scheduling delays which occur when an activity falls behind its target rate"
);
}
this.pendingOpsCounter=activity.create().counter("pending_ops");
this.opTrackerBlockedCounter=activity.create().counter("optracker_blocked");
this.pendingOpsCounter=activity.create().counter(
"pending_ops",
MetricCategory.Core,
"Indicate the number of operations which have been started, but which have not been completed." +
" This starts "
);
this.bindTimer = activity.create().timer("bind",hdrdigits);
this.executeTimer = activity.create().timer("execute",hdrdigits);
this.resultTimer = activity.create().timer("result",hdrdigits);
this.resultSuccessTimer = activity.create().timer("result_success",hdrdigits);
this.triesHistogram = activity.create().histogram("tries",hdrdigits);
this.verifierTimer = activity.create().timer("verifier",hdrdigits);
this.bindTimer = activity.create().timer(
"bind",
hdrdigits,
MetricCategory.Core,
"Time the step within a cycle which binds generated data to an op template to synthesize an executable operation."
);
this.executeTimer = activity.create().timer(
"execute",
hdrdigits,
MetricCategory.Core,
"Time how long it takes to submit a request and receive a result, including reading the result in the client."
);
this.resultTimer = activity.create().timer(
"result",
hdrdigits,
MetricCategory.Core,
"Time how long it takes to submit a request, receive a result, including binding, reading results, " +
"and optionally verifying them, including all operations whether successful or not, for each attempted request."
);
this.resultSuccessTimer = activity.create().timer(
"result_success",
hdrdigits,
MetricCategory.Core,
"The execution time of successful operations, which includes submitting the operation, waiting for a response, and reading the result"
);
this.triesHistogram = activity.create().histogram(
"tries",
hdrdigits,
MetricCategory.Core,
"A histogram of all tries for an activity. Perfect results mean all quantiles return 1." +
" Slight saturation is indicated by p99 or p95 returning higher values." +
" Lower quantiles returning more than 1, or higher values at high quantiles indicate incremental overload."
);
this.verifierTimer = activity.create().timer(
"verifier",
hdrdigits,
MetricCategory.Verification,
"Time the execution of verifier code, if any"
);
}

View File

@ -16,6 +16,7 @@
package io.nosqlbench.engine.api.activityapi.ratelimits.simrate;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.core.NBComponent;
@ -86,9 +87,25 @@ public class SimRate extends NBBaseComponent implements RateLimiter, Thread.Unca
}
private void initMetrics() {
create().gauge("cycles_waittime",() -> (double)getWaitTimeDuration().get(ChronoUnit.NANOS));
create().gauge("config_cyclerate", () -> spec.opsPerSec);
create().gauge("config_burstrate", () -> spec.burstRatio);
create().gauge(
"cycles_waittime",
() -> (double)getWaitTimeDuration().get(ChronoUnit.NANOS),
MetricCategory.Core,
"The cumulative scheduling delay which accrues when" +
" an activity is not able to execute operations as fast as requested."
);
create().gauge(
"config_cyclerate",
() -> spec.opsPerSec,
MetricCategory.Config,
"The configured cycle rate in ops/s"
);
create().gauge(
"config_burstrate",
() -> spec.burstRatio,
MetricCategory.Config,
"the configured burst rate as a multiplier to the configured cycle rate. ex: 1.05 means 5% faster is allowed."
);
}
public long refill() {

View File

@ -23,6 +23,7 @@ import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.engine.api.activityapi.core.ActivityDefObserver;
import io.nosqlbench.engine.api.activityapi.cyclelog.buffers.results.CycleSegment;
import io.nosqlbench.engine.api.activityapi.input.Input;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -60,14 +61,54 @@ public class AtomicInput extends NBBaseComponent implements Input, ActivityDefOb
super(parent);
this.activityDef = activityDef;
onActivityDefUpdate(activityDef);
create().gauge("input_cycles_first",() -> (double) this.cycles_min.get());
create().gauge("input_cycles_last",() -> (double) this.cycles_max.get());
create().gauge("input_cycle",() -> (double) this.cycle_value.get());
create().gauge("input_cycles_total",this::getTotalCycles);
create().gauge("input_recycles_first",() -> (double) this.recycles_min.get());
create().gauge("input_recycles_last",() -> (double) this.recycles_max.get());
create().gauge("input_recycle",() -> (double) this.recycle_value.get());
create().gauge("input_recycles_total",this::getTotalRecycles);
create().gauge(
"input_cycles_first",
() -> (double) this.cycles_min.get(),
MetricCategory.Config,
"The first cycle of the cycle interval, inclusive"
);
create().gauge(
"input_cycles_last",
() -> (double) this.cycles_max.get(),
MetricCategory.Config,
"The last cycle of the cycle interval, exclusive"
);
create().gauge(
"input_cycle",
() -> (double) this.cycle_value.get(),
MetricCategory.Core,
"The next input cycle that will be dispatched to a thread"
);
create().gauge(
"input_cycles_total",
this::getTotalCycles,
MetricCategory.Config,
"The total number of cycles to be executed"
);
create().gauge(
"input_recycles_first",
() -> (double) this.recycles_min.get(),
MetricCategory.Config,
"The first recycle value, inclusive"
);
create().gauge(
"input_recycles_last",
() -> (double) this.recycles_max.get(),
MetricCategory.Config,
"The last recycle value, exclusive"
);
create().gauge(
"input_recycle",
() -> (double) this.recycle_value.get(),
MetricCategory.Core,
"The next recycle value that will be dispatched once cycles are completed"
);
create().gauge(
"input_recycles_total",
this::getTotalRecycles,
MetricCategory.Config,
"The total number of recycles to be executed, within which each set of cycles will be executed"
);
}
private double getTotalRecycles() {

View File

@ -26,6 +26,7 @@ import io.nosqlbench.adapters.api.activityimpl.uniform.DriverAdapter;
import io.nosqlbench.adapters.api.activityimpl.uniform.decorators.SyntheticOpTemplateProvider;
import io.nosqlbench.adapters.api.activityimpl.uniform.flowtypes.Op;
import io.nosqlbench.adapters.api.templating.ParsedOp;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.lifecycle.Shutdownable;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.config.standard.*;
@ -155,11 +156,23 @@ public class StandardActivity<R extends Op, S> extends SimpleActivity implements
}
create().gauge(
"ops_pending", () -> this.getProgressMeter().getSummary().pending());
"ops_pending",
() -> this.getProgressMeter().getSummary().pending(),
MetricCategory.Core,
"The current number of operations which have not been dispatched for processing yet."
);
create().gauge(
"ops_active", () -> this.getProgressMeter().getSummary().current());
"ops_active",
() -> this.getProgressMeter().getSummary().current(),
MetricCategory.Core,
"The current number of operations which have been dispatched for processing, but which have not yet completed."
);
create().gauge(
"ops_complete", () -> this.getProgressMeter().getSummary().complete());
"ops_complete",
() -> this.getProgressMeter().getSummary().complete(),
MetricCategory.Core,
"The current number of operations which have been completed"
);
}
@Override

View File

@ -18,6 +18,7 @@ package io.nosqlbench.engine.api.metrics;
import com.codahale.metrics.Counter;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +34,11 @@ public class ExceptionCountMetrics {
public ExceptionCountMetrics(final NBComponent parent) {
this.parent = parent;
this.allerrors=parent.create().counter( "errors_ALL");
this.allerrors=parent.create().counter(
"errors_ALL",
MetricCategory.Errors,
"all errors, regardless of type type, for " + parent.description()
);
}
public void count(final String name) {
@ -41,7 +46,11 @@ public class ExceptionCountMetrics {
if (null == c) synchronized (this.counters) {
c = this.counters.computeIfAbsent(
name,
k -> parent.create().counter("errors_" + name)
k -> parent.create().counter(
"errors_" + name,
MetricCategory.Errors,
name + " errors for " + parent.description()
)
);
}
c.inc();

View File

@ -18,6 +18,7 @@ package io.nosqlbench.engine.api.metrics;
import com.codahale.metrics.Counter;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
/**
@ -30,8 +31,16 @@ public class ExceptionExpectedResultVerificationMetrics {
public ExceptionExpectedResultVerificationMetrics(final NBComponent parent) {
this.parent = parent;
this.verificationRetries=parent.create().counter("verificationcounts_RETRIES");
this.verificationErrors=parent.create().counter( "verificationcounts_ERRORS");
this.verificationRetries=parent.create().counter(
"verificationcounts_RETRIES",
MetricCategory.Verification,
"The number of retries used by the optional verifier logic for a given operation"
);
this.verificationErrors=parent.create().counter(
"verificationcounts_ERRORS",
MetricCategory.Verification,
"The number of errors encountered while attempting to verify the result of an soperation"
);
}
public void countVerificationRetries() {

View File

@ -19,6 +19,7 @@ package io.nosqlbench.engine.api.metrics;
import com.codahale.metrics.Histogram;
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import java.util.ArrayList;
import java.util.List;
@ -38,7 +39,12 @@ public class ExceptionHistoMetrics {
public ExceptionHistoMetrics(final NBComponent parent, final ActivityDef activityDef) {
this.parent = parent;
this.activityDef = activityDef;
this.allerrors = parent.create().histogram( "errorhistos_ALL", activityDef.getParams().getOptionalInteger("hdr_digits").orElse(4));
this.allerrors = parent.create().histogram(
"errorhistos_ALL",
activityDef.getParams().getOptionalInteger("hdr_digits").orElse(4),
MetricCategory.Errors,
"A histogram for all exceptions"
);
}
public void update(final String name, final long magnitude) {
@ -46,7 +52,12 @@ public class ExceptionHistoMetrics {
if (null == h) synchronized (this.histos) {
h = this.histos.computeIfAbsent(
name,
errName -> parent.create().histogram( "errorhistos_"+errName, this.activityDef.getParams().getOptionalInteger("hdr_digits").orElse(4))
errName -> parent.create().histogram(
"errorhistos_"+errName,
this.activityDef.getParams().getOptionalInteger("hdr_digits").orElse(4),
MetricCategory.Errors,
"error histogram for exception '" + errName + "'"
)
);
}
h.update(magnitude);

View File

@ -18,6 +18,7 @@ package io.nosqlbench.engine.api.metrics;
import com.codahale.metrics.Meter;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import java.util.ArrayList;
import java.util.List;
@ -33,7 +34,9 @@ public class ExceptionMeterMetrics {
public ExceptionMeterMetrics(final NBComponent parent) {
this.parent = parent;
this.allerrors = parent.create().meter("errormeters_ALL");
this.allerrors = parent.create().meter("errormeters_ALL", MetricCategory.Errors,
"all errors, regardless of type type, for the parent " + parent.description()
);
}
public void mark(final String name) {
@ -41,7 +44,11 @@ public class ExceptionMeterMetrics {
if (null == c) synchronized (this.meters) {
c = this.meters.computeIfAbsent(
name,
k -> parent.create().meter("errormeters_" + name)
k -> parent.create().meter(
"errormeters_" + name,
MetricCategory.Errors,
name + " errors for " + parent.description()
)
);
}
c.mark();

View File

@ -19,6 +19,7 @@ package io.nosqlbench.engine.api.metrics;
import com.codahale.metrics.Timer;
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import java.util.ArrayList;
import java.util.List;
@ -38,14 +39,24 @@ public class ExceptionTimerMetrics {
this.activityDef = activityDef;
this.parentLabels = parent;
this.allerrors=parent.create().timer("errortimers_ALL",4);
this.allerrors=parent.create().timer(
"errortimers_ALL",
4,
MetricCategory.Errors,
"exception timers for all error types"
);
}
public void update(final String name, final long nanosDuration) {
Timer timer = this.timers.get(name);
if (null == timer) synchronized (this.timers) {
timer = this.timers.computeIfAbsent(
name, k -> parentLabels.create().timer("errortimers_" + name, 3)
name, k -> parentLabels.create().timer(
"errortimers_" + name,
3,
MetricCategory.Errors,
"exception timers for specific error '" + name + "'"
)
);
}
timer.update(nanosDuration, TimeUnit.NANOSECONDS);

View File

@ -16,6 +16,7 @@
package io.nosqlbench.engine.core.lifecycle.activity;
import com.codahale.metrics.Gauge;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricGauge;
import io.nosqlbench.nb.api.labels.NBLabeledElement;
import io.nosqlbench.nb.api.labels.NBLabels;
@ -463,7 +464,12 @@ public class ActivityExecutor implements NBLabeledElement, ParameterMap.Listener
// }
private void registerMetrics() {
this.activity.create().gauge("threads",() -> (double) this.motors.size());
this.activity.create().gauge(
"threads",
() -> (double) this.motors.size(),
MetricCategory.Core,
"The current number of threads in activity " + this.description()
);
}

View File

@ -17,6 +17,7 @@
package io.nosqlbench.engine.core.lifecycle.session;
import io.nosqlbench.nb.api.engine.activityimpl.ActivityDef;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBFunctionGauge;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricGauge;
import io.nosqlbench.nb.api.labels.NBLabeledElement;

View File

@ -16,6 +16,7 @@
package io.nosqlbench.nb.api.components.core;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.tagging.TagFilter;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
@ -28,7 +29,7 @@ public class NBBaseComponentMetrics implements NBComponentMetrics {
private final Lock lock = new ReentrantLock(false);
private final Map<String, NBMetric> metrics = new ConcurrentHashMap<>();
@Override
public String addComponentMetric(NBMetric metric) {
public String addComponentMetric(NBMetric metric, MetricCategory category, String requiredDescription) {
try {
lock.lock();
String openMetricsName = metric.getLabels().linearizeAsMetrics();

View File

@ -16,6 +16,7 @@
package io.nosqlbench.nb.api.components.core;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
import java.util.Collection;
@ -29,7 +30,7 @@ import java.util.List;
*
*/
public interface NBComponentMetrics {
String addComponentMetric(NBMetric metric);
String addComponentMetric(NBMetric metric, MetricCategory category, String requiredDescription);
/**
* If you have the serialized open metrics name of a metric, you can ask for it

View File

@ -53,63 +53,64 @@ public class NBCreators {
this.base = base;
}
public NBMetricTimer timer(String metricFamilyName) {
return timer(metricFamilyName,3);
public NBMetricTimer timer(String metricFamilyName, MetricCategory category, String description) {
return timer(metricFamilyName,3, category,description);
}
public NBMetricTimer timer(String metricFamilyName, int hdrdigits) {
public NBMetricTimer timer(String metricFamilyName, int hdrdigits, MetricCategory category, String description) {
NBLabels labels = base.getLabels().and("name", metricFamilyName);
NBMetricTimer timer = new NBMetricTimer(labels, new DeltaHdrHistogramReservoir(labels, hdrdigits));
base.addComponentMetric(timer);
base.addComponentMetric(timer, category, description);
return timer;
}
public Meter meter(String metricFamilyName) {
public Meter meter(String metricFamilyName, MetricCategory category, String requiredDescription) {
NBLabels labels = base.getLabels().and("name", metricFamilyName);
NBMetricMeter meter = new NBMetricMeter(labels);
base.addComponentMetric(meter);
base.addComponentMetric(meter, category, requiredDescription);
return meter;
}
public NBMetricCounter counter(String metricFamilyName) {
public NBMetricCounter counter(String metricFamilyName, MetricCategory category, String requiredDescription) {
NBLabels labels = base.getLabels().and("name", metricFamilyName);
NBMetricCounter counter = new NBMetricCounter(labels);
base.addComponentMetric(counter);
base.addComponentMetric(counter, category, requiredDescription);
return counter;
}
public NBFunctionGauge gauge(String metricFamilyName, Supplier<Double> valueSource) {
public NBFunctionGauge gauge(String metricFamilyName, Supplier<Double> valueSource, MetricCategory category, String requiredDescription) {
NBFunctionGauge gauge = new NBFunctionGauge(base, valueSource, metricFamilyName);
base.addComponentMetric(gauge);
base.addComponentMetric(gauge, category, requiredDescription);
return gauge;
}
public NBVariableGauge variableGauge(String metricFamilyName, double initialValue, String... additionalLabels) {
public NBVariableGauge variableGauge(String metricFamilyName, double initialValue, MetricCategory category, String requiredDescription, String... additionalLabels) {
NBVariableGauge gauge = new NBVariableGauge(base, metricFamilyName, initialValue, additionalLabels);
base.addComponentMetric(gauge);
base.addComponentMetric(gauge, category, requiredDescription);
return gauge;
}
public DoubleSummaryGauge summaryGauge(String name, String... statspecs) {
List<DoubleSummaryGauge.Stat> stats = Arrays.stream(statspecs).map(DoubleSummaryGauge.Stat::valueOf).toList();
public DoubleSummaryGauge summaryGauge(String name, List<String> statspecs, MetricCategory category, String requiredDescription) {
List<DoubleSummaryGauge.Stat> stats = statspecs.stream().map(DoubleSummaryGauge.Stat::valueOf).toList();
DoubleSummaryStatistics reservoir = new DoubleSummaryStatistics();
DoubleSummaryGauge anyGauge = null;
for (DoubleSummaryGauge.Stat stat : stats) {
anyGauge = new DoubleSummaryGauge(base.getLabels().and(NBLabels.forKV("name",name,"stat", stat)), stat, reservoir);
base.addComponentMetric(anyGauge);
base.addComponentMetric(anyGauge, category, requiredDescription);
}
return anyGauge;
}
public NBMetricHistogram histogram(String metricFamilyName) {
return histogram(metricFamilyName,4);
public NBMetricHistogram histogram(String metricFamilyName, MetricCategory category, String requiredDescription) {
return histogram(metricFamilyName,4, category, requiredDescription);
}
public NBMetricHistogram histogram(String metricFamilyName, int hdrdigits) {
public NBMetricHistogram histogram(String metricFamilyName, int hdrdigits, MetricCategory category, String requiredDescription) {
NBLabels labels = base.getLabels().and("name", metricFamilyName);
NBMetricHistogram histogram = new NBMetricHistogram(labels, new DeltaHdrHistogramReservoir(labels, hdrdigits));
base.addComponentMetric(histogram);
base.addComponentMetric(histogram, category, requiredDescription);
return histogram;
}

View File

@ -0,0 +1,78 @@
/*
* 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.nb.api.engine.metrics.instruments;
public enum MetricCategory {
/**
* Metrics which are essential to understanding the behavior of any activity
*/
Core,
/**
* Metrics which mirror configuration data, either static or dynamic during the lifetime
* of an activity, session, or container. These are shared because they may need to be known
* for further understanding or evaluation. For example, the target rate puts the achieved
* rate in context, and having them both together in downstream metrics view makes computation
* simple and direct.
*/
Config,
/**
* Metrics which are used to ascertain the validity of client behavior, such as the CPU load
* or other potentially contending effects. This is important because test results can be invalidated
* when the composed system <PRE>{@code client <-> infrastructure <-> target system }</PRE> relies
* too heavily on the testing apparatus. When the testing apparatus is under any degree of measurable
* stress, the ability to drive the target system to its capacity is compromised, as well as the client's
* ability to approximate real-time measurements due to task scheduling delays.
*/
Internals,
/**
* When drivers are used to augment the metrics views, such as with the CQL client, these metrics can be
* folded into metrics feeds. However, they are not part of the core NB metrics. Such auxiliary metric
* need to be identified separately.
*/
Driver,
/**
* Measurements of error rates, exception counts, and any other failure modes which can be counted or
* otherwise quantified
*/
Errors,
/**
* Verification logic is used to assert the validity or some property of results returned by individual
* operations. Verification is meant to indicate whether a result was valid or invalid, with no
* room for interpretation in between.
*/
Verification,
/**
* Metrics which describe payload properties, such as result size or similar
*/
Payload,
/**
* Sometimes users provide their own metrics instrumentation. These may or may not have descriptions provided.
*/
User,
/**
* Some metrics help provide insight into analysis methods and progress. This can include parameters for
* an optimizers configuration, parameters from a single frame of simulation, achieved results in the form of
* a value function, or similar.
*/
Analysis,
/**
* When the result returned by an operation is scrutinized for some degree of accuracy on a sliding scale,
* this category applies. This is distinct from Verification in that verification implies a pass/fail scenario,
* whereas accuracy measures are on a sliding scale where interpretation is often more subjective.
*/
Accuracy
}

View File

@ -16,6 +16,7 @@
package io.nosqlbench.nb.api.engine.metrics.wrappers;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.labels.NBLabeledElement;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.nb.api.engine.metrics.DoubleSummaryGauge;
@ -58,7 +59,7 @@ public class RelevancyMeasures implements NBLabeledElement {
for (RelevancyFunction function : f) {
this.functions.add(function);
function.prependLabels(this);
DoubleSummaryGauge gauge = parent.create().summaryGauge(function.getUniqueName(),DoubleSummaryGauge.Stat.Average.toString());
DoubleSummaryGauge gauge = parent.create().summaryGauge(function.getUniqueName(), List.of("average"), MetricCategory.Accuracy, DoubleSummaryGauge.Stat.Average.toString());
this.gauges.add(gauge);
}
return this;

View File

@ -17,6 +17,7 @@
package io.nosqlbench.nb.api.components.core;
import io.nosqlbench.nb.api.config.standard.TestComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBFunctionGauge;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricCounter;
import org.apache.logging.log4j.LogManager;
@ -54,10 +55,22 @@ class AttachedMetricsSummaryReporterTest {
TestComponent root = new TestComponent("root", "root");
scope.add(root);
TestComponent l1 = new TestComponent(root, "l1", "l1");
NBMetricCounter counter = l1.create().counter("mycounter");
NBMetricCounter counter = l1.create().counter(
"mycounter",
MetricCategory.Verification,
"A verification metric for testing"
);
// AttachedMetricsSummaryReporter reporter = l1.create().summaryReporter(1000);
NBFunctionGauge g1 = root.create().gauge("rootgauge", () -> 42d);
NBFunctionGauge g2 = l1.create().gauge("leafgauge", () -> 48d);
NBFunctionGauge g1 = root.create().gauge(
"rootgauge", () -> 42d,
MetricCategory.Verification,
"A verification metric for testing"
);
NBFunctionGauge g2 = l1.create().gauge(
"leafgauge", () -> 48d,
MetricCategory.Verification,
"A verification metric for testing"
);
// This wait state is here only to emulate some time passing while background processing
// in the component hierarchy runs. Without it, you would be standing and immediate tearing
@ -82,10 +95,22 @@ class AttachedMetricsSummaryReporterTest {
public void testAttachedReporter() {
TestComponent root = new TestComponent("root", "root");
TestComponent l1 = new TestComponent(root, "l1", "l1");
NBMetricCounter counter = l1.create().counter("mycounter");
NBMetricCounter counter = l1.create().counter(
"mycounter",
MetricCategory.Verification,
"A verification metric for testing"
);
// AttachedMetricsSummaryReporter reporter = l1.create().summaryReporter(5000);
NBFunctionGauge g1 = root.create().gauge("rootgauge", () -> 42d);
NBFunctionGauge g2 = l1.create().gauge("leafgauge", () -> 48d);
NBFunctionGauge g1 = root.create().gauge(
"rootgauge", () -> 42d,
MetricCategory.Verification,
"A verification metric for testing"
);
NBFunctionGauge g2 = l1.create().gauge(
"leafgauge", () -> 48d,
MetricCategory.Verification,
"A verification metric for testing"
);
// TODO: this output should also include the node itself
// TODO: end lifecycle events need to be supported for metrics flushing

View File

@ -17,6 +17,7 @@
package io.nosqlbench.nb.api.components.core;
import io.nosqlbench.nb.api.components.core.NBBaseComponentMetrics;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBBaseMetric;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
import org.junit.jupiter.api.Test;
@ -31,9 +32,17 @@ class NBBaseComponentMetricsTest {
void testBasicAddAndLookup() {
NBBaseComponentMetrics cm = new NBBaseComponentMetrics();
NBMetric m1 = new NBBaseMetric("k","20");
String m1Handle = cm.addComponentMetric(m1);
String m1Handle = cm.addComponentMetric(
m1,
MetricCategory.Verification,
"testing metric"
);
NBMetric m2 = new NBBaseMetric("k","27","l","62");
String m2Handle = cm.addComponentMetric(m2);
String m2Handle = cm.addComponentMetric(
m2,
MetricCategory.Verification,
"testing metric"
);
assertThat(cm.getComponentMetric(m1Handle)).isEqualTo(m1);
assertThat(cm.getComponentMetric(m2Handle)).isEqualTo(m2);
@ -42,9 +51,17 @@ class NBBaseComponentMetricsTest {
void find() {
NBBaseComponentMetrics cm = new NBBaseComponentMetrics();
NBMetric m1 = new NBBaseMetric("k","20");
String m1Handle = cm.addComponentMetric(m1);
String m1Handle = cm.addComponentMetric(
m1,
MetricCategory.Verification,
"testing metric"
);
NBMetric m2 = new NBBaseMetric("k","27","l","62");
String m2Handle = cm.addComponentMetric(m2);
String m2Handle = cm.addComponentMetric(
m2,
MetricCategory.Verification,
"testing metric"
);
assertThat(cm.findComponentMetrics("k=27")).isEqualTo(List.of(m2));
assertThat(cm.findComponentMetrics("k=20")).isNotEqualTo(List.of(m2));

View File

@ -17,6 +17,7 @@
package io.nosqlbench.nb.api.components.core;
import io.nosqlbench.nb.api.config.standard.TestComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBFunctionGauge;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetricTimer;
@ -35,7 +36,12 @@ class NBComponentServicesTest {
TestComponent a1 = new TestComponent(root, "a1", "a1");
TestComponent b1 = new TestComponent(a1, "b1", "b1");
NBMetricTimer timer1 = a1.create().timer("mfn1", 3);
NBMetricTimer timer1 = a1.create().timer(
"mfn1",
3,
MetricCategory.Verification,
"testing metric"
);
String handle = timer1.getHandle();
timer1.update(23L, TimeUnit.MILLISECONDS);
@ -45,7 +51,12 @@ class NBComponentServicesTest {
NBMetric foundByPattern = root.find().metric("name:mfn1");
assertThat(foundByPattern).isEqualTo(timer1);
NBFunctionGauge gauge = b1.create().gauge("test_gauge", () -> 5.2d);
NBFunctionGauge gauge = b1.create().gauge(
"test_gauge",
() -> 5.2d,
MetricCategory.Verification,
"testing metric"
);
String gaugeHandle = gauge.getHandle();
List<NBMetric> metricsInTree = root.find().metrics();

View File

@ -17,6 +17,7 @@
package io.nosqlbench.nb.api.components.core;
import io.nosqlbench.nb.api.config.standard.TestComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBBaseMetric;
import io.nosqlbench.nb.api.engine.metrics.instruments.NBMetric;
import org.junit.jupiter.api.Test;
@ -31,11 +32,23 @@ class NBMetricsQueryTest {
private final static TestComponent root_c2 = new TestComponent(root,"c2","c2");
private final static TestComponent root_c3 = new TestComponent(root,"c3","c3");
private final static NBMetric m1 = new NBBaseMetric("m1","m1");
private final static String m1Handle = root.addComponentMetric(m1);
private final static String m1Handle = root.addComponentMetric(
m1,
MetricCategory.Verification,
"testing metric"
);
private final static NBMetric m2 = new NBBaseMetric("m2","m2");
private final static String m2Handle = root_c2.addComponentMetric(m2);
private final static String m2Handle = root_c2.addComponentMetric(
m2,
MetricCategory.Verification,
"testing metric"
);
private final static NBMetric m3 = new NBBaseMetric("m3","m3");
private final static String m3Handle = root_c3.addComponentMetric(m3);
private final static String m3Handle = root_c3.addComponentMetric(
m3,
MetricCategory.Verification,
"testing metric"
);
@Test
public void testFindInTree() {

View File

@ -22,6 +22,7 @@ import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.events.ParamChange;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import io.nosqlbench.scenarios.simframe.capture.JournalView;
import io.nosqlbench.scenarios.simframe.capture.SimFrameCapture;
import io.nosqlbench.scenarios.simframe.planning.HoldAndSample;
@ -35,10 +36,29 @@ public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFramePara
public RCurvePlanner(NBBaseComponent parent, NBCommandParams params) {
super(parent,params);
create().gauge("rcuve_step",() -> lastFrame==null ? 0 : (double)lastFrame.step());
create().gauge("rcurve_maxstep",() -> lastFrame==null ? 0 : (double)lastFrame.maxsteps());
create().gauge("rcurve_ratio",() -> lastFrame==null ? 0.0 : lastFrame.ratio());
create().gauge("rcurve_rate",() -> lastFrame==null ? 0.0 : lastFrame.rate());
create().gauge(
"rcurve_step",
() -> lastFrame==null ? 0 : (double)lastFrame.step(),
MetricCategory.Analysis,
"The current step which the response curve analyzer is on"
);
create().gauge(
"rcurve_maxstep",
() -> lastFrame==null ? 0 : (double)lastFrame.maxsteps(),
MetricCategory.Analysis,
"The maximum step that the response curve analyzer will run"
);
create().gauge(
"rcurve_ratio",
() -> lastFrame==null ? 0.0 : lastFrame.ratio(),
MetricCategory.Analysis,
"The fractional throughput capacity of the current response curve step"
);
create().gauge(
"rcurve_rate",() -> lastFrame==null ? 0.0 : lastFrame.rate(),
MetricCategory.Analysis,
"The actual throughput target of the current response curve step"
);
}
@Override

View File

@ -19,6 +19,7 @@ package io.nosqlbench.engine.core.script;
import com.codahale.metrics.Histogram;
import io.nosqlbench.nb.api.config.standard.TestComponent;
import io.nosqlbench.nb.api.components.core.NBComponent;
import io.nosqlbench.nb.api.engine.metrics.instruments.MetricCategory;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -32,7 +33,12 @@ public class MetricsIntegrationTest {
@Test
public void testHistogramLogger() {
NBComponent parent = new TestComponent("metricstest","metricstest","alias","foo","driver","diag","op","noop");
final Histogram testhistogram = parent.create().histogram("testhistogram", 3);
final Histogram testhistogram = parent.create().histogram(
"testhistogram",
3,
MetricCategory.Verification,
"test metric"
);
// TODO: metrics
// ActivityMetrics.addHistoLogger("testsession", ".*","testhisto.log","1s");
testhistogram.update(400);