From ed694564c38fd544c2a1401e6847da5d8b6bccad Mon Sep 17 00:00:00 2001 From: Ankit Bhargava Date: Mon, 27 Jul 2020 10:55:04 -0400 Subject: [PATCH] Add Metric Instruments API (#161) --- .../opentelemetry/metrics/async_instruments.h | 87 +++++ .../opentelemetry/metrics/instrument.h | 204 ++++++++++ api/include/opentelemetry/metrics/noop.h | 366 +++++++++++++++++- .../opentelemetry/metrics/observer_result.h | 36 ++ .../opentelemetry/metrics/sync_instruments.h | 172 ++++++++ api/test/metrics/BUILD | 12 + api/test/metrics/CMakeLists.txt | 2 +- api/test/metrics/noop_instrument_test.cc | 185 +++++++++ 8 files changed, 1061 insertions(+), 3 deletions(-) create mode 100644 api/include/opentelemetry/metrics/async_instruments.h create mode 100644 api/include/opentelemetry/metrics/instrument.h create mode 100644 api/include/opentelemetry/metrics/observer_result.h create mode 100644 api/include/opentelemetry/metrics/sync_instruments.h create mode 100644 api/test/metrics/noop_instrument_test.cc diff --git a/api/include/opentelemetry/metrics/async_instruments.h b/api/include/opentelemetry/metrics/async_instruments.h new file mode 100644 index 00000000000..71504a8480b --- /dev/null +++ b/api/include/opentelemetry/metrics/async_instruments.h @@ -0,0 +1,87 @@ +#pragma once + +#include "instrument.h" +#include "observer_result.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +template +class ValueObserver : virtual public AsynchronousInstrument +{ + +public: + ValueObserver() = default; + + ValueObserver(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled, + void (*callback)(ObserverResult)) + {} + + /* + * Updates the instruments aggregator with the new value. The labels should + * contain the keys and values to be associated with this value. + * + * @param value is the numerical representation of the metric being captured + * @param labels the set of labels, as key-value pairs + */ + virtual void observe(T value, const trace::KeyValueIterable &labels) override = 0; + + /** + * Captures data by activating the callback function associated with the + * instrument and storing its return value. Callbacks for asynchronous + * instruments are defined during construction. + * + * @param none + * @return none + */ + virtual void run () override = 0; + +}; + +template +class SumObserver : virtual public AsynchronousInstrument +{ + +public: + SumObserver() = default; + + SumObserver(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled, + void (*callback)(ObserverResult)) + {} + + + virtual void observe(T value, const trace::KeyValueIterable &labels) override = 0; + + virtual void run() override = 0; + +}; + +template +class UpDownSumObserver : virtual public AsynchronousInstrument +{ + +public: + UpDownSumObserver() = default; + + UpDownSumObserver(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled, + void (*callback)(ObserverResult)) + {} + + virtual void observe(T value, const trace::KeyValueIterable &labels) override = 0; + + virtual void run() override = 0; + +}; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/instrument.h b/api/include/opentelemetry/metrics/instrument.h new file mode 100644 index 00000000000..9728bab8bb5 --- /dev/null +++ b/api/include/opentelemetry/metrics/instrument.h @@ -0,0 +1,204 @@ +#pragma once + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/trace/key_value_iterable_view.h" +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +// Enum classes to help determine instrument types in other parts of the API +enum class InstrumentKind +{ + Counter = 0, + UpDownCounter = 1, + ValueRecorder = 2, + ValueObserver = 3, + SumObserver = 4, + UpDownSumObserver = 5, +}; + +class Instrument +{ + +public: + // Note that Instruments should be created using the Meter class. + // Please refer to meter.h for documentation. + Instrument() = default; + + /** + * Base class constructor for all other instrument types. Whether or not + * an instrument is synchronous or bound, it requires a name, description, + * unit, and enabled flag. + * + * @param name is the identifier of the instrumenting library + * @param description explains what the metric captures + * @param unit specifies the data type held in the instrument + * @param enabled determines if the metric is currently capturing data + * @return Instrument type with the specified attirbutes + */ + Instrument(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled) + {} + + // Returns true if the instrument is enabled and collecting data + virtual bool IsEnabled() = 0; + + // Return the instrument name + virtual nostd::string_view GetName() = 0; + + // Return the instrument description + virtual nostd::string_view GetDescription() = 0; + + // Return the insrument's units of measurement + virtual nostd::string_view GetUnits() = 0; + + // Return the intrument's kind + virtual InstrumentKind GetKind() = 0; + + virtual ~Instrument() = default; +}; + +template +class BoundSynchronousInstrument : virtual public Instrument +{ + +public: + BoundSynchronousInstrument() = default; + + BoundSynchronousInstrument(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled); + + /** + * Frees the resources associated with this Bound Instrument. + * The Metric from which this instrument was created is not impacted. + * + * @param none + * @return void + */ + virtual void unbind() {} + + /** + * Incremements the reference count of this bound object when a new instance is + * either created or the same instance is returned as a result of binding + * + * @param none + * @return void + */ + virtual void inc_ref () {} + + /** + * Return the object's current reference count. This information is used to remove + * stale objects from instrument registries. + */ + virtual int get_ref() { + return 0; + } + + /** + * Records a single synchronous metric event; a call to the aggregator + * Since this is a bound synchronous instrument, labels are not required in * metric capture + * calls. + * + * @param value is the numerical representation of the metric being captured + * @return void + */ + virtual void update(T value) {} +}; + +template +class SynchronousInstrument : virtual public Instrument +{ + +public: + SynchronousInstrument() = default; + + SynchronousInstrument(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled) + { } + + /** + * Returns a Bound Instrument associated with the specified labels. * Multiples requests + * with the same set of labels may return the same Bound Instrument instance. + * + * It is recommended that callers keep a reference to the Bound Instrument + * instead of repeatedly calling this operation. + * + * @param labels the set of labels, as key-value pairs + * @return a Bound Instrument + */ + virtual nostd::shared_ptr> bind(const trace::KeyValueIterable &labels) { + return nostd::shared_ptr>(); + } + + /** + * Records a single synchronous metric event. + * Since this is an unbound synchronous instrument, labels are required in * metric capture + * calls. + * + * update can be used in instruments with both add or record since it simply + * activated the aggregator + * + * @param labels the set of labels, as key-value pairs + * @param value is the numerical representation of the metric being captured + * @return void + */ + virtual void update(T value, const trace::KeyValueIterable &labels) = 0; +}; + +template +class ObserverResult; + +template +class AsynchronousInstrument : virtual public Instrument +{ + +public: + AsynchronousInstrument() = default; + + AsynchronousInstrument(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled, + void(callback)(ObserverResult)) + {} + + /** + * Captures data through a manual call rather than the automatic collection process instituted + * in the run function. Asynchronous instruments are generally expected to obtain data from + * their callbacks rather than direct calls. This function is used by the callback to store data. + * + * @param value is the numerical representation of the metric being captured + * @param labels is the numerical representation of the metric being captured + * @return none + */ + virtual void observe (T value, const trace::KeyValueIterable &labels) = 0; + + /** + * Captures data by activating the callback function associated with the + * instrument and storing its return value. Callbacks for asynchronous + * instruments are defined during construction. + * + * @param none + * @return none + */ + virtual void run() = 0; + +protected: + // Callback function which takes a pointer to an Asynchronous instrument (this) type which is + // stored in an observer result type and returns nothing. This function calls the instrument's + // observe. + void (*callback_)(ObserverResult); +}; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index a53a591232a..36952774100 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -4,14 +4,18 @@ // This file is part of the internal implementation of OpenTelemetry. Nothing in this file should be // used directly. Please refer to meter.h for documentation on these interfaces. +#include "opentelemetry/version.h" +#include "opentelemetry/metrics/instrument.h" #include "opentelemetry/metrics/meter.h" #include "opentelemetry/metrics/meter_provider.h" +#include "opentelemetry/metrics/sync_instruments.h" +#include "opentelemetry/metrics/async_instruments.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/unique_ptr.h" -#include "opentelemetry/version.h" #include + OPENTELEMETRY_BEGIN_NAMESPACE namespace metrics { @@ -38,5 +42,363 @@ class NoopMeterProvider final : public opentelemetry::metrics::MeterProvider private: nostd::shared_ptr meter_; }; -} // namespace metrics + +template +class NoopValueObserver : public ValueObserver +{ + +public: + NoopValueObserver(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/, + void (*callback)(ObserverResult)) {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual void observe(T value, const trace::KeyValueIterable &labels) override {} + + virtual void run() override {} + + virtual InstrumentKind GetKind() override { + return InstrumentKind::Counter; + } + +}; + + +template +class NoopSumObserver : public SumObserver +{ + +public: + NoopSumObserver(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/, + void (*callback)(ObserverResult)) + {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual void observe(T value, const trace::KeyValueIterable &labels) override {} + + virtual void run() override {} + + virtual InstrumentKind GetKind() override { + return InstrumentKind::Counter; + } +}; + + +template +class NoopUpDownSumObserver : public UpDownSumObserver +{ + +public: + NoopUpDownSumObserver(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/, + void (*callback)(ObserverResult)) + {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual void observe(T value, const trace::KeyValueIterable &labels) override {} + + virtual void run() override {} + + virtual InstrumentKind GetKind() override { + return InstrumentKind::Counter; + } +}; + + +template +class BoundNoopCounter : public BoundCounter +{ + +public: + BoundNoopCounter() = default; + + BoundNoopCounter(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/) + {} + + virtual void add(T value) override {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual InstrumentKind GetKind() override { + return InstrumentKind::Counter; + } + +}; + +template +class NoopCounter : public Counter +{ + +public: + NoopCounter() = default; + + NoopCounter(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/) + {} + + nostd::shared_ptr> bindNoopCounter(const trace::KeyValueIterable & /*labels*/) + { + return nostd::shared_ptr>(new BoundNoopCounter()); + } + + virtual void add(T value, const trace::KeyValueIterable & /*labels*/) override {} + + virtual void update(T value, const trace::KeyValueIterable & /*labels*/) override {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual InstrumentKind GetKind() override { + return InstrumentKind::Counter; + } + +}; + +template +class BoundNoopUpDownCounter : public BoundUpDownCounter +{ + +public: + BoundNoopUpDownCounter() = default; + + BoundNoopUpDownCounter(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/) + {} + + virtual void add(T value) override {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual InstrumentKind GetKind() override { + return InstrumentKind::UpDownCounter; + } + +}; + +template +class NoopUpDownCounter : public UpDownCounter +{ + +public: + NoopUpDownCounter() = default; + + NoopUpDownCounter(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/) + {} + + nostd::shared_ptr> bindNoopUpDownCounter(const trace::KeyValueIterable & /*labels*/) + { + return nostd::shared_ptr>(new BoundNoopUpDownCounter()); + } + + virtual void add(T value, const trace::KeyValueIterable & /*labels*/) override {} + + virtual void update(T value, const trace::KeyValueIterable & /*labels*/) override {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual InstrumentKind GetKind() override { + return InstrumentKind::UpDownCounter; + } +}; + + +template +class BoundNoopValueRecorder : public BoundValueRecorder +{ + +public: + BoundNoopValueRecorder() = default; + + BoundNoopValueRecorder(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/) + {} + + virtual void record(T value) override {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual InstrumentKind GetKind() override { + return InstrumentKind::ValueRecorder; + } +}; + +template +class NoopValueRecorder : public ValueRecorder +{ + +public: + NoopValueRecorder() = default; + + NoopValueRecorder(nostd::string_view /*name*/, + nostd::string_view /*description*/, + nostd::string_view /*unit*/, + bool /*enabled*/) + {} + + nostd::shared_ptr> bindNoopValueRecorder(const trace::KeyValueIterable & /*labels*/) + { + return nostd::shared_ptr>(new BoundNoopValueRecorder()); + } + + virtual void record(T value, const trace::KeyValueIterable & /*labels*/) override {} + + virtual void update(T value, const trace::KeyValueIterable & /*labels*/) override {} + + virtual bool IsEnabled() override { + return false; + } + + virtual nostd::string_view GetName() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetDescription() override { + return nostd::string_view(""); + } + + virtual nostd::string_view GetUnits() override { + return nostd::string_view(""); + } + + virtual InstrumentKind GetKind() override { + return InstrumentKind::ValueRecorder; + } + +}; + + +} // namespace metrics OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/observer_result.h b/api/include/opentelemetry/metrics/observer_result.h new file mode 100644 index 00000000000..5b675092ebb --- /dev/null +++ b/api/include/opentelemetry/metrics/observer_result.h @@ -0,0 +1,36 @@ +#pragma once + +#include "instrument.h" +#include "opentelemetry/nostd/shared_ptr.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +/** + * ObserverResult class is necessary for the callback recording asynchronous + * instrument use. Callback functions asynchronous instruments are designed to + * accept a single ObserverResult object and update using its pointer to the + * instrument itself. + */ + +template +class ObserverResult +{ + +public: + ObserverResult() = default; + + ObserverResult(AsynchronousInstrument * instrument): instrument_(instrument) {} + + virtual void observe(T value, const trace::KeyValueIterable &labels) { + instrument_->observe(value, labels); + } + +private: + AsynchronousInstrument * instrument_; + +}; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/sync_instruments.h b/api/include/opentelemetry/metrics/sync_instruments.h new file mode 100644 index 00000000000..79f3a450978 --- /dev/null +++ b/api/include/opentelemetry/metrics/sync_instruments.h @@ -0,0 +1,172 @@ +#pragma once + +#include "instrument.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +template +class BoundCounter : virtual public BoundSynchronousInstrument +{ + +public: + BoundCounter() = default; + + BoundCounter(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled); + + /* + * Add adds the value to the counter's sum. The labels are already linked * to the instrument + * and are not specified. + * + * @param value the numerical representation of the metric being captured + * @param labels the set of labels, as key-value pairs + */ + virtual void add(T value) = 0; +}; + +template +class Counter : virtual public SynchronousInstrument +{ + +public: + Counter() = default; + + Counter(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled) {} + + /* + * Bind creates a bound instrument for this counter. The labels are + * associated with values recorded via subsequent calls to Record. + * + * @param labels the set of labels, as key-value pairs. + * @return a BoundIntCounter tied to the specified labels + */ + virtual nostd::shared_ptr> bindCounter(const trace::KeyValueIterable &labels) { + return nostd::shared_ptr>(); + } + + /* + * Add adds the value to the counter's sum. The labels should contain + * the keys and values to be associated with this value. Counters only * accept positive + * valued updates. + * + * @param value the numerical representation of the metric being captured + * @param labels the set of labels, as key-value pairs + */ + virtual void add(T value, const trace::KeyValueIterable &labels) = 0; + + virtual void update(T value, const trace::KeyValueIterable &labels) override = 0; +}; + +template +class BoundUpDownCounter : virtual public BoundSynchronousInstrument +{ + +public: + BoundUpDownCounter() = default; + + BoundUpDownCounter(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled); + + /* + * Add adds the value to the counter's sum. The labels are already linked to * the instrument and + * do not need to specified again. UpDownCounters can accept positive and negative values. + * + * @param value the numerical representation of the metric being captured + * @param labels the set of labels, as key-value pairs + */ + virtual void add(T value) = 0; +}; + +template +class UpDownCounter : virtual public SynchronousInstrument +{ + +public: + UpDownCounter() = default; + + UpDownCounter(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled); + + virtual nostd::shared_ptr> bindUpDownCounter(const trace::KeyValueIterable &labels) + { + return nostd::shared_ptr>(); + } + + /* + * Add adds the value to the counter's sum. The labels should contain + * the keys and values to be associated with this value. UpDownCounters can + * accept positive and negative values. + * + * @param value the numerical representation of the metric being captured + * @param labels the set of labels, as key-value pairs + */ + virtual void add(T value, const trace::KeyValueIterable &labels) = 0; + + virtual void update(T value, const trace::KeyValueIterable &labels) override = 0; +}; + +template +class BoundValueRecorder : virtual public BoundSynchronousInstrument +{ + +public: + BoundValueRecorder() = default; + + BoundValueRecorder(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled); + + /* + * Records the value by summing it with previous measurements and checking * previously stored + * minimum and maximum values. The labels associated with * new values are already linked to the + * instrument as it is bound. * ValueRecorders can accept positive and negative values. + * + * @param value the numerical representation of the metric being captured + */ + virtual void record(T value) = 0; +}; + + +template +class ValueRecorder : virtual public SynchronousInstrument +{ + +public: + ValueRecorder() = default; + + ValueRecorder(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit, + bool enabled); + + virtual nostd::shared_ptr> bindValueRecorder(const trace::KeyValueIterable &labels){ + return nostd::shared_ptr>(); + } + + /* + * Records the value by summing it with previous measurements and checking * previously stored + * minimum and maximum values. The labels should contain the keys and values to be associated with + * this value. ValueRecorders can accept positive and negative values. + * + * @param value the numerical representation of the metric being captured + * @param labels the set of labels, as key-value pairs + */ + virtual void record(T value, const trace::KeyValueIterable &labels) = 0; + + virtual void update(T value, const trace::KeyValueIterable &labels) override = 0; +}; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/api/test/metrics/BUILD b/api/test/metrics/BUILD index 54feb0c75b8..08cd98cf8ef 100644 --- a/api/test/metrics/BUILD +++ b/api/test/metrics/BUILD @@ -10,3 +10,15 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "noop_instrument_test", + srcs = [ + "noop_instrument_test.cc", + ], + linkstatic = 1, + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) \ No newline at end of file diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index 1f2aca70a84..204aa992a62 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -1,4 +1,4 @@ -foreach(testname meter_provider_test) +foreach(testname noop_instrument_test meter_provider_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) diff --git a/api/test/metrics/noop_instrument_test.cc b/api/test/metrics/noop_instrument_test.cc new file mode 100644 index 00000000000..46f4babe420 --- /dev/null +++ b/api/test/metrics/noop_instrument_test.cc @@ -0,0 +1,185 @@ +#include +#include +#include +#include "opentelemetry/metrics/noop.h" +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +void noopIntCallback(ObserverResult result) +{ + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + result.observe(1, labelkv); + result.observe(-1, labelkv); +} + +void noopDoubleCallback(ObserverResult result) +{ + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + result.observe(1.5, labelkv); + result.observe(-1.5, labelkv); +} + +TEST(ValueObserver, Observe) +{ + NoopValueObserver alpha("test", "none", "unitless", true, &noopIntCallback); + + NoopValueObserver beta("test", "none", "unitless", true, &noopDoubleCallback); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.observe(1, labelkv); + beta.observe(1.5, labelkv); +} + +TEST(SumObserver, DefaultConstruction) +{ + NoopSumObserver alpha("test", "none", "unitless", true, &noopIntCallback); + + NoopSumObserver beta("test", "none", "unitless", true, &noopDoubleCallback); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.observe(1, labelkv); + beta.observe(1.5, labelkv); +} + +TEST(UpDownSumObserver, DefaultConstruction) +{ + NoopUpDownSumObserver alpha("test", "none", "unitless", true, &noopIntCallback); + + NoopUpDownSumObserver beta("test", "none", "unitless", true, &noopDoubleCallback); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.observe(1, labelkv); + beta.observe(1.0, labelkv); + alpha.observe(-1, labelkv); + beta.observe(-1.0, labelkv); +} + +TEST(Counter, DefaultConstruction) +{ + NoopCounter alpha("test", "none", "unitless", true); + NoopCounter beta("other", "none", "unitless", true); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.bind(labelkv); + + auto gamma = alpha.bindNoopCounter(labelkv); + auto delta = beta.bindNoopCounter(labelkv); + + gamma->unbind(); + delta->unbind(); +} + +TEST(Counter, Add) +{ + NoopCounter alpha("test", "none", "unitless", true); + NoopCounter beta("other", "none", "unitless", true); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.add(1, labelkv); + beta.add(1.5, labelkv); + + auto gamma = alpha.bindNoopCounter(labelkv); + auto delta = beta.bindNoopCounter(labelkv); + + gamma->add(1); + delta->add(1.5); + + gamma->unbind(); + delta->unbind(); +} + +TEST(UpDownCounter, DefaultConstruction) +{ + NoopUpDownCounter alpha("test", "none", "unitless", true); + NoopUpDownCounter beta("other", "none", "unitless", true); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.bind(labelkv); + + auto gamma = alpha.bindNoopUpDownCounter(labelkv); + auto delta = beta.bindNoopUpDownCounter(labelkv); + + gamma->unbind(); + delta->unbind(); +} + +TEST(UpDownCounter, Add) +{ + NoopUpDownCounter alpha("test", "none", "unitless", true); + NoopUpDownCounter beta("other", "none", "unitless", true); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.add(1, labelkv); + beta.add(1.5, labelkv); + + auto gamma = alpha.bindNoopUpDownCounter(labelkv); + auto delta = beta.bindNoopUpDownCounter(labelkv); + + gamma->add(1); + delta->add(1.0); + gamma->add(-1); + delta->add(-1.0); + + gamma->unbind(); + delta->unbind(); +} + +TEST(ValueRecorder, DefaultConstruction) +{ + NoopValueRecorder alpha("test", "none", "unitless", true); + NoopValueRecorder beta("other", "none", "unitless", true); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.bind(labelkv); + + auto gamma = alpha.bindNoopValueRecorder(labelkv); + auto delta = beta.bindNoopValueRecorder(labelkv); + + gamma->unbind(); + delta->unbind(); +} + +TEST(ValueRecorder, Record) +{ + NoopValueRecorder alpha("test", "none", "unitless", true); + NoopValueRecorder beta("other", "none", "unitless", true); + + std::map labels = {{"key", "value"}}; + auto labelkv = trace::KeyValueIterableView{labels}; + + alpha.record(1, labelkv); + beta.record(1.5, labelkv); + + auto gamma = alpha.bindNoopValueRecorder(labelkv); + auto delta = beta.bindNoopValueRecorder(labelkv); + + gamma->record(1); + delta->record(1.5); + + gamma->unbind(); + delta->unbind(); +} + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE