mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
add support for named timers as "start-timers" and "stop-timers" op fields
This commit is contained in:
parent
4d7355c803
commit
5a4692cf9e
@ -20,7 +20,7 @@ import com.codahale.metrics.Histogram;
|
|||||||
import com.codahale.metrics.Timer;
|
import com.codahale.metrics.Timer;
|
||||||
import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate;
|
import io.nosqlbench.engine.api.activityconfig.yaml.OpTemplate;
|
||||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||||
import io.nosqlbench.engine.api.templating.CommandTemplate;
|
import io.nosqlbench.engine.api.metrics.ThreadLocalNamedTimers;
|
||||||
import io.nosqlbench.engine.api.templating.ParsedOp;
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -31,6 +31,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
*
|
*
|
||||||
* Some details are tracked per op template, which aligns to the life-cycle of the op dispenser.
|
* Some details are tracked per op template, which aligns to the life-cycle of the op dispenser.
|
||||||
* Thus, each op dispenser is where the stats for all related operations are kept.
|
* Thus, each op dispenser is where the stats for all related operations are kept.
|
||||||
|
*
|
||||||
* @param <T> The type of operation
|
* @param <T> The type of operation
|
||||||
*/
|
*/
|
||||||
public abstract class BaseOpDispenser<T> implements OpDispenser<T> {
|
public abstract class BaseOpDispenser<T> implements OpDispenser<T> {
|
||||||
@ -40,22 +41,40 @@ public abstract class BaseOpDispenser<T> implements OpDispenser<T> {
|
|||||||
private Histogram resultSizeHistogram;
|
private Histogram resultSizeHistogram;
|
||||||
private Timer successTimer;
|
private Timer successTimer;
|
||||||
private Timer errorTimer;
|
private Timer errorTimer;
|
||||||
|
private String[] timerStarts = new String[0];
|
||||||
|
private String[] timerStops = new String[0];
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Consider changing this to "ready op template" or similar
|
||||||
public BaseOpDispenser(OpTemplate optpl) {
|
public BaseOpDispenser(OpTemplate optpl) {
|
||||||
this.name = optpl.getName();
|
this.name = optpl.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseOpDispenser(ParsedOp op) {
|
public BaseOpDispenser(ParsedOp op) {
|
||||||
this.name = op.getName();
|
this.name = op.getName();
|
||||||
|
timerStarts = op.takeOptionalStaticValue("start-timers", String.class)
|
||||||
|
.map(s -> s.split(", *"))
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
timerStops = op.takeOptionalStaticValue("stop-timers", String.class)
|
||||||
|
.map(s -> s.split(", *"))
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (timerStarts!=null) {
|
||||||
|
for (String timerStart : timerStarts) {
|
||||||
|
ThreadLocalNamedTimers.addTimer(op,timerStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
configureInstrumentation(op);
|
configureInstrumentation(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseOpDispenser(CommandTemplate cmdtpl) {
|
// public BaseOpDispenser(CommandTemplate cmdtpl) {
|
||||||
this.name = cmdtpl.getName();
|
// this.name = cmdtpl.getName();
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
* @param value The cycle number which serves as the seed for any
|
* @param value The cycle number which serves as the seed for any
|
||||||
* generated op fields to be bound into an operation.
|
* generated op fields to be bound into an operation.
|
||||||
* @return
|
* @return
|
||||||
@ -63,31 +82,54 @@ public abstract class BaseOpDispenser<T> implements OpDispenser<T> {
|
|||||||
@Override
|
@Override
|
||||||
public abstract T apply(long value);
|
public abstract T apply(long value);
|
||||||
|
|
||||||
private void configureInstrumentation(ParsedOp optpl) {
|
private void configureInstrumentation(ParsedOp pop) {
|
||||||
this.instrument = optpl.getStaticConfigOr("instrument", false);
|
this.instrument = pop.takeStaticConfigOr("instrument", false);
|
||||||
if (instrument) {
|
if (instrument) {
|
||||||
this.successTimer = ActivityMetrics.timer(optpl.getStaticConfigOr("alias","UNKNOWN")+"-"+optpl.getName()+"--success");
|
this.successTimer = ActivityMetrics.timer(pop.getStaticConfigOr("alias", "UNKNOWN") + "-" + pop.getName() + "--success");
|
||||||
this.errorTimer = ActivityMetrics.timer(optpl.getStaticConfigOr("alias","UNKNOWN")+"-"+optpl.getName()+"--error");
|
this.errorTimer = ActivityMetrics.timer(pop.getStaticConfigOr("alias", "UNKNOWN") + "-" + pop.getName() + "--error");
|
||||||
this.resultSizeHistogram = ActivityMetrics.histogram(optpl.getStaticConfigOr("alias","UNKNOWN")+"-"+optpl.getName()+ "--resultset-size");
|
this.resultSizeHistogram = ActivityMetrics.histogram(pop.getStaticConfigOr("alias", "UNKNOWN") + "-" + pop.getName() + "--resultset-size");
|
||||||
|
}
|
||||||
|
|
||||||
|
timerStarts = pop.takeOptionalStaticValue("start-timers", String.class)
|
||||||
|
.map(s -> s.split(", *"))
|
||||||
|
.orElse(null);
|
||||||
|
|
||||||
|
if (timerStarts!=null) {
|
||||||
|
for (String timerStart : timerStarts) {
|
||||||
|
ThreadLocalNamedTimers.addTimer(pop,timerStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timerStops = pop.takeOptionalStaticValue("stop-timers", String.class)
|
||||||
|
.map(s -> s.split(", *"))
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart(long cycleValue) {
|
||||||
|
if (timerStarts!=null) {
|
||||||
|
ThreadLocalNamedTimers.TL_INSTANCE.get().start(timerStops);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(long cycleValue, long nanoTime, long resultsize) {
|
public void onSuccess(long cycleValue, long nanoTime, long resultsize) {
|
||||||
if (!instrument) {
|
if (instrument) {
|
||||||
return;
|
successTimer.update(nanoTime, TimeUnit.NANOSECONDS);
|
||||||
|
resultSizeHistogram.update(resultsize);
|
||||||
}
|
}
|
||||||
successTimer.update(nanoTime, TimeUnit.NANOSECONDS);
|
|
||||||
resultSizeHistogram.update(resultsize);
|
|
||||||
// ThreadLocalNamedTimers.TL_INSTANCE.get().stop(stopTimers);
|
// ThreadLocalNamedTimers.TL_INSTANCE.get().stop(stopTimers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(long cycleValue, long resultNanos, Throwable t) {
|
public void onError(long cycleValue, long resultNanos, Throwable t) {
|
||||||
if (!instrument) {
|
if (instrument) {
|
||||||
return;
|
errorTimer.update(resultNanos, TimeUnit.NANOSECONDS);
|
||||||
|
}
|
||||||
|
if (timerStops!=null) {
|
||||||
|
ThreadLocalNamedTimers.TL_INSTANCE.get().stop(timerStops);
|
||||||
}
|
}
|
||||||
errorTimer.update(resultNanos, TimeUnit.NANOSECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -81,4 +81,6 @@ public interface OpDispenser<T> extends LongFunction<T>, OpResultTracker {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
T apply(long value);
|
T apply(long value);
|
||||||
|
|
||||||
|
void onStart(long cycleValue);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package io.nosqlbench.engine.api.metrics;
|
|||||||
|
|
||||||
import com.codahale.metrics.Timer;
|
import com.codahale.metrics.Timer;
|
||||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||||
|
import io.nosqlbench.engine.api.templating.ParsedOp;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@ -44,6 +45,14 @@ public class ThreadLocalNamedTimers {
|
|||||||
timers.put(name, timer);
|
timers.put(name, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addTimer(ParsedOp pop, String name) {
|
||||||
|
if (timers.containsKey("name")) {
|
||||||
|
logger.warn("A timer named '" + name + "' was already defined and initialized.");
|
||||||
|
}
|
||||||
|
Timer timer = ActivityMetrics.timer(pop.getStaticConfig("alias",String.class)+"."+name);
|
||||||
|
timers.put(name, timer);
|
||||||
|
}
|
||||||
|
|
||||||
public void start(String name) {
|
public void start(String name) {
|
||||||
Timer.Context context = timers.get(name).time();
|
Timer.Context context = timers.get(name).time();
|
||||||
contexts.put(name, context);
|
contexts.put(name, context);
|
||||||
@ -54,9 +63,15 @@ public class ThreadLocalNamedTimers {
|
|||||||
context.stop();
|
context.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(List<String> timerName) {
|
public void start(List<String> timerNames) {
|
||||||
for (String startTimer : timerName) {
|
for (String timerName : timerNames) {
|
||||||
start(startTimer);
|
start(timerName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start(String[] timerNames) {
|
||||||
|
for (String timerName : timerNames) {
|
||||||
|
start(timerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,4 +81,9 @@ public class ThreadLocalNamedTimers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stop(String[] timerStops) {
|
||||||
|
for (String timerStop : timerStops) {
|
||||||
|
stop(timerStop);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,8 @@ public class StandardAction<A extends StandardActivity<R, ?>, R extends Op> impl
|
|||||||
Throwable error = null;
|
Throwable error = null;
|
||||||
long startedAt = System.nanoTime();
|
long startedAt = System.nanoTime();
|
||||||
|
|
||||||
|
dispenser.onStart(cycle);
|
||||||
|
|
||||||
try (Timer.Context ct = executeTimer.time()) {
|
try (Timer.Context ct = executeTimer.time()) {
|
||||||
if (op instanceof RunnableOp) {
|
if (op instanceof RunnableOp) {
|
||||||
((RunnableOp) op).run();
|
((RunnableOp) op).run();
|
||||||
|
Loading…
Reference in New Issue
Block a user