From 9b961c46d716811cd2ee042e19ff03b29810b7ca Mon Sep 17 00:00:00 2001 From: Jake Landis Date: Tue, 22 Aug 2017 17:06:17 -0500 Subject: [PATCH] Metrics: Add custom witness for plugins, and code clean up Remove LongGauge and DoubleGauge and Replace with NumberGauge - This is an unecessary distiction for Gauges and can complicate the serialization. Double/Float should serialize with decimal precision, and Jackson handles this by default. Add custom witness to match existing Ruby API, such that existing Ruby plugins should not need changes Remove namespace from LazyDelegatingGauge - It was only there for logging, but newer versions (not here) will completely remove the concept of namespace. Part of #7788 Fixes #8053 --- .../logstash/instrument/metric_type/gauge.rb | 2 +- .../instrument/metrics/MetricType.java | 8 +- .../instrument/metrics/gauge/DoubleGauge.java | 35 ---- .../metrics/gauge/LazyDelegatingGauge.java | 38 ++-- .../{LongGauge.java => NumberGauge.java} | 12 +- .../instrument/witness/ConfigWitness.java | 36 ++-- .../witness/DeadLetterQueueWitness.java | 12 +- .../instrument/witness/MetricSerializer.java | 17 +- .../instrument/witness/PluginWitness.java | 182 ++++++++++++++++++ .../instrument/witness/PluginsWitness.java | 1 - .../instrument/witness/QueueWitness.java | 52 ++--- .../instrument/metrics/MetricTypeTest.java | 3 +- .../metrics/counter/LongCounterTest.java | 1 - .../metrics/gauge/DoubleGaugeTest.java | 33 ---- .../gauge/LazyDelegatingGaugeTest.java | 50 +++-- .../metrics/gauge/LongGaugeTest.java | 34 ---- .../metrics/gauge/NumberGaugeTest.java | 37 ++++ .../instrument/witness/ConfigWitnessTest.java | 8 +- .../witness/DeadLetterQueueWitnessTest.java | 2 +- .../instrument/witness/ErrorWitnessTest.java | 1 - .../instrument/witness/PluginWitnessTest.java | 116 ++++++++++- .../instrument/witness/QueueWitnessTest.java | 13 +- 22 files changed, 462 insertions(+), 231 deletions(-) delete mode 100644 logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/DoubleGauge.java rename logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/{LongGauge.java => NumberGauge.java} (69%) delete mode 100644 logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/DoubleGaugeTest.java delete mode 100644 logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LongGaugeTest.java create mode 100644 logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/NumberGaugeTest.java diff --git a/logstash-core/lib/logstash/instrument/metric_type/gauge.rb b/logstash-core/lib/logstash/instrument/metric_type/gauge.rb index f78080537..e6492305e 100644 --- a/logstash-core/lib/logstash/instrument/metric_type/gauge.rb +++ b/logstash-core/lib/logstash/instrument/metric_type/gauge.rb @@ -4,7 +4,7 @@ module LogStash module Instrument module MetricType class Gauge < LazyDelegatingGauge def initialize(namespaces, key) - super(namespaces, key.to_s) + super(key.to_s) end def execute(action, value = nil) diff --git a/logstash-core/src/main/java/org/logstash/instrument/metrics/MetricType.java b/logstash-core/src/main/java/org/logstash/instrument/metrics/MetricType.java index 292c46cf4..6a3e86cdc 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/metrics/MetricType.java +++ b/logstash-core/src/main/java/org/logstash/instrument/metrics/MetricType.java @@ -21,13 +21,9 @@ public enum MetricType { */ GAUGE_BOOLEAN("gauge/boolean"), /** - * A gauge backed by a {@link Double} type + * A gauge backed by a {@link Number} type */ - GAUGE_DOUBLE("gauge/double"), - /** - * A gauge backed by a {@link Long} type - */ - GAUGE_LONG("gauge/long"), + GAUGE_NUMBER("gauge/number"), /** * A gauge backed by a {@link Object} type. */ diff --git a/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/DoubleGauge.java b/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/DoubleGauge.java deleted file mode 100644 index ab77e05d9..000000000 --- a/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/DoubleGauge.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.logstash.instrument.metrics.gauge; - -import org.logstash.instrument.metrics.MetricType; - -/** - * A {@link GaugeMetric} that is backed by a {@link Double} - */ -public class DoubleGauge extends AbstractGaugeMetric { - - /** - * Constructor - * - * @param name The name of this metric. This value may be used for display purposes. - */ - public DoubleGauge(String name) { - super(name); - } - - /** - * Constructor - * - * @param name The name of this metric. This value may be used for display purposes. - * @param initialValue The initial value for this {@link GaugeMetric}, may be null - */ - public DoubleGauge(String name, Double initialValue) { - super(name, initialValue); - } - - @Override - public MetricType getType() { - return MetricType.GAUGE_DOUBLE; - } - -} - diff --git a/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGauge.java b/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGauge.java index e684eefd7..b54bfc354 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGauge.java +++ b/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGauge.java @@ -7,44 +7,39 @@ import org.logstash.ext.JrubyTimestampExtLibrary.RubyTimestamp; import org.logstash.instrument.metrics.AbstractMetric; import org.logstash.instrument.metrics.MetricType; -import java.util.List; - /** * A lazy proxy to a more specific typed {@link GaugeMetric}. The metric will only be initialized if the initial value is set, or once the {@code set} operation is called. *

Intended only for use with Ruby's duck typing, Java consumers should use the specific typed {@link GaugeMetric}

+ * * @deprecated - there are no plans to replace this. */ -public class LazyDelegatingGauge extends AbstractMetric implements GaugeMetric { +public class LazyDelegatingGauge extends AbstractMetric implements GaugeMetric { private final static Logger LOGGER = LogManager.getLogger(LazyDelegatingGauge.class); protected final String key; - protected final List nameSpaces; private GaugeMetric lazyMetric; /** - * Constructor - protected so that Ruby may sub class proxy and discourage usage from Java, null initial value + * Constructor - null initial value * - * @param nameSpace The namespace for this metric - * @param key The key (with in the namespace) for this metric + * @param key The key (with in the namespace) for this metric * @deprecated - there are no plans to replace this */ - public LazyDelegatingGauge(final List nameSpace, final String key) { - this(nameSpace, key, null); + public LazyDelegatingGauge(final String key) { + this(key, null); } /** - * Constructor - protected so that Ruby may sub class proxy and discourage usage from Java + * Constructor - with initial value * - * @param nameSpace The namespace for this metric - * @param key The key (with in the namespace) for this metric + * @param key The key for this metric * @param initialValue The initial value for this {@link GaugeMetric}, may be null * @deprecated - there are no plans to replace this */ - protected LazyDelegatingGauge(List nameSpace, String key, Object initialValue) { + public LazyDelegatingGauge(String key, Object initialValue) { super(key); - this.nameSpaces = nameSpace; this.key = key; if (initialValue != null) { wakeMetric(initialValue); @@ -52,7 +47,7 @@ public class LazyDelegatingGauge extends AbstractMetric implements Gauge } @Override - @SuppressWarnings( "deprecation" ) + @SuppressWarnings("deprecation") public Object get() { return lazyMetric == null ? null : lazyMetric.get(); } @@ -86,10 +81,8 @@ public class LazyDelegatingGauge extends AbstractMetric implements Gauge //"quack quack" if (value instanceof String) { lazyMetric = new TextGauge(key, (String) value); - } else if (value instanceof Long) { - lazyMetric = new LongGauge(key, (Long) value); - } else if (value instanceof Double) { - lazyMetric = new DoubleGauge(key, (Double) value); + } else if (value instanceof Number) { + lazyMetric = new NumberGauge(key, (Number) value); } else if (value instanceof Boolean) { lazyMetric = new BooleanGauge(key, (Boolean) value); } else if (value instanceof RubyHash) { @@ -97,11 +90,10 @@ public class LazyDelegatingGauge extends AbstractMetric implements Gauge } else if (value instanceof RubyTimestamp) { lazyMetric = new RubyTimeStampGauge(key, ((RubyTimestamp) value)); } else { - LOGGER.warn("A gauge metric of an unknown type ({}) has been create for key: {}, namespace:{}. This may result in invalid serialization. It is recommended to " + - "log an issue to the responsible developer/development team.", value.getClass().getCanonicalName(), key, nameSpaces); + LOGGER.warn("A gauge metric of an unknown type ({}) has been create for key: {}. This may result in invalid serialization. It is recommended to " + + "log an issue to the responsible developer/development team.", value.getClass().getCanonicalName(), key); lazyMetric = new UnknownGauge(key, value); } } - } - + } } diff --git a/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LongGauge.java b/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/NumberGauge.java similarity index 69% rename from logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LongGauge.java rename to logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/NumberGauge.java index 2351e3518..143947f20 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/LongGauge.java +++ b/logstash-core/src/main/java/org/logstash/instrument/metrics/gauge/NumberGauge.java @@ -3,17 +3,16 @@ package org.logstash.instrument.metrics.gauge; import org.logstash.instrument.metrics.MetricType; /** - * A {@link GaugeMetric} that is backed by a {@link Long} + * A {@link GaugeMetric} that is backed by a {@link Number} */ -public class LongGauge extends AbstractGaugeMetric { - +public class NumberGauge extends AbstractGaugeMetric { /** * Constructor * * @param name The name of this metric. This value may be used for display purposes. */ - public LongGauge(String name) { + public NumberGauge(String name) { super(name); } @@ -23,14 +22,13 @@ public class LongGauge extends AbstractGaugeMetric { * @param name The name of this metric. This value may be used for display purposes. * @param initialValue The initial value for this {@link GaugeMetric}, may be null */ - public LongGauge(String name, Long initialValue) { + public NumberGauge(String name, Number initialValue) { super(name, initialValue); - } @Override public MetricType getType() { - return MetricType.GAUGE_LONG; + return MetricType.GAUGE_NUMBER; } } diff --git a/logstash-core/src/main/java/org/logstash/instrument/witness/ConfigWitness.java b/logstash-core/src/main/java/org/logstash/instrument/witness/ConfigWitness.java index e4fea54e1..6ef45c3a8 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/witness/ConfigWitness.java +++ b/logstash-core/src/main/java/org/logstash/instrument/witness/ConfigWitness.java @@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import org.logstash.instrument.metrics.Metric; import org.logstash.instrument.metrics.gauge.BooleanGauge; -import org.logstash.instrument.metrics.gauge.LongGauge; +import org.logstash.instrument.metrics.gauge.NumberGauge; import org.logstash.instrument.metrics.gauge.TextGauge; import java.io.IOException; @@ -19,10 +19,10 @@ final public class ConfigWitness implements SerializableWitness { private final BooleanGauge deadLetterQueueEnabled; private final BooleanGauge configReloadAutomatic; - private final LongGauge batchSize; - private final LongGauge workers; - private final LongGauge batchDelay; - private final LongGauge configReloadInterval; + private final NumberGauge batchSize; + private final NumberGauge workers; + private final NumberGauge batchDelay; + private final NumberGauge configReloadInterval; private final TextGauge deadLetterQueuePath; private final Snitch snitch; private final static String KEY = "config"; @@ -35,10 +35,10 @@ final public class ConfigWitness implements SerializableWitness { public ConfigWitness() { deadLetterQueueEnabled = new BooleanGauge("dead_letter_queue_enabled"); configReloadAutomatic = new BooleanGauge("config_reload_automatic"); - batchSize = new LongGauge("batch_size"); - workers = new LongGauge("workers"); - batchDelay = new LongGauge("batch_delay"); - configReloadInterval = new LongGauge("config_reload_interval"); + batchSize = new NumberGauge("batch_size"); + workers = new NumberGauge("workers"); + batchDelay = new NumberGauge("batch_delay"); + configReloadInterval = new NumberGauge("config_reload_interval"); deadLetterQueuePath = new TextGauge("dead_letter_queue_path"); snitch = new Snitch(this); } @@ -151,14 +151,14 @@ final public class ConfigWitness implements SerializableWitness { void innerSerialize(ConfigWitness witness, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeObjectFieldStart(KEY); - MetricSerializer> longSerializer = MetricSerializer.Get.longSerializer(gen); + MetricSerializer> numberSerializer = MetricSerializer.Get.numberSerializer(gen); MetricSerializer> booleanSerializer = MetricSerializer.Get.booleanSerializer(gen); MetricSerializer> stringSerializer = MetricSerializer.Get.stringSerializer(gen); - longSerializer.serialize(witness.batchSize); - longSerializer.serialize(witness.workers); - longSerializer.serialize(witness.batchDelay); - longSerializer.serialize(witness.configReloadInterval); + numberSerializer.serialize(witness.batchSize); + numberSerializer.serialize(witness.workers); + numberSerializer.serialize(witness.batchDelay); + numberSerializer.serialize(witness.configReloadInterval); booleanSerializer.serialize(witness.configReloadAutomatic); booleanSerializer.serialize(witness.deadLetterQueueEnabled); stringSerializer.serialize(witness.deadLetterQueuePath); @@ -182,7 +182,7 @@ final public class ConfigWitness implements SerializableWitness { * * @return the batch delay. May be {@code null} */ - public Long batchDelay() { + public Number batchDelay() { return witness.batchDelay.getValue(); } @@ -192,7 +192,7 @@ final public class ConfigWitness implements SerializableWitness { * * @return the batch size. May be {@code null} */ - public Long batchSize() { + public Number batchSize() { return witness.batchSize.getValue(); } @@ -211,7 +211,7 @@ final public class ConfigWitness implements SerializableWitness { * * @return the configured reload interval. May be {@code null} */ - public Long configReloadInterval() { + public Number configReloadInterval() { return witness.configReloadInterval.getValue(); } @@ -239,7 +239,7 @@ final public class ConfigWitness implements SerializableWitness { * * @return the configured number of workers. May be {@code null} */ - public Long workers() { + public Number workers() { return witness.workers.getValue(); } } diff --git a/logstash-core/src/main/java/org/logstash/instrument/witness/DeadLetterQueueWitness.java b/logstash-core/src/main/java/org/logstash/instrument/witness/DeadLetterQueueWitness.java index 7c91a5ee6..f098e15dc 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/witness/DeadLetterQueueWitness.java +++ b/logstash-core/src/main/java/org/logstash/instrument/witness/DeadLetterQueueWitness.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import org.logstash.instrument.metrics.Metric; -import org.logstash.instrument.metrics.gauge.LongGauge; +import org.logstash.instrument.metrics.gauge.NumberGauge; import java.io.IOException; @@ -18,13 +18,13 @@ public class DeadLetterQueueWitness implements SerializableWitness { private static String KEY = "dead_letter_queue"; private static final Serializer SERIALIZER = new Serializer(); private final Snitch snitch; - private final LongGauge queueSizeInBytes; + private final NumberGauge queueSizeInBytes; /** * Constructor */ public DeadLetterQueueWitness() { - queueSizeInBytes = new LongGauge("queue_size_in_bytes"); + queueSizeInBytes = new NumberGauge("queue_size_in_bytes"); snitch = new Snitch(this); } @@ -82,8 +82,8 @@ public class DeadLetterQueueWitness implements SerializableWitness { void innerSerialize(DeadLetterQueueWitness witness, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeObjectFieldStart(KEY); - MetricSerializer> longSerializer = MetricSerializer.Get.longSerializer(gen); - longSerializer.serialize(witness.queueSizeInBytes); + MetricSerializer> numberSerializer = MetricSerializer.Get.numberSerializer(gen); + numberSerializer.serialize(witness.queueSizeInBytes); gen.writeEndObject(); } } @@ -103,7 +103,7 @@ public class DeadLetterQueueWitness implements SerializableWitness { * * @return the queue size in bytes. May be {@code null} */ - public Long queueSizeInBytes() { + public Number queueSizeInBytes() { return witness.queueSizeInBytes.getValue(); } } diff --git a/logstash-core/src/main/java/org/logstash/instrument/witness/MetricSerializer.java b/logstash-core/src/main/java/org/logstash/instrument/witness/MetricSerializer.java index 7e5ab2d03..acb0140a2 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/witness/MetricSerializer.java +++ b/logstash-core/src/main/java/org/logstash/instrument/witness/MetricSerializer.java @@ -25,9 +25,24 @@ public interface MetricSerializer> { /** * Helper class to create a functional fluent api. - * Usage example: {@code MetricSerializer.Get.longSerializer(gen).serialize(99);} + * Usage example: {@code MetricSerializer.Get.numberSerializer(gen).serialize(99);} */ class Get { + /** + * Proper way to serialize a {@link Number} type metric to JSON + * + * @param gen The {@link JsonGenerator} used to generate JSON + * @return the {@link MetricSerializer} which is the function used to serialize the metric + */ + static MetricSerializer> numberSerializer(JsonGenerator gen) { + return m -> { + if (m != null) { + Number value = m.getValue(); + gen.writeObjectField(m.getName(), value == null ? 0 : value); + } + }; + } + /** * Proper way to serialize a {@link Long} type metric to JSON * diff --git a/logstash-core/src/main/java/org/logstash/instrument/witness/PluginWitness.java b/logstash-core/src/main/java/org/logstash/instrument/witness/PluginWitness.java index 0eaa03f47..a161c0cbd 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/witness/PluginWitness.java +++ b/logstash-core/src/main/java/org/logstash/instrument/witness/PluginWitness.java @@ -4,10 +4,19 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.jruby.RubySymbol; import org.logstash.instrument.metrics.Metric; +import org.logstash.instrument.metrics.counter.CounterMetric; +import org.logstash.instrument.metrics.counter.LongCounter; +import org.logstash.instrument.metrics.gauge.GaugeMetric; +import org.logstash.instrument.metrics.gauge.LazyDelegatingGauge; import org.logstash.instrument.metrics.gauge.TextGauge; import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * Witness for a single plugin. @@ -16,9 +25,12 @@ import java.io.IOException; public class PluginWitness implements SerializableWitness { private final EventsWitness eventsWitness; + private final CustomWitness customWitness; private final TextGauge id; private final TextGauge name; private final Snitch snitch; + + private static final Serializer SERIALIZER = new Serializer(); /** @@ -28,6 +40,7 @@ public class PluginWitness implements SerializableWitness { */ public PluginWitness(String id) { eventsWitness = new EventsWitness(); + customWitness = new CustomWitness(); this.id = new TextGauge("id", id); this.name = new TextGauge("name"); this.snitch = new Snitch(this); @@ -53,6 +66,15 @@ public class PluginWitness implements SerializableWitness { return this; } + /** + * Get a reference to the associated custom witness + * + * @return the {@link CustomWitness} + */ + public CustomWitness custom() { + return this.customWitness; + } + /** * Get a reference to associated snitch to get discrete metric values. * @@ -97,9 +119,169 @@ public class PluginWitness implements SerializableWitness { void innerSerialize(PluginWitness witness, JsonGenerator gen, SerializerProvider provider) throws IOException { MetricSerializer> stringSerializer = MetricSerializer.Get.stringSerializer(gen); + MetricSerializer> longSerializer = MetricSerializer.Get.longSerializer(gen); stringSerializer.serialize(witness.id); witness.events().genJson(gen, provider); stringSerializer.serialize(witness.name); + for (GaugeMetric gauge : witness.customWitness.gauges.values()) { + gen.writeObjectField(gauge.getName(), gauge.getValue()); + } + for (CounterMetric counter : witness.customWitness.counters.values()) { + longSerializer.serialize(counter); + } + } + } + + /** + * A custom witness that we can hand off to plugin's to contribute to the metrics + */ + public class CustomWitness { + + private final Snitch snitch; + + /** + * private Constructor - not for external instantiation + */ + private CustomWitness() { + this.snitch = new Snitch(this); + } + + private final Map> gauges = new ConcurrentHashMap<>(); + private final Map> counters = new ConcurrentHashMap<>(); + + /** + * Set that gauge value + * + * @param key the {@link RubySymbol} for the key of this gauge. Note - internally this will be converted to a {@link String} + * @param value The value of the Gauge. This allows for any {@link Object} type, unless text or numeric type, there is no guarantees of proper serialization. + */ + public void gauge(RubySymbol key, Object value) { + gauge(key.asJavaString(), value); + } + + /** + * Set that gauge value + * + * @param key the {@link String} for the key of this gauge. Note - internally this will be converted to a {@link String} + * @param value The value of the Gauge. This allows for any {@link Object} type, unless text or numeric type, there is no guarantees of proper serialization. + */ + public void gauge(String key, Object value) { + GaugeMetric gauge = gauges.get(key); + if (gauge != null) { + gauge.set(value); + } else { + gauge = new LazyDelegatingGauge(key, value); + gauges.put(key, gauge); + } + } + + /** + * Increments the underlying counter for this {@link RubySymbol} by 1. + * + * @param key the {@link RubySymbol} key of the counter to increment. Note - internally this will be converted to a {@link String} + */ + public void increment(RubySymbol key) { + increment(key.asJavaString()); + } + + /** + * Increments the underlying counter for this {@link RubySymbol} by 1. + * + * @param key the {@link String} key of the counter to increment. Note - internally this will be converted to a {@link String} + */ + public void increment(String key) { + increment(key, 1); + } + + /** + * Increments the underlying counter for this {@link RubySymbol} by the given value. + * + * @param key the {@link RubySymbol} key of the counter to increment. Note - internally this will be converted to a {@link String} + * @param by the amount to increment by + */ + public void increment(RubySymbol key, long by) { + increment(key.asJavaString(), by); + } + + /** + * Increments the underlying counter for this {@link RubySymbol} by the given value. + * + * @param key the {@link String} key of the counter to increment. Note - internally this will be converted to a {@link String} + * @param by the amount to increment by + */ + public void increment(String key, long by) { + CounterMetric counter = counters.get(key); + if (counter != null) { + counter.increment(by); + } else { + counter = new LongCounter(key); + counter.increment(); + counters.put(key, counter); + } + } + + /** + * Get a reference to associated snitch to get discrete metric values. + * + * @return the associate {@link Snitch} + */ + public Snitch snitch() { + return snitch; + } + + /** + * Snitch for a plugin. Provides discrete metric values. + */ + public class Snitch { + + private final CustomWitness witness; + + /** + * Construtor + * + * @param witness the witness + */ + private Snitch(CustomWitness witness) { + this.witness = witness; + } + + /** + * Get the underlying {@link GaugeMetric}. May call {@link GaugeMetric#getType()} to get the underlying type. + * + * @param key the key/name of the {@link GaugeMetric}. + * @return the {@link GaugeMetric} May return {@code null} + */ + public GaugeMetric gauge(String key) { + return witness.gauges.get(key); + } + + /** + * Gets the full set of custom {@link GaugeMetric} + * + * @return the map of all of the {@link GaugeMetric}, keyed by the associated {@link GaugeMetric} key/name + */ + public Map> gauges() { + return Collections.unmodifiableMap(witness.gauges); + } + + /** + * Get the custom Counter. May call {@link CounterMetric#getType()} to get the underlying type. + * + * @param key the key/name of the {@link CounterMetric} + * @return the {@link CounterMetric} for the given key. May return {@code null} + */ + public CounterMetric counter(String key) { + return witness.counters.get(key); + } + + /** + * Gets the full set of the custom {@link CounterMetric} + * + * @return the map of all of the {@link CounterMetric}, keyed by the associated {@link CounterMetric} key/name + */ + public Map> counters() { + return Collections.unmodifiableMap(witness.counters); + } } } diff --git a/logstash-core/src/main/java/org/logstash/instrument/witness/PluginsWitness.java b/logstash-core/src/main/java/org/logstash/instrument/witness/PluginsWitness.java index 2efdd629f..5fb9446ff 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/witness/PluginsWitness.java +++ b/logstash-core/src/main/java/org/logstash/instrument/witness/PluginsWitness.java @@ -27,7 +27,6 @@ public class PluginsWitness implements SerializableWitness { * Constructor. */ public PluginsWitness() { - this.inputs = new ConcurrentHashMap<>(); this.outputs = new ConcurrentHashMap<>(); this.filters = new ConcurrentHashMap<>(); diff --git a/logstash-core/src/main/java/org/logstash/instrument/witness/QueueWitness.java b/logstash-core/src/main/java/org/logstash/instrument/witness/QueueWitness.java index 61b1dcf92..13f8a8caf 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/witness/QueueWitness.java +++ b/logstash-core/src/main/java/org/logstash/instrument/witness/QueueWitness.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import org.logstash.instrument.metrics.Metric; -import org.logstash.instrument.metrics.gauge.LongGauge; +import org.logstash.instrument.metrics.gauge.NumberGauge; import org.logstash.instrument.metrics.gauge.TextGauge; import java.io.IOException; @@ -17,7 +17,7 @@ import java.io.IOException; final public class QueueWitness implements SerializableWitness { private final TextGauge type; - private final LongGauge events; // note this is NOT an EventsWitness + private final NumberGauge events; // note this is NOT an EventsWitness private final Snitch snitch; private final CapacityWitness capacity; private final DataWitness data; @@ -29,7 +29,7 @@ final public class QueueWitness implements SerializableWitness { */ public QueueWitness() { type = new TextGauge("type"); - events = new LongGauge("events"); + events = new NumberGauge("events"); snitch = new Snitch(this); capacity = new CapacityWitness(); data = new DataWitness(); @@ -90,19 +90,19 @@ final public class QueueWitness implements SerializableWitness { */ public class CapacityWitness { - private final LongGauge queueSizeInBytes; - private final LongGauge pageCapacityInBytes; - private final LongGauge maxQueueSizeInBytes; - private final LongGauge maxUnreadEvents; + private final NumberGauge queueSizeInBytes; + private final NumberGauge pageCapacityInBytes; + private final NumberGauge maxQueueSizeInBytes; + private final NumberGauge maxUnreadEvents; private final Snitch snitch; private final static String KEY = "capacity"; private CapacityWitness() { - queueSizeInBytes = new LongGauge("queue_size_in_bytes"); - pageCapacityInBytes = new LongGauge("page_capacity_in_bytes"); - maxQueueSizeInBytes = new LongGauge("max_queue_size_in_bytes"); - maxUnreadEvents = new LongGauge("max_unread_events"); + queueSizeInBytes = new NumberGauge("queue_size_in_bytes"); + pageCapacityInBytes = new NumberGauge("page_capacity_in_bytes"); + maxQueueSizeInBytes = new NumberGauge("max_queue_size_in_bytes"); + maxUnreadEvents = new NumberGauge("max_unread_events"); snitch = new Snitch(this); } @@ -167,7 +167,7 @@ final public class QueueWitness implements SerializableWitness { * * @return the queue size in bytes. May be {@code null} */ - public Long queueSizeInBytes() { + public Number queueSizeInBytes() { return witness.queueSizeInBytes.getValue(); } @@ -176,7 +176,7 @@ final public class QueueWitness implements SerializableWitness { * * @return the page queue capacity. */ - public Long pageCapacityInBytes() { + public Number pageCapacityInBytes() { return witness.pageCapacityInBytes.getValue(); } @@ -185,7 +185,7 @@ final public class QueueWitness implements SerializableWitness { * * @return the max queue size. */ - public Long maxQueueSizeInBytes() { + public Number maxQueueSizeInBytes() { return witness.maxQueueSizeInBytes.getValue(); } @@ -194,7 +194,7 @@ final public class QueueWitness implements SerializableWitness { * * @return the max unread events. */ - public Long maxUnreadEvents() { + public Number maxUnreadEvents() { return witness.maxUnreadEvents.getValue(); } @@ -207,7 +207,7 @@ final public class QueueWitness implements SerializableWitness { public class DataWitness { private final TextGauge path; - private final LongGauge freeSpaceInBytes; + private final NumberGauge freeSpaceInBytes; private final TextGauge storageType; private final Snitch snitch; private final static String KEY = "data"; @@ -215,7 +215,7 @@ final public class QueueWitness implements SerializableWitness { private DataWitness() { path = new TextGauge("path"); - freeSpaceInBytes = new LongGauge("free_space_in_bytes"); + freeSpaceInBytes = new NumberGauge("free_space_in_bytes"); storageType = new TextGauge("storage_type"); snitch = new Snitch(this); } @@ -281,7 +281,7 @@ final public class QueueWitness implements SerializableWitness { * * @return the free space of the queue */ - public Long freeSpaceInBytes() { + public Number freeSpaceInBytes() { return witness.freeSpaceInBytes.getValue(); } @@ -326,22 +326,22 @@ final public class QueueWitness implements SerializableWitness { void innerSerialize(QueueWitness witness, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeObjectFieldStart(KEY); - MetricSerializer> longSerializer = MetricSerializer.Get.longSerializer(gen); + MetricSerializer> numberSerializer = MetricSerializer.Get.numberSerializer(gen); MetricSerializer> stringSerializer = MetricSerializer.Get.stringSerializer(gen); stringSerializer.serialize(witness.type); if ("persisted".equals(witness.type.getValue())) { - longSerializer.serialize(witness.events); + numberSerializer.serialize(witness.events); //capacity gen.writeObjectFieldStart(CapacityWitness.KEY); - longSerializer.serialize(witness.capacity.queueSizeInBytes); - longSerializer.serialize(witness.capacity.pageCapacityInBytes); - longSerializer.serialize(witness.capacity.maxQueueSizeInBytes); - longSerializer.serialize(witness.capacity.maxUnreadEvents); + numberSerializer.serialize(witness.capacity.queueSizeInBytes); + numberSerializer.serialize(witness.capacity.pageCapacityInBytes); + numberSerializer.serialize(witness.capacity.maxQueueSizeInBytes); + numberSerializer.serialize(witness.capacity.maxUnreadEvents); gen.writeEndObject(); //data gen.writeObjectFieldStart(DataWitness.KEY); stringSerializer.serialize(witness.data.path); - longSerializer.serialize(witness.data.freeSpaceInBytes); + numberSerializer.serialize(witness.data.freeSpaceInBytes); stringSerializer.serialize(witness.data.storageType); gen.writeEndObject(); } @@ -375,7 +375,7 @@ final public class QueueWitness implements SerializableWitness { * * @return the count of events in the queue. {@code null} */ - public Long events() { + public Number events() { return witness.events.getValue(); } } diff --git a/logstash-core/src/test/java/org/logstash/instrument/metrics/MetricTypeTest.java b/logstash-core/src/test/java/org/logstash/instrument/metrics/MetricTypeTest.java index 88740c1a6..4e95c74b4 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/metrics/MetricTypeTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/metrics/MetricTypeTest.java @@ -24,8 +24,7 @@ public class MetricTypeTest { nameMap.put(MetricType.COUNTER_LONG, "counter/long"); nameMap.put(MetricType.GAUGE_TEXT, "gauge/text"); nameMap.put(MetricType.GAUGE_BOOLEAN, "gauge/boolean"); - nameMap.put(MetricType.GAUGE_LONG, "gauge/long"); - nameMap.put(MetricType.GAUGE_DOUBLE, "gauge/double"); + nameMap.put(MetricType.GAUGE_NUMBER, "gauge/number"); nameMap.put(MetricType.GAUGE_UNKNOWN, "gauge/unknown"); nameMap.put(MetricType.GAUGE_RUBYHASH, "gauge/rubyhash"); nameMap.put(MetricType.GAUGE_RUBYTIMESTAMP, "gauge/rubytimestamp"); diff --git a/logstash-core/src/test/java/org/logstash/instrument/metrics/counter/LongCounterTest.java b/logstash-core/src/test/java/org/logstash/instrument/metrics/counter/LongCounterTest.java index 1a1a1bb4f..1fa1e5c49 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/metrics/counter/LongCounterTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/metrics/counter/LongCounterTest.java @@ -8,7 +8,6 @@ import java.util.Collections; import static org.assertj.core.api.Assertions.assertThat; - /** * Unit tests for {@link LongCounter} */ diff --git a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/DoubleGaugeTest.java b/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/DoubleGaugeTest.java deleted file mode 100644 index 6a2184693..000000000 --- a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/DoubleGaugeTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.logstash.instrument.metrics.gauge; - -import org.junit.Test; -import org.logstash.instrument.metrics.MetricType; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link DoubleGauge} - */ -public class DoubleGaugeTest { - - @Test - public void getValue() { - DoubleGauge gauge = new DoubleGauge("bar", 123.0); - assertThat(gauge.getValue()).isEqualTo(123.0); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_DOUBLE); - - //Null - gauge = new DoubleGauge("bar"); - assertThat(gauge.getValue()).isNull(); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_DOUBLE); - } - - @Test - public void set() { - DoubleGauge gauge = new DoubleGauge("bar"); - assertThat(gauge.getValue()).isNull(); - gauge.set(123.0); - assertThat(gauge.getValue()).isEqualTo(123.0); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_DOUBLE); - } -} \ No newline at end of file diff --git a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGaugeTest.java b/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGaugeTest.java index 88f0ae057..9a428dba4 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGaugeTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LazyDelegatingGaugeTest.java @@ -42,43 +42,43 @@ public class LazyDelegatingGaugeTest { @Test public void getValue() { //Long - LazyDelegatingGauge gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", 99l); + LazyDelegatingGauge gauge = new LazyDelegatingGauge("bar", 99l); assertThat(gauge.getValue()).isEqualTo(99l); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_LONG); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); //Double - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", 99.0); + gauge = new LazyDelegatingGauge("bar", 99.0); assertThat(gauge.getValue()).isEqualTo(99.0); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_DOUBLE); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); //Boolean - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", true); + gauge = new LazyDelegatingGauge("bar", true); assertThat(gauge.getValue()).isEqualTo(true); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_BOOLEAN); //Text - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", "something"); + gauge = new LazyDelegatingGauge("bar", "something"); assertThat(gauge.getValue()).isEqualTo("something"); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_TEXT); //Ruby Hash - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", rubyHash); + gauge = new LazyDelegatingGauge("bar", rubyHash); assertThat(gauge.getValue().toString()).isEqualTo(RUBY_HASH_AS_STRING); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_RUBYHASH); //Ruby Timestamp - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", rubyTimestamp); + gauge = new LazyDelegatingGauge("bar", rubyTimestamp); assertThat(gauge.getValue()).isEqualTo(timestamp); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_RUBYTIMESTAMP); //Unknown - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar", Collections.singleton("value")); + gauge = new LazyDelegatingGauge("bar", Collections.singleton("value")); assertThat(gauge.getValue()).isEqualTo(Collections.singleton("value")); assertThat(gauge.getValue()).isEqualTo(gauge.get()); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_UNKNOWN); //Null - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); assertThat(gauge.getValue()).isNull(); assertThat(gauge.get()).isNull(); assertThat(gauge.getType()).isNull(); @@ -87,23 +87,31 @@ public class LazyDelegatingGaugeTest { @Test public void set() { //Long - LazyDelegatingGauge gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + LazyDelegatingGauge gauge = new LazyDelegatingGauge("bar"); gauge.set(99l); assertThat(gauge.getValue()).isEqualTo(99l); gauge.set(199l); assertThat(gauge.getValue()).isEqualTo(199l); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_LONG); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); + + //Integer + gauge = new LazyDelegatingGauge("bar"); + gauge.set(99); + assertThat(gauge.getValue()).isEqualTo(99); + gauge.set(199); + assertThat(gauge.getValue()).isEqualTo(199); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); //Double - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set(99.0); assertThat(gauge.getValue()).isEqualTo(99.0); gauge.set(199.01); assertThat(gauge.getValue()).isEqualTo(199.01); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_DOUBLE); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); //Boolean - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set(true); assertThat(gauge.getValue()).isEqualTo(true); gauge.set(false); @@ -111,7 +119,7 @@ public class LazyDelegatingGaugeTest { assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_BOOLEAN); //Text - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set("something"); assertThat(gauge.getValue()).isEqualTo("something"); gauge.set("something else"); @@ -119,19 +127,19 @@ public class LazyDelegatingGaugeTest { assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_TEXT); //Ruby Hash - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set(rubyHash); assertThat(gauge.getValue().toString()).isEqualTo(RUBY_HASH_AS_STRING); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_RUBYHASH); //Ruby Timestamp - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set(rubyTimestamp); assertThat(gauge.getValue()).isEqualTo(timestamp); assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_RUBYTIMESTAMP); //Unknown - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set(Collections.singleton("value")); assertThat(gauge.getValue()).isEqualTo(Collections.singleton("value")); gauge.set(URI.create("foo")); //please don't change the type of gauge after already set @@ -139,13 +147,13 @@ public class LazyDelegatingGaugeTest { assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_UNKNOWN); //Null - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set(null); assertThat(gauge.getValue()).isNull(); assertThat(gauge.getType()).isNull(); //Valid, then Null - gauge = new LazyDelegatingGauge(Collections.singletonList("foo"), "bar"); + gauge = new LazyDelegatingGauge("bar"); gauge.set("something"); assertThat(gauge.getValue()).isEqualTo("something"); gauge.set(null); diff --git a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LongGaugeTest.java b/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LongGaugeTest.java deleted file mode 100644 index 02204d6f9..000000000 --- a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/LongGaugeTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.logstash.instrument.metrics.gauge; - -import org.junit.Test; -import org.logstash.instrument.metrics.MetricType; - -import static org.assertj.core.api.Assertions.assertThat; - - -/** - * Unit tests for {@link LongGauge} - */ -public class LongGaugeTest { - - @Test - public void getValue() { - LongGauge gauge = new LongGauge("bar", 99l); - assertThat(gauge.getValue()).isEqualTo(99); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_LONG); - - //Null - gauge = new LongGauge("bar"); - assertThat(gauge.getValue()).isNull(); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_LONG); - } - - @Test - public void set() { - LongGauge gauge = new LongGauge("bar"); - assertThat(gauge.getValue()).isNull(); - gauge.set(123l); - assertThat(gauge.getValue()).isEqualTo(123); - assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_LONG); - } -} \ No newline at end of file diff --git a/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/NumberGaugeTest.java b/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/NumberGaugeTest.java new file mode 100644 index 000000000..2b6f0c233 --- /dev/null +++ b/logstash-core/src/test/java/org/logstash/instrument/metrics/gauge/NumberGaugeTest.java @@ -0,0 +1,37 @@ +package org.logstash.instrument.metrics.gauge; + +import org.junit.Test; +import org.logstash.instrument.metrics.MetricType; + +import static org.assertj.core.api.Assertions.assertThat; + + +/** + * Unit tests for {@link NumberGauge} + */ +public class NumberGaugeTest { + + @Test + public void getValue() { + NumberGauge gauge = new NumberGauge("bar", 99l); + assertThat(gauge.getValue()).isEqualTo(99l); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); + //other number type + gauge.set(98.00); + assertThat(gauge.getValue()).isEqualTo(98.00); + + //Null + gauge = new NumberGauge("bar"); + assertThat(gauge.getValue()).isNull(); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); + } + + @Test + public void set() { + NumberGauge gauge = new NumberGauge("bar"); + assertThat(gauge.getValue()).isNull(); + gauge.set(123l); + assertThat(gauge.getValue()).isEqualTo(123l); + assertThat(gauge.getType()).isEqualTo(MetricType.GAUGE_NUMBER); + } +} \ No newline at end of file diff --git a/logstash-core/src/test/java/org/logstash/instrument/witness/ConfigWitnessTest.java b/logstash-core/src/test/java/org/logstash/instrument/witness/ConfigWitnessTest.java index bc2a7748c..b1f93f0fc 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/witness/ConfigWitnessTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/witness/ConfigWitnessTest.java @@ -23,14 +23,14 @@ public class ConfigWitnessTest { public void testBatchDelay() { assertThat(witness.snitch().batchDelay()).isNull(); witness.batchDelay(99); - assertThat(witness.snitch().batchDelay()).isEqualTo(99); + assertThat(witness.snitch().batchDelay()).isEqualTo(99l); } @Test public void testBatchSize() { assertThat(witness.snitch().batchSize()).isNull(); witness.batchSize(98); - assertThat(witness.snitch().batchSize()).isEqualTo(98); + assertThat(witness.snitch().batchSize()).isEqualTo(98l); } @Test @@ -46,7 +46,7 @@ public class ConfigWitnessTest { public void testConfigReloadInterval() { assertThat(witness.snitch().configReloadInterval()).isNull(); witness.configReloadInterval(97); - assertThat(witness.snitch().configReloadInterval()).isEqualTo(97); + assertThat(witness.snitch().configReloadInterval()).isEqualTo(97l); } @Test @@ -69,7 +69,7 @@ public class ConfigWitnessTest { public void testWorkers() { assertThat(witness.snitch().workers()).isNull(); witness.workers(96); - assertThat(witness.snitch().workers()).isEqualTo(96); + assertThat(witness.snitch().workers()).isEqualTo(96l); } @Test diff --git a/logstash-core/src/test/java/org/logstash/instrument/witness/DeadLetterQueueWitnessTest.java b/logstash-core/src/test/java/org/logstash/instrument/witness/DeadLetterQueueWitnessTest.java index b4389cac5..fc480e95d 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/witness/DeadLetterQueueWitnessTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/witness/DeadLetterQueueWitnessTest.java @@ -23,7 +23,7 @@ public class DeadLetterQueueWitnessTest { public void queueSizeInBytes() { assertThat(witness.snitch().queueSizeInBytes()).isNull(); witness.queueSizeInBytes(99); - assertThat(witness.snitch().queueSizeInBytes()).isEqualTo(99); + assertThat(witness.snitch().queueSizeInBytes()).isEqualTo(99l); } @Test diff --git a/logstash-core/src/test/java/org/logstash/instrument/witness/ErrorWitnessTest.java b/logstash-core/src/test/java/org/logstash/instrument/witness/ErrorWitnessTest.java index 15259f3c9..1d9724b06 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/witness/ErrorWitnessTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/witness/ErrorWitnessTest.java @@ -3,7 +3,6 @@ package org.logstash.instrument.witness; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; -import org.logstash.instrument.metrics.gauge.LongGauge; import static org.assertj.core.api.Assertions.assertThat; diff --git a/logstash-core/src/test/java/org/logstash/instrument/witness/PluginWitnessTest.java b/logstash-core/src/test/java/org/logstash/instrument/witness/PluginWitnessTest.java index 9ae3c4877..8f4576e90 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/witness/PluginWitnessTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/witness/PluginWitnessTest.java @@ -2,8 +2,16 @@ package org.logstash.instrument.witness; import com.fasterxml.jackson.databind.ObjectMapper; +import org.jruby.RubySymbol; import org.junit.Before; import org.junit.Test; +import org.logstash.RubyUtil; +import org.logstash.instrument.metrics.MetricType; + +import java.io.IOException; +import java.math.BigDecimal; +import java.net.URI; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -15,19 +23,73 @@ public class PluginWitnessTest { private PluginWitness witness; @Before - public void setup(){ + public void setup() { witness = new PluginWitness("123"); assertThat(witness.snitch().id()).isEqualTo("123"); } @Test - public void testName(){ + public void testName() { assertThat(witness.name("abc")).isEqualTo(witness); assertThat(witness.snitch().name()).isEqualTo("abc"); } @Test - public void testEvents(){ + public void testCustomGauge() { + witness.custom().gauge("a", "foo"); + witness.custom().gauge("b", 1); + witness.custom().gauge("c", true); + witness.custom().gauge("d", URI.create("unknown")); + assertThat(witness.custom().snitch().gauges().size()).isEqualTo(4); + assertThat(witness.custom().snitch().gauge("a").getValue()).isEqualTo("foo"); + assertThat(witness.custom().snitch().gauge("a").getType()).isEqualTo(MetricType.GAUGE_TEXT); + assertThat(witness.custom().snitch().gauge("b").getValue()).isEqualTo(1); + assertThat(witness.custom().snitch().gauge("b").getType()).isEqualTo(MetricType.GAUGE_NUMBER); + assertThat(witness.custom().snitch().gauge("c").getValue()).isEqualTo(Boolean.TRUE); + assertThat(witness.custom().snitch().gauge("c").getType()).isEqualTo(MetricType.GAUGE_BOOLEAN); + assertThat(witness.custom().snitch().gauge("d").getValue()).isEqualTo(URI.create("unknown")); + assertThat(witness.custom().snitch().gauge("d").getType()).isEqualTo(MetricType.GAUGE_UNKNOWN); + } + + @Test + public void testCustomCounter(){ + witness.custom().increment("foo"); + witness.custom().increment("bar"); + + assertThat(witness.custom().snitch().counters().size()).isEqualTo(2); + assertThat(witness.custom().snitch().counters().values().stream().allMatch(v -> MetricType.COUNTER_LONG.equals(v.getType()))).isTrue(); + assertThat(witness.custom().snitch().counter("foo").getValue()).isEqualTo(1l); + assertThat(witness.custom().snitch().counter("bar").getValue()).isEqualTo(1l); + witness.custom().increment("foo"); + witness.custom().increment("foo"); + witness.custom().increment("bar"); + assertThat(witness.custom().snitch().counter("foo").getValue()).isEqualTo(3l); + assertThat(witness.custom().snitch().counter("bar").getValue()).isEqualTo(2l); + } + + @Test + public void testRubySymbol() throws IOException { + RubySymbol symbol = RubySymbol.newSymbol(RubyUtil.RUBY, "mysymbol"); + witness.custom().increment(symbol); + witness.custom().increment(symbol, 99); + assertThat(witness.custom().snitch().counter("mysymbol").getValue()).isEqualTo(100l); + + witness.custom().gauge(symbol, "blah"); + assertThat(witness.custom().snitch().gauge("mysymbol").getValue()).isEqualTo("blah"); + witness.custom().gauge(symbol, "blah2"); + assertThat(witness.custom().snitch().gauge("mysymbol").getValue()).isEqualTo("blah2"); + } + + @Test + public void testCustomNotSet(){ + assertThat(witness.custom().snitch().counter("nothing")).isNull(); + assertThat(witness.custom().snitch().gauge("nothing")).isNull(); + assertThat(witness.custom().snitch().gauges()).isEmpty(); + assertThat(witness.custom().snitch().counters()).isEmpty(); + } + + @Test + public void testEvents() { assertThat(witness.events()).isNotNull(); } @@ -56,4 +118,52 @@ public class PluginWitnessTest { String json = witness.asJson(); assertThat(json).isEqualTo("{\"id\":\"123\",\"events\":{\"duration_in_millis\":0,\"in\":1,\"out\":0,\"filtered\":0,\"queue_push_duration_in_millis\":0},\"name\":null}"); } + + @Test + public void testSerializationCustomCounter() throws Exception { + witness.custom().increment("a"); + witness.custom().increment("a"); + witness.custom().increment("b"); + + String json = witness.asJson(); + assertThat(json).isEqualTo("{\"id\":\"123\",\"events\":{\"duration_in_millis\":0,\"in\":0,\"out\":0,\"filtered\":0,\"queue_push_duration_in_millis\":0},\"name\":null," + + "\"a\":2,\"b\":1}"); + } + + @Test + public void testSerializationCustomGauge() throws Exception { + witness.custom().gauge("a", "foo"); + witness.custom().gauge("b", 1); + witness.custom().gauge("c", true); + + String json = witness.asJson(); + assertThat(json).isEqualTo("{\"id\":\"123\",\"events\":{\"duration_in_millis\":0,\"in\":0,\"out\":0,\"filtered\":0,\"queue_push_duration_in_millis\":0},\"name\":null," + + "\"a\":\"foo\",\"b\":1,\"c\":true}"); + } + + @Test + public void testSerializationCustomGaugeNumericTypes() throws Exception { + short a = 1; + int b = 1; + float c = 1; + double d = 1; + BigDecimal e = new BigDecimal(1); + + witness.custom().gauge("a", a); + witness.custom().gauge("b", b); + witness.custom().gauge("c", c); + witness.custom().gauge("d", d); + witness.custom().gauge("e", e); + + String json = witness.asJson(); + assertThat(json).isEqualTo("{\"id\":\"123\",\"events\":{\"duration_in_millis\":0,\"in\":0,\"out\":0,\"filtered\":0,\"queue_push_duration_in_millis\":0},\"name\":null," + + "\"a\":1,\"b\":1,\"c\":1.0,\"d\":1.0,\"e\":1}"); + } + + @Test(expected = IllegalStateException.class) + public void testSerializationUnknownCustomGauge() throws Exception { + //There are not default Jackson serializers for UUID + witness.custom().gauge("a", UUID.randomUUID()); + witness.asJson(); + } } \ No newline at end of file diff --git a/logstash-core/src/test/java/org/logstash/instrument/witness/QueueWitnessTest.java b/logstash-core/src/test/java/org/logstash/instrument/witness/QueueWitnessTest.java index 5bb01804b..4b46d9a72 100644 --- a/logstash-core/src/test/java/org/logstash/instrument/witness/QueueWitnessTest.java +++ b/logstash-core/src/test/java/org/logstash/instrument/witness/QueueWitnessTest.java @@ -1,6 +1,5 @@ package org.logstash.instrument.witness; - import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Before; import org.junit.Test; @@ -29,31 +28,31 @@ public class QueueWitnessTest { public void testEvents() { assertThat(witness.snitch().events()).isNull(); witness.events(101); - assertThat(witness.snitch().events()).isEqualTo(101); + assertThat(witness.snitch().events()).isEqualTo(101l); } @Test public void testQueueSizeInBytes(){ witness.capacity().queueSizeInBytes(99); - assertThat(witness.capacity().snitch().queueSizeInBytes()).isEqualTo(99); + assertThat(witness.capacity().snitch().queueSizeInBytes()).isEqualTo(99l); } @Test public void testPageCapacityInBytes(){ witness.capacity().pageCapacityInBytes(98); - assertThat(witness.capacity().snitch().pageCapacityInBytes()).isEqualTo(98); + assertThat(witness.capacity().snitch().pageCapacityInBytes()).isEqualTo(98l); } @Test public void testMaxQueueSizeInBytes(){ witness.capacity().maxQueueSizeInBytes(97); - assertThat(witness.capacity().snitch().maxQueueSizeInBytes()).isEqualTo(97); + assertThat(witness.capacity().snitch().maxQueueSizeInBytes()).isEqualTo(97l); } @Test public void testMaxUnreadEvents(){ witness.capacity().maxUnreadEvents(96); - assertThat(witness.capacity().snitch().maxUnreadEvents()).isEqualTo(96); + assertThat(witness.capacity().snitch().maxUnreadEvents()).isEqualTo(96l); } @Test @@ -65,7 +64,7 @@ public class QueueWitnessTest { @Test public void testFreeSpace(){ witness.data().freeSpaceInBytes(77); - assertThat(witness.data().snitch().freeSpaceInBytes()).isEqualTo(77); + assertThat(witness.data().snitch().freeSpaceInBytes()).isEqualTo(77l); } @Test