Skip to content

Commit

Permalink
adding log4jmetricsreporter
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkWolters committed Oct 7, 2023
1 parent f492979 commit 8f90820
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 203 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
package io.nosqlbench.api.engine.metrics.reporters;

import com.codahale.metrics.*;
import io.nosqlbench.api.labels.NBLabels;
import io.nosqlbench.components.NBComponent;
import io.nosqlbench.components.PeriodicTaskComponent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
Expand All @@ -32,201 +35,33 @@
* was built to allow for consolidating internal logging dependencies
* to log4j only.
*/
public class Log4JMetricsReporter extends ScheduledReporter {
/**
* Returns a new {@link Builder} for .
*
* @param registry the registry to report
* @return a {@link Builder} instance for a
*/
public static Builder forRegistry(final MetricRegistry registry) {
return new Builder(registry);
}

public class Log4JMetricsReporter extends PeriodicTaskComponent {
public enum LoggingLevel { TRACE, DEBUG, INFO, WARN, ERROR }

/**
* A builder for {@link Log4JMetricsReporter} instances. Defaults to logging to {@code metrics}, not
* using a marker, converting rates to events/second, converting durations to milliseconds, and
* not filtering metrics.
*/
public static class Builder {
private final MetricRegistry registry;
private Logger logger;
private LoggingLevel loggingLevel;
private Marker marker;
private String prefix;
private TimeUnit rateUnit;
private TimeUnit durationUnit;
private MetricFilter filter;
private ScheduledExecutorService executor;
private boolean shutdownExecutorOnStop;

private Builder(final MetricRegistry registry) {
this.registry = registry;
logger = LogManager.getLogger("metrics");
marker = null;
prefix = "";
rateUnit = TimeUnit.SECONDS;
durationUnit = TimeUnit.MILLISECONDS;
filter = MetricFilter.ALL;
loggingLevel = LoggingLevel.INFO;
executor = null;
shutdownExecutorOnStop = true;
}

/**
* Specifies whether or not, the executor (used for reporting) will be stopped with same time with reporter.
* Default value is true.
* Setting this parameter to false, has the sense in combining with providing external managed executor via {@link #scheduleOn(ScheduledExecutorService)}.
*
* @param shutdownExecutorOnStop if true, then executor will be stopped in same time with this reporter
* @return {@code this}
*/
public Builder shutdownExecutorOnStop(final boolean shutdownExecutorOnStop) {
this.shutdownExecutorOnStop = shutdownExecutorOnStop;
return this;
}

/**
* Specifies the executor to use while scheduling reporting of metrics.
* Default value is null.
* Null value leads to executor will be auto created on start.
*
* @param executor the executor to use while scheduling reporting of metrics.
* @return {@code this}
*/
public Builder scheduleOn(final ScheduledExecutorService executor) {
this.executor = executor;
return this;
}

/**
* Log metrics to the given logger.
*
* @param logger an SLF4J {@link Logger}
* @return {@code this}
*/
public Builder outputTo(final Logger logger) {
this.logger = logger;
return this;
}

/**
* Mark all logged metrics with the given marker.
*
* @param marker an SLF4J {@link Marker}
* @return {@code this}
*/
public Builder markWith(final Marker marker) {
this.marker = marker;
return this;
}

/**
* Prefix all metric names with the given string.
*
* @param prefix the prefix for all metric names
* @return {@code this}
*/
public Builder prefixedWith(final String prefix) {
this.prefix = prefix;
return this;
}

/**
* Convert rates to the given time unit.
*
* @param rateUnit a unit of time
* @return {@code this}
*/
public Builder convertRatesTo(final TimeUnit rateUnit) {
this.rateUnit = rateUnit;
return this;
}

/**
* Convert durations to the given time unit.
*
* @param durationUnit a unit of time
* @return {@code this}
*/
public Builder convertDurationsTo(final TimeUnit durationUnit) {
this.durationUnit = durationUnit;
return this;
}

/**
* Only report metrics which match the given filter.
*
* @param filter a {@link MetricFilter}
* @return {@code this}
*/
public Builder filter(final MetricFilter filter) {
this.filter = filter;
return this;
}

/**
* Use Logging Level when reporting.
*
* @param loggingLevel a (@link Slf4jReporter.LoggingLevel}
* @return {@code this}
*/
public Builder withLoggingLevel(final LoggingLevel loggingLevel) {
this.loggingLevel = loggingLevel;
return this;
}

/**
* Builds a {@link Log4JMetricsReporter} with the given properties.
*
* @return a {@link Log4JMetricsReporter}
*/
public Log4JMetricsReporter build() {
final LoggerProxy loggerProxy;
switch (this.loggingLevel) {
case TRACE:
loggerProxy = new TraceLoggerProxy(this.logger);
break;
case INFO:
loggerProxy = new InfoLoggerProxy(this.logger);
break;
case WARN:
loggerProxy = new WarnLoggerProxy(this.logger);
break;
case ERROR:
loggerProxy = new ErrorLoggerProxy(this.logger);
break;
default:
case DEBUG:
loggerProxy = new DebugLoggerProxy(this.logger);
break;
}
return new Log4JMetricsReporter(this.registry, loggerProxy, this.marker, this.prefix, this.rateUnit, this.durationUnit, this.filter, this.executor, this.shutdownExecutorOnStop);
}
}

private final LoggerProxy loggerProxy;
private final Marker marker;
private final String prefix;

private Log4JMetricsReporter(final MetricRegistry registry,
final LoggerProxy loggerProxy,
final Marker marker,
final String prefix,
final TimeUnit rateUnit,
final TimeUnit durationUnit,
final MetricFilter filter,
final ScheduledExecutorService executor,
final boolean shutdownExecutorOnStop) {
super(registry, "logger-reporter", filter, rateUnit, durationUnit, executor, shutdownExecutorOnStop);
private final TimeUnit rateUnit = TimeUnit.NANOSECONDS;
private final TimeUnit durationUnit = TimeUnit.NANOSECONDS;
private final long durationFactor = TimeUnit.NANOSECONDS.toNanos(1);
private final long rateFactor = TimeUnit.NANOSECONDS.toSeconds(1);;

public Log4JMetricsReporter(final NBComponent component,
final LoggerProxy loggerProxy,
final Marker marker,
final MetricFilter filter,
final NBLabels extraLabels,
final int seconds,
final boolean oneLastTime) {
super(component, extraLabels, seconds, oneLastTime);
this.loggerProxy = loggerProxy;
this.marker = marker;
this.prefix = prefix;
}

@Override
protected void task() {

}

@SuppressWarnings("rawtypes")
public void report(final SortedMap<String, Gauge> gauges,
final SortedMap<String, Counter> counters,
Expand Down Expand Up @@ -275,7 +110,13 @@ private void logTimer(final String name, final Timer timer) {
this.convertRate(timer.getFiveMinuteRate()),
this.convertRate(timer.getFifteenMinuteRate()),
this.getRateUnit(),
this.getDurationUnit());
this.durationUnit);
}
protected double convertDuration(double duration) {
return duration / durationFactor;
}
protected double convertRate(double rate) {
return rate * rateFactor;
}

private void logMeter(final String name, final Meter meter) {
Expand Down Expand Up @@ -319,17 +160,16 @@ private void logGauge(final String name, final Gauge<?> gauge) {
this.loggerProxy.log(this.marker, "type={}, name={}, value={}", "GAUGE", this.prefix(name), gauge.getValue());
}

@Override
protected String getRateUnit() {
return "events/" + super.getRateUnit();
return "events/" + rateUnit;
}

private String prefix(final String... components) {
return MetricRegistry.name(this.prefix, components);
return getParent().getLabels().linearizeAsMetrics();
}

/* private class to allow logger configuration */
abstract static class LoggerProxy {
public abstract static class LoggerProxy {
protected final Logger logger;

protected LoggerProxy(final Logger logger) {
Expand All @@ -342,7 +182,7 @@ protected LoggerProxy(final Logger logger) {
}

/* private class to allow logger configuration */
private static class DebugLoggerProxy extends LoggerProxy {
public static class DebugLoggerProxy extends LoggerProxy {
public DebugLoggerProxy(final Logger logger) {
super(logger);
}
Expand All @@ -359,7 +199,7 @@ public boolean isEnabled(final Marker marker) {
}

/* private class to allow logger configuration */
private static class TraceLoggerProxy extends LoggerProxy {
public static class TraceLoggerProxy extends LoggerProxy {
public TraceLoggerProxy(final Logger logger) {
super(logger);
}
Expand All @@ -376,7 +216,7 @@ public boolean isEnabled(final Marker marker) {
}

/* private class to allow logger configuration */
private static class InfoLoggerProxy extends LoggerProxy {
public static class InfoLoggerProxy extends LoggerProxy {
public InfoLoggerProxy(final Logger logger) {
super(logger);
}
Expand All @@ -393,7 +233,7 @@ public boolean isEnabled(final Marker marker) {
}

/* private class to allow logger configuration */
private static class WarnLoggerProxy extends LoggerProxy {
public static class WarnLoggerProxy extends LoggerProxy {
public WarnLoggerProxy(final Logger logger) {
super(logger);
}
Expand All @@ -410,7 +250,7 @@ public boolean isEnabled(final Marker marker) {
}

/* private class to allow logger configuration */
private static class ErrorLoggerProxy extends LoggerProxy {
public static class ErrorLoggerProxy extends LoggerProxy {
public ErrorLoggerProxy(final Logger logger) {
super(logger);
}
Expand Down

0 comments on commit 8f90820

Please sign in to comment.