summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry')
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/aggregator.h156
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h108
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/exact_aggregator.h169
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/gauge_aggregator.h146
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h207
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h159
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/sketch_aggregator.h282
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/async_instruments.h286
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/controller.h154
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/exporter.h35
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/instrument.h312
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter.h392
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter_provider.h37
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/processor.h38
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/record.h50
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h465
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h365
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_shared_ptr.h62
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h87
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attribute_utils.h199
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attributemap_hash.h62
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer.h186
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer_range.h93
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/empty_attributes.h34
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/env_variables.h53
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/exporter_utils.h34
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/global_log_handler.h222
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h96
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h128
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/exporter.h62
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/log_record.h193
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger.h77
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_context.h81
-rwxr-xr-xsrc/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_provider.h131
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h69
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_recordable.h104
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/processor.h61
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/recordable.h97
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h55
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h55
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h146
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h51
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h103
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h63
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h64
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/async_instruments.h115
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h42
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/point_data.h78
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h43
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h45
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h39
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h43
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h55
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h55
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h57
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h72
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/instruments.h70
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter.h156
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_context.h133
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_provider.h95
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h55
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_reader.h72
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/observer_result.h48
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h95
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h124
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h57
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h86
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h68
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h119
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h50
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h127
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h81
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h36
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/meter_selector.h47
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate.h82
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate_factory.h45
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view.h57
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h102
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/experimental_semantic_conventions.h141
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource.h86
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource_detector.h38
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h158
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/exporter.h55
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/id_generator.h31
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_recordable.h161
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h187
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/processor.h70
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/random_id_generator.h24
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/recordable.h152
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/sampler.h91
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_off.h48
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_on.h47
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/parent.h45
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/trace_id_ratio.h53
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/simple_processor.h84
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/span_data.h304
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer.h70
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_context.h100
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_provider.h103
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/version/version.h30
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk_config.h7
101 files changed, 10563 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/aggregator.h
new file mode 100644
index 000000000..f6821d731
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/aggregator.h
@@ -0,0 +1,156 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <mutex>
+# include <vector>
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/common/timestamp.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+enum class AggregatorKind
+{
+ Counter = 0,
+ MinMaxSumCount = 1,
+ Gauge = 2,
+ Sketch = 3,
+ Histogram = 4,
+ Exact = 5,
+};
+
+/*
+ * Performs calculations necessary to combine updates from instruments into an
+ * insightful value.
+ * Also stores current instrument values and checkpoints collected at intervals
+ * governing the entire pipeline.
+ */
+template <typename T>
+class Aggregator
+{
+public:
+ Aggregator() = default;
+
+ virtual ~Aggregator() = default;
+
+ /**
+ * Receives a captured value from the instrument and applies it to the current aggregator value.
+ *
+ * @param val, the raw value used in aggregation
+ * @return none
+ */
+ virtual void update(T val) = 0;
+
+ /**
+ * Checkpoints the current value. This function will overwrite the current checkpoint with the
+ * current value.
+ *
+ * @param none
+ * @return none
+ */
+ virtual void checkpoint() = 0;
+
+ /**
+ * Merges the values of two aggregators in a semantically accurate manner.
+ * Merging will occur differently for different aggregators depending on the
+ * way values are tracked.
+ *
+ * @param other, the aggregator with merge with
+ * @return none
+ */
+ void merge(Aggregator *other);
+
+ /**
+ * Returns the checkpointed value
+ *
+ * @param none
+ * @return the value of the checkpoint
+ */
+ virtual std::vector<T> get_checkpoint() = 0;
+
+ /**
+ * Returns the current value
+ *
+ * @param none
+ * @return the present aggregator value
+ */
+ virtual std::vector<T> get_values() = 0;
+
+ /**
+ * Returns the instrument kind which this aggregator is associated with
+ *
+ * @param none
+ * @return the InstrumentKind of the aggregator's owner
+ */
+ virtual opentelemetry::metrics::InstrumentKind get_instrument_kind() final { return kind_; }
+
+ /**
+ * Returns the type of this aggregator
+ *
+ * @param none
+ * @return the AggregatorKind of this instrument
+ */
+ virtual AggregatorKind get_aggregator_kind() final { return agg_kind_; }
+
+ /**
+ * Getter function for updated_ protected var
+ *
+ * @return A bool indicating wether or not this aggregator has been updated
+ * in the most recent collection interval.
+ */
+ virtual bool is_updated() final { return updated_; }
+
+ // virtual function to be overridden for the Histogram Aggregator
+ virtual std::vector<double> get_boundaries() { return std::vector<double>(); }
+
+ // virtual function to be overridden for the Histogram Aggregator
+ virtual std::vector<int> get_counts() { return std::vector<int>(); }
+
+ // virtual function to be overridden for Exact and Sketch Aggregators
+ virtual bool get_quant_estimation() { return false; }
+
+ // virtual function to be overridden for Exact and Sketch Aggregators
+ virtual T get_quantiles(double q) { return values_[0]; }
+
+ // virtual function to be overridden for Sketch Aggregator
+ virtual double get_error_bound() { return 0; }
+
+ // virtual function to be overridden for Sketch Aggregator
+ virtual size_t get_max_buckets() { return 0; }
+
+ // virtual function to be overridden for Gauge Aggregator
+ virtual opentelemetry::common::SystemTimestamp get_checkpoint_timestamp()
+ {
+ return opentelemetry::common::SystemTimestamp();
+ }
+
+ // Custom copy constructor to handle the mutex
+ Aggregator(const Aggregator &cp)
+ {
+ values_ = cp.values_;
+ checkpoint_ = cp.checkpoint_;
+ kind_ = cp.kind_;
+ agg_kind_ = cp.agg_kind_;
+ // use default initialized mutex as they cannot be copied
+ }
+
+protected:
+ std::vector<T> values_;
+ std::vector<T> checkpoint_;
+ opentelemetry::metrics::InstrumentKind kind_;
+ std::mutex mu_;
+ AggregatorKind agg_kind_;
+ bool updated_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h
new file mode 100644
index 000000000..b9842e8e0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h
@@ -0,0 +1,108 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <mutex>
+# include <vector>
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+template <class T>
+class CounterAggregator final : public Aggregator<T>
+{
+
+public:
+ CounterAggregator(opentelemetry::metrics::InstrumentKind kind)
+ {
+ this->kind_ = kind;
+ this->values_ = std::vector<T>(1, 0);
+ this->checkpoint_ = std::vector<T>(1, 0);
+ this->agg_kind_ = AggregatorKind::Counter;
+ }
+
+ /**
+ * Receives a captured value from the instrument and applies it to the current aggregator value.
+ *
+ * @param val, the raw value used in aggregation
+ * @return none
+ */
+ void update(T val) override
+ {
+ this->mu_.lock();
+ this->updated_ = true;
+ this->values_[0] += val; // atomic operation
+ this->mu_.unlock();
+ }
+
+ /**
+ * Checkpoints the current value. This function will overwrite the current checkpoint with the
+ * current value.
+ *
+ * @param none
+ * @return none
+ */
+ void checkpoint() override
+ {
+ this->mu_.lock();
+ this->updated_ = false;
+ this->checkpoint_ = this->values_;
+ this->values_[0] = 0;
+ this->mu_.unlock();
+ }
+
+ /**
+ * Merges the values of two aggregators in a semantically accurate manner.
+ * In this case, merging only requires the the current values of the two aggregators be summed.
+ *
+ * @param other, the aggregator with merge with
+ * @return none
+ */
+ void merge(CounterAggregator other)
+ {
+ if (this->agg_kind_ == other.agg_kind_)
+ {
+ this->mu_.lock();
+ this->values_[0] += other.values_[0];
+ this->checkpoint_[0] += other.checkpoint_[0];
+ this->mu_.unlock();
+ }
+ else
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Aggregators of different types cannot be merged.");
+# else
+ std::terminate();
+# endif
+ }
+ }
+
+ /**
+ * Returns the checkpointed value
+ *
+ * @param none
+ * @return the value of the checkpoint
+ */
+ virtual std::vector<T> get_checkpoint() override { return this->checkpoint_; }
+
+ /**
+ * Returns the current values
+ *
+ * @param none
+ * @return the present aggregator values
+ */
+ virtual std::vector<T> get_values() override { return this->values_; }
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/exact_aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/exact_aggregator.h
new file mode 100644
index 000000000..44ea717a0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/exact_aggregator.h
@@ -0,0 +1,169 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/version.h"
+
+# include <cmath>
+# include <memory>
+# include <mutex>
+# include <vector>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+/**
+ * This aggregator has two modes. In-order and quantile estimation.
+ *
+ * The first mode simply stores all values sent to the Update()
+ * function in a vector and maintains the order they were sent in.
+ *
+ * The second mode also stores all values sent to the Update()
+ * function in a vector but sorts this vector when Checkpoint()
+ * is called. This mode also includes a function, Quantile(),
+ * that estimates the quantiles of the recorded data.
+ *
+ * @tparam T the type of values stored in this aggregator.
+ */
+template <class T>
+class ExactAggregator : public Aggregator<T>
+{
+public:
+ ExactAggregator(opentelemetry::metrics::InstrumentKind kind, bool quant_estimation = false)
+ {
+ static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
+ this->kind_ = kind;
+ this->checkpoint_ = this->values_;
+ this->agg_kind_ = AggregatorKind::Exact;
+ quant_estimation_ = quant_estimation;
+ }
+
+ ~ExactAggregator() = default;
+
+ ExactAggregator(const ExactAggregator &cp)
+ {
+ this->values_ = cp.values_;
+ this->checkpoint_ = cp.checkpoint_;
+ this->kind_ = cp.kind_;
+ this->agg_kind_ = cp.agg_kind_;
+ quant_estimation_ = cp.quant_estimation_;
+ // use default initialized mutex as they cannot be copied
+ }
+
+ /**
+ * Receives a captured value from the instrument and adds it to the values_ vector.
+ *
+ * @param val, the raw value used in aggregation
+ */
+ void update(T val) override
+ {
+ this->mu_.lock();
+ this->updated_ = true;
+ this->values_.push_back(val);
+ this->mu_.unlock();
+ }
+
+ /**
+ * Checkpoints the current values. This function will overwrite the current checkpoint with the
+ * current value. Sorts the values_ vector if quant_estimation_ == true
+ *
+ */
+ void checkpoint() override
+ {
+ this->mu_.lock();
+ this->updated_ = false;
+ if (quant_estimation_)
+ {
+ std::sort(this->values_.begin(), this->values_.end());
+ }
+ this->checkpoint_ = this->values_;
+ this->values_.clear();
+ this->mu_.unlock();
+ }
+
+ /**
+ * Merges two exact aggregators' values_ vectors together.
+ *
+ * @param other the aggregator to merge with this aggregator
+ */
+ void merge(const ExactAggregator &other)
+ {
+ if (this->kind_ == other.kind_)
+ {
+ this->mu_.lock();
+ // First merge values
+ this->values_.insert(this->values_.end(), other.values_.begin(), other.values_.end());
+ // Now merge checkpoints
+ this->checkpoint_.insert(this->checkpoint_.end(), other.checkpoint_.begin(),
+ other.checkpoint_.end());
+ this->mu_.unlock();
+ }
+ else
+ {
+ // Log error
+ return;
+ }
+ }
+
+ /**
+ * Performs quantile estimation on the checkpoint vector in this aggregator.
+ * This function only works if quant_estimation_ == true.
+ * @param q the quantile to estimate. 0 <= q <= 1
+ * @return the nearest value in the vector to the exact quantile.
+ */
+ T get_quantiles(double q) override
+ {
+ if (!quant_estimation_)
+ {
+// Log error
+# if __EXCEPTIONS
+ throw std::domain_error("Exact aggregator is not in quantile estimation mode!");
+# else
+ std::terminate();
+# endif
+ }
+ if (this->checkpoint_.size() == 0 || q < 0 || q > 1)
+ {
+// Log error
+# if __EXCEPTIONS
+ throw std::invalid_argument("Arg 'q' must be between 0 and 1, inclusive");
+# else
+ std::terminate();
+# endif
+ }
+ else if (q == 0 || this->checkpoint_.size() == 1)
+ {
+ return this->checkpoint_[0];
+ }
+ else if (q == 1)
+ {
+ return this->checkpoint_[this->checkpoint_.size() - 1];
+ }
+ else
+ {
+ float position = float(float(this->checkpoint_.size() - 1) * q);
+ int ceiling = int(ceil(position));
+ return this->checkpoint_[ceiling];
+ }
+ }
+
+ //////////////////////////ACCESSOR FUNCTIONS//////////////////////////
+ std::vector<T> get_checkpoint() override { return this->checkpoint_; }
+
+ std::vector<T> get_values() override { return this->values_; }
+
+ bool get_quant_estimation() override { return quant_estimation_; }
+
+private:
+ bool quant_estimation_; // Used to switch between in-order and quantile estimation modes
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/gauge_aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/gauge_aggregator.h
new file mode 100644
index 000000000..96119386d
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/gauge_aggregator.h
@@ -0,0 +1,146 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/common/timestamp.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/version.h"
+
+# include <memory>
+# include <mutex>
+# include <vector>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+/**
+ * This aggregator stores and maintains a vector of
+ * type T where the contents of the vector simply
+ * include the last value recorded to the aggregator.
+ * The aggregator also maintains a timestamp of when
+ * the last value was recorded.
+ *
+ * @tparam T the type of values stored in this aggregator.
+ */
+template <class T>
+class GaugeAggregator : public Aggregator<T>
+{
+public:
+ explicit GaugeAggregator(opentelemetry::metrics::InstrumentKind kind)
+ {
+ static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
+ this->kind_ = kind;
+ this->values_ = std::vector<T>(1, 0);
+ this->checkpoint_ = this->values_;
+ this->agg_kind_ = AggregatorKind::Gauge;
+ current_timestamp_ = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now());
+ }
+
+ ~GaugeAggregator() = default;
+
+ GaugeAggregator(const GaugeAggregator &cp)
+ {
+ this->values_ = cp.values_;
+ this->checkpoint_ = cp.checkpoint_;
+ this->kind_ = cp.kind_;
+ this->agg_kind_ = cp.agg_kind_;
+ current_timestamp_ = cp.current_timestamp_;
+ // use default initialized mutex as they cannot be copied
+ }
+
+ /**
+ * Receives a captured value from the instrument and applies it to the current aggregator value.
+ *
+ * @param val, the raw value used in aggregation
+ */
+ void update(T val) override
+ {
+ this->mu_.lock();
+ this->updated_ = true;
+ this->values_[0] = val;
+ current_timestamp_ = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now());
+ this->mu_.unlock();
+ }
+
+ /**
+ * Checkpoints the current value. This function will overwrite the current checkpoint with the
+ * current value.
+ *
+ * @return none
+ */
+
+ void checkpoint() override
+ {
+ this->mu_.lock();
+
+ this->updated_ = false;
+ this->checkpoint_ = this->values_;
+
+ // Reset the values to default
+ this->values_[0] = 0;
+ checkpoint_timestamp_ = current_timestamp_;
+ current_timestamp_ = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now());
+
+ this->mu_.unlock();
+ }
+
+ /**
+ * Merges two Gauge aggregators together
+ *
+ * @param other the aggregator to merge with this aggregator
+ */
+ void merge(GaugeAggregator<T> other)
+ {
+ if (this->kind_ == other.kind_)
+ {
+ this->mu_.lock();
+ // First merge values
+ this->values_[0] = other.values_[0];
+ // Now merge checkpoints
+ this->checkpoint_[0] = other.checkpoint_[0];
+ current_timestamp_ = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now());
+ this->mu_.unlock();
+ }
+ else
+ {
+ // Log error
+ return;
+ }
+ }
+
+ /**
+ * @return the value of the latest checkpoint
+ */
+ std::vector<T> get_checkpoint() override { return this->checkpoint_; }
+
+ /**
+ * @return the latest checkpointed timestamp
+ */
+ opentelemetry::common::SystemTimestamp get_checkpoint_timestamp() override
+ {
+ return checkpoint_timestamp_;
+ }
+
+ /**
+ * @return the values_ vector stored in this aggregator
+ */
+ std::vector<T> get_values() override { return this->values_; }
+
+ /**
+ * @return the timestamp of when the last value recorded
+ */
+ opentelemetry::common::SystemTimestamp get_timestamp() { return current_timestamp_; }
+
+private:
+ opentelemetry::common::SystemTimestamp current_timestamp_;
+ opentelemetry::common::SystemTimestamp checkpoint_timestamp_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h
new file mode 100644
index 000000000..13e1e1244
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h
@@ -0,0 +1,207 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <algorithm>
+# include <mutex>
+# include <stdexcept>
+# include <vector>
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+template <class T>
+class HistogramAggregator final : public Aggregator<T>
+{
+
+public:
+ /**
+ * Constructor for the histogram aggregator. A sorted vector of boundaries is expected and
+ * boundaries are doubles regardless of the aggregator's templated data type.
+ *
+ * Sum is stored in values_[0]
+ * Count is stored in position_[1]
+ */
+ HistogramAggregator(opentelemetry::metrics::InstrumentKind kind, std::vector<double> boundaries)
+ {
+ if (!std::is_sorted(boundaries.begin(), boundaries.end()))
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Histogram boundaries must be monotonic.");
+# else
+ std::terminate();
+# endif
+ }
+ this->kind_ = kind;
+ this->agg_kind_ = AggregatorKind::Histogram;
+ boundaries_ = boundaries;
+ this->values_ = std::vector<T>(2, 0);
+ this->checkpoint_ = std::vector<T>(2, 0);
+ bucketCounts_ = std::vector<int>(boundaries_.size() + 1, 0);
+ bucketCounts_ckpt_ = std::vector<int>(boundaries_.size() + 1, 0);
+ }
+
+ /**
+ * Receives a captured value from the instrument and inserts it into the current histogram counts.
+ *
+ * Depending on the use case, a linear search or binary search based implementation may be
+ * preferred. In uniformly distributed datasets, linear search outperforms binary search until 512
+ * buckets. However, if the distribution is strongly skewed right (for example server latency
+ * where most values may be <10ms but the range is from 0 - 1000 ms), a linear search could be
+ * superior even with more than 500 buckets as almost all values inserted would be at the
+ * beginning of the boundaries array and thus found more quickly through linear search.
+ *
+ * @param val, the raw value used in aggregation
+ * @return none
+ */
+ void update(T val) override
+ {
+ this->mu_.lock();
+ this->updated_ = true;
+ size_t bucketID = boundaries_.size();
+ for (size_t i = 0; i < boundaries_.size(); i++)
+ {
+ if (val < boundaries_[i]) // concurrent read is thread-safe
+ {
+ bucketID = i;
+ break;
+ }
+ }
+
+ // Alternate implementation with binary search
+ // auto pos = std::lower_bound (boundaries_.begin(), boundaries_.end(), val);
+ // bucketCounts_[pos-boundaries_.begin()] += 1;
+
+ this->values_[0] += val;
+ this->values_[1] += 1;
+ bucketCounts_[bucketID] += 1;
+ this->mu_.unlock();
+ }
+
+ /**
+ * Checkpoints the current value. This function will overwrite the current checkpoint with the
+ * current value.
+ *
+ * @param none
+ * @return none
+ */
+ void checkpoint() override
+ {
+ this->mu_.lock();
+ this->updated_ = false;
+ this->checkpoint_ = this->values_;
+ this->values_[0] = 0;
+ this->values_[1] = 0;
+ bucketCounts_ckpt_ = bucketCounts_;
+ std::fill(bucketCounts_.begin(), bucketCounts_.end(), 0);
+ this->mu_.unlock();
+ }
+
+ /**
+ * Merges the values of two aggregators in a semantically accurate manner.
+ * A histogram aggregator can only be merged with another histogram aggregator that has the same
+ * boudnaries. A histogram merge first adds the sum and count values then iterates over the adds
+ * the bucket counts element by element.
+ *
+ * @param other, the aggregator with merge with
+ * @return none
+ */
+ void merge(HistogramAggregator other)
+ {
+ this->mu_.lock();
+
+ // Ensure that incorrect types are not merged
+ if (this->agg_kind_ != other.agg_kind_)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Aggregators of different types cannot be merged.");
+# else
+ std::terminate();
+# endif
+ // Reject histogram merges with differing boundary vectors
+ }
+ else if (other.boundaries_ != this->boundaries_)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Histogram boundaries do not match.");
+# else
+ std::terminate();
+# endif
+ }
+
+ this->values_[0] += other.values_[0];
+ this->values_[1] += other.values_[1];
+
+ this->checkpoint_[0] += other.checkpoint_[0];
+ this->checkpoint_[1] += other.checkpoint_[1];
+
+ for (size_t i = 0; i < bucketCounts_.size(); i++)
+ {
+ bucketCounts_[i] += other.bucketCounts_[i];
+ bucketCounts_ckpt_[i] += other.bucketCounts_ckpt_[i];
+ }
+ this->mu_.unlock();
+ }
+
+ /**
+ * Returns the checkpointed value
+ *
+ * @param none
+ * @return the value of the checkpoint
+ */
+ std::vector<T> get_checkpoint() override { return this->checkpoint_; }
+
+ /**
+ * Returns the current values
+ *
+ * @param none
+ * @return the present aggregator values
+ */
+ std::vector<T> get_values() override { return this->values_; }
+
+ /**
+ * Returns the bucket boundaries specified at this aggregator's creation.
+ *
+ * @param none
+ * @return the aggregator boundaries
+ */
+ virtual std::vector<double> get_boundaries() override { return boundaries_; }
+
+ /**
+ * Returns the current counts for each bucket .
+ *
+ * @param none
+ * @return the aggregator bucket counts
+ */
+ virtual std::vector<int> get_counts() override { return bucketCounts_ckpt_; }
+
+ HistogramAggregator(const HistogramAggregator &cp)
+ {
+ this->values_ = cp.values_;
+ this->checkpoint_ = cp.checkpoint_;
+ this->kind_ = cp.kind_;
+ this->agg_kind_ = cp.agg_kind_;
+ boundaries_ = cp.boundaries_;
+ bucketCounts_ = cp.bucketCounts_;
+ bucketCounts_ckpt_ = cp.bucketCounts_ckpt_;
+ // use default initialized mutex as they cannot be copied
+ }
+
+private:
+ std::vector<double> boundaries_;
+ std::vector<int> bucketCounts_;
+ std::vector<int> bucketCounts_ckpt_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h
new file mode 100644
index 000000000..60628b567
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h
@@ -0,0 +1,159 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/version.h"
+
+# include <memory>
+# include <mutex>
+# include <vector>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+const int MinValueIndex = 0;
+const int MaxValueIndex = 1;
+const int SumValueIndex = 2;
+const int CountValueIndex = 3;
+/**
+ * This aggregator stores and maintains a vector of
+ * type T where the contents in the vector are made
+ * up of the minimum value recorded to this instrument,
+ * the maximum value, the sum of all values, and the
+ * count of all values.
+ *
+ * @tparam T the type of values stored in this aggregator.
+ */
+template <class T>
+class MinMaxSumCountAggregator : public Aggregator<T>
+{
+public:
+ explicit MinMaxSumCountAggregator(opentelemetry::metrics::InstrumentKind kind)
+ {
+ static_assert(std::is_arithmetic<T>::value, "Not an arithmetic type");
+ this->kind_ = kind;
+ this->values_ = std::vector<T>(4, 0); // {min, max, sum, count}
+ this->checkpoint_ = this->values_;
+ this->agg_kind_ = AggregatorKind::MinMaxSumCount;
+ }
+
+ ~MinMaxSumCountAggregator() = default;
+
+ MinMaxSumCountAggregator(const MinMaxSumCountAggregator &cp)
+ {
+ this->values_ = cp.values_;
+ this->checkpoint_ = cp.checkpoint_;
+ this->kind_ = cp.kind_;
+ this->agg_kind_ = cp.agg_kind_;
+ // use default initialized mutex as they cannot be copied
+ }
+
+ /**
+ * Receives a captured value from the instrument and applies it to the current aggregator value.
+ *
+ * @param val, the raw value used in aggregation
+ */
+ void update(T val) override
+ {
+ this->mu_.lock();
+ this->updated_ = true;
+
+ if (this->values_[CountValueIndex] == 0 || val < this->values_[MinValueIndex]) // set min
+ this->values_[MinValueIndex] = val;
+ if (this->values_[CountValueIndex] == 0 || val > this->values_[MaxValueIndex]) // set max
+ this->values_[MaxValueIndex] = val;
+
+ this->values_[SumValueIndex] += val; // compute sum
+ this->values_[CountValueIndex]++; // increment count
+
+ this->mu_.unlock();
+ }
+
+ /**
+ * Checkpoints the current value. This function will overwrite the current checkpoint with the
+ * current value.
+ *
+ */
+ void checkpoint() override
+ {
+ this->mu_.lock();
+ this->updated_ = false;
+ this->checkpoint_ = this->values_;
+ // Reset the values
+ this->values_[MinValueIndex] = 0;
+ this->values_[MaxValueIndex] = 0;
+ this->values_[SumValueIndex] = 0;
+ this->values_[CountValueIndex] = 0;
+ this->mu_.unlock();
+ }
+
+ /**
+ * Merges two MinMaxSumCount aggregators together
+ *
+ * @param other the aggregator to merge with this aggregator
+ */
+ void merge(const MinMaxSumCountAggregator &other)
+ {
+ if (this->kind_ == other.kind_)
+ {
+ this->mu_.lock();
+ // First merge values
+ // set min
+ if (this->values_[CountValueIndex] == 0 ||
+ other.values_[MinValueIndex] < this->values_[MinValueIndex])
+ this->values_[MinValueIndex] = other.values_[MinValueIndex];
+ // set max
+ if (this->values_[CountValueIndex] == 0 ||
+ other.values_[MaxValueIndex] > this->values_[MaxValueIndex])
+ this->values_[MaxValueIndex] = other.values_[MaxValueIndex];
+ // set sum
+ this->values_[SumValueIndex] += other.values_[SumValueIndex];
+ // set count
+ this->values_[CountValueIndex] += other.values_[CountValueIndex];
+
+ // Now merge checkpoints
+ if (this->checkpoint_[CountValueIndex] == 0 ||
+ other.checkpoint_[MinValueIndex] < this->checkpoint_[MinValueIndex])
+ this->checkpoint_[MinValueIndex] = other.checkpoint_[MinValueIndex];
+ // set max
+ if (this->checkpoint_[CountValueIndex] == 0 ||
+ other.checkpoint_[MaxValueIndex] > this->checkpoint_[MaxValueIndex])
+ this->checkpoint_[MaxValueIndex] = other.checkpoint_[MaxValueIndex];
+ // set sum
+ this->checkpoint_[SumValueIndex] += other.checkpoint_[SumValueIndex];
+ // set count
+ this->checkpoint_[CountValueIndex] += other.checkpoint_[CountValueIndex];
+
+ this->mu_.unlock();
+ }
+ else
+ {
+ // Log error
+ return;
+ }
+ }
+
+ /**
+ * Returns the checkpointed value
+ *
+ * @return the value of the checkpoint
+ */
+ std::vector<T> get_checkpoint() override { return this->checkpoint_; }
+
+ /**
+ * Returns the values currently held by the aggregator
+ *
+ * @return the values held by the aggregator
+ */
+ std::vector<T> get_values() override { return this->values_; }
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/sketch_aggregator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/sketch_aggregator.h
new file mode 100644
index 000000000..3942c9550
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/aggregator/sketch_aggregator.h
@@ -0,0 +1,282 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <algorithm>
+# include <cmath>
+# include <limits>
+# include <map>
+# include <mutex>
+# include <stdexcept>
+# include <vector>
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+/** Sketch Aggregators implement the DDSketch data type. Note that data is compressed
+ * by the DDSketch algorithm and users should be informed about its behavior before
+ * selecting it as the aggregation type. NOTE: The current implementation can only support
+ * non-negative values.
+ *
+ * Detailed information about the algorithm can be found in the following paper
+ * published by Datadog: http://www.vldb.org/pvldb/vol12/p2195-masson.pdf
+ */
+
+template <class T>
+class SketchAggregator final : public Aggregator<T>
+{
+
+public:
+ /**
+ * Given the distribution of data this aggregator is designed for and its usage, the raw updates
+ *are stored in a map rather than a vector.
+ *
+ *@param kind, the instrument kind creating this aggregator
+ *@param error_bound, what is referred to as "alpha" in the DDSketch algorithm
+ *@param max_buckets, the maximum number of indices in the raw value map
+ */
+ SketchAggregator(opentelemetry::metrics::InstrumentKind kind,
+ double error_bound,
+ size_t max_buckets = 2048)
+ {
+
+ this->kind_ = kind;
+ this->agg_kind_ = AggregatorKind::Sketch;
+ this->values_ = std::vector<T>(2, 0); // Sum in [0], Count in [1]
+ this->checkpoint_ = std::vector<T>(2, 0);
+ max_buckets_ = max_buckets;
+ error_bound_ = error_bound;
+ gamma = (1 + error_bound) / (1 - error_bound);
+ }
+
+ /**
+ * Update the aggregator with the new value. For a DDSketch aggregator, if the addition of this
+ * value creates a new bucket which is in excess of the maximum allowed size, the lowest indexes
+ * buckets are merged.
+ *
+ * @param val, the raw value used in aggregation
+ * @return none
+ */
+ void update(T val) override
+ {
+ this->mu_.lock();
+ this->updated_ = true;
+ int idx;
+ if (val == 0)
+ {
+ idx = (std::numeric_limits<int>::min());
+ }
+ else
+ {
+ idx = static_cast<int>(ceil(log(val) / log(gamma)));
+ }
+ if (raw_.find(idx) != raw_.end())
+ {
+ raw_[idx] += 1;
+ }
+ else
+ {
+ raw_[idx] = 1;
+ }
+ this->values_[1] += 1;
+ this->values_[0] += val;
+ if (raw_.size() > max_buckets_)
+ {
+ int minidx = raw_.begin()->first, minidxval = raw_.begin()->second;
+ raw_.erase(minidx);
+ raw_[raw_.begin()->first] += minidxval;
+ }
+ this->mu_.unlock();
+ }
+
+ /**
+ * Calculate and return the value of a user specified quantile.
+ *
+ * @param q, the quantile to calculate (for example 0.5 is equivalent to the 50th percentile)
+ */
+ virtual T get_quantiles(double q) override
+ {
+ if (q < 0 || q > 1)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Quantile values must fall between 0 and 1");
+# else
+ std::terminate();
+# endif
+ }
+ auto iter = checkpoint_raw_.begin();
+ int idx = iter->first;
+ int count = iter->second;
+
+ while (count < (q * (this->checkpoint_[1] - 1)) && iter != checkpoint_raw_.end())
+ {
+ iter++;
+ idx = iter->first;
+ count += iter->second;
+ }
+ return static_cast<T>(round(2 * pow(gamma, idx) / (gamma + 1)));
+ }
+
+ /**
+ * Checkpoints the current value. This function will overwrite the current checkpoint with the
+ * current value.
+ *
+ * @param none
+ * @return none
+ */
+ void checkpoint() override
+ {
+ this->mu_.lock();
+ this->updated_ = false;
+ this->checkpoint_ = this->values_;
+ checkpoint_raw_ = raw_;
+ this->values_[0] = 0;
+ this->values_[1] = 0;
+ raw_.clear();
+ this->mu_.unlock();
+ }
+
+ /**
+ * Merges this sketch aggregator with another. The same bucket compression used when
+ * updating values is employed here to manage bucket size if the merging of aggregators
+ * results in more buckets than allowed.
+ *
+ * @param other, the aggregator with merge with
+ * @return none
+ */
+ void merge(SketchAggregator other)
+ {
+ if (gamma != other.gamma)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Aggregators must have identical error tolerance");
+# else
+ std::terminate();
+# endif
+ }
+ else if (max_buckets_ != other.max_buckets_)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Aggregators must have the same maximum bucket allowance");
+# else
+ std::terminate();
+# endif
+ }
+
+ this->mu_.lock();
+ this->values_[0] += other.values_[0];
+ this->values_[1] += other.values_[1];
+ this->checkpoint_[0] += other.checkpoint_[0];
+ this->checkpoint_[1] += other.checkpoint_[1];
+ auto other_iter = other.raw_.begin();
+ while (other_iter != other.raw_.end())
+ {
+ raw_[other_iter->first] += other_iter->second;
+ if (raw_.size() > max_buckets_)
+ {
+ int minidx = raw_.begin()->first, minidxval = raw_.begin()->second;
+ raw_.erase(minidx);
+ raw_[raw_.begin()->first] += minidxval;
+ }
+ other_iter++;
+ }
+ auto other_ckpt_iter = other.checkpoint_raw_.begin();
+ while (other_ckpt_iter != other.checkpoint_raw_.end())
+ {
+ checkpoint_raw_[other_ckpt_iter->first] += other_ckpt_iter->second;
+ if (checkpoint_raw_.size() > max_buckets_)
+ {
+ int minidx = checkpoint_raw_.begin()->first, minidxval = checkpoint_raw_.begin()->second;
+ checkpoint_raw_.erase(minidx);
+ checkpoint_raw_[checkpoint_raw_.begin()->first] += minidxval;
+ }
+ other_ckpt_iter++;
+ }
+ this->mu_.unlock();
+ }
+
+ /**
+ * Returns the checkpointed value
+ *
+ * @param none
+ * @return the value of the checkpoint
+ */
+ std::vector<T> get_checkpoint() override { return this->checkpoint_; }
+
+ /**
+ * Returns the current values
+ *
+ * @param none
+ * @return the present aggregator values
+ */
+ std::vector<T> get_values() override { return this->values_; }
+
+ /**
+ * Returns the indices (or values) stored by this sketch aggregator.
+ *
+ * @param none
+ * @return a vector of all values the aggregator is currently tracking
+ */
+ virtual std::vector<double> get_boundaries() override
+ {
+ std::vector<double> ret;
+ for (auto const &x : checkpoint_raw_)
+ {
+ ret.push_back(2 * pow(gamma, x.first) / (gamma + 1));
+ }
+ return ret;
+ }
+
+ /**
+ * Returns the error bound
+ *
+ * @param none
+ * @return the error bound specified during construction
+ */
+ virtual double get_error_bound() override { return error_bound_; }
+
+ /**
+ * Returns the maximum allowed buckets
+ *
+ * @param none
+ * @return the maximum allowed buckets
+ */
+ virtual size_t get_max_buckets() override { return max_buckets_; }
+
+ /**
+ * Returns the count of each value tracked by this sketch aggregator. These are returned
+ * in the same order as the indices returned by the get_boundaries function.
+ *
+ * @param none
+ * @return a vector of all counts for values tracked by the aggregator
+ */
+ virtual std::vector<int> get_counts() override
+ {
+ std::vector<int> ret;
+ for (auto const &x : checkpoint_raw_)
+ {
+ ret.push_back(x.second);
+ }
+ return ret;
+ }
+
+private:
+ double gamma;
+ double error_bound_;
+ size_t max_buckets_;
+ std::map<int, int> raw_;
+ std::map<int, int> checkpoint_raw_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/async_instruments.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/async_instruments.h
new file mode 100644
index 000000000..5213a4e2e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/async_instruments.h
@@ -0,0 +1,286 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <map>
+# include <memory>
+# include <sstream>
+# include <stdexcept>
+# include <vector>
+# include "opentelemetry/_metrics/async_instruments.h"
+# include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h"
+# include "opentelemetry/sdk/_metrics/instrument.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+# if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable : 4250) // inheriting methods via dominance
+# endif
+
+template <class T>
+class ValueObserver : public AsynchronousInstrument<T>,
+ virtual public opentelemetry::metrics::ValueObserver<T>
+{
+
+public:
+ ValueObserver() = default;
+
+ ValueObserver(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<T>))
+ : AsynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ callback,
+ opentelemetry::metrics::InstrumentKind::ValueObserver)
+ {}
+
+ /*
+ * 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 opentelemetry::common::KeyValueIterable &labels) override
+ {
+ this->mu_.lock();
+ std::string labelset = KvToString(labels);
+ if (boundAggregators_.find(labelset) == boundAggregators_.end())
+ {
+ auto sp1 = std::shared_ptr<Aggregator<T>>(new MinMaxSumCountAggregator<T>(this->kind_));
+ boundAggregators_.insert(std::make_pair(labelset, sp1));
+ sp1->update(value);
+ }
+ else
+ {
+ boundAggregators_[labelset]->update(value);
+ }
+ this->mu_.unlock();
+ }
+
+ /*
+ * Activate the instrument's callback function to record a measurement. This
+ * function will be called by the specified controller at a regular interval.
+ *
+ * @param none
+ * @return none
+ */
+ virtual void run() override
+ {
+ opentelemetry::metrics::ObserverResult<T> res(this);
+ this->callback_(res);
+ }
+
+ virtual std::vector<Record> GetRecords() override
+ {
+ this->mu_.lock();
+ std::vector<Record> ret;
+ for (auto x : boundAggregators_)
+ {
+ x.second->checkpoint();
+ ret.push_back(Record(this->GetName(), this->GetDescription(), x.first, x.second));
+ }
+ boundAggregators_.clear();
+ this->mu_.unlock();
+ return ret;
+ }
+
+ // Public mapping from labels (stored as strings) to their respective aggregators
+ std::unordered_map<std::string, std::shared_ptr<Aggregator<T>>> boundAggregators_;
+};
+
+template <class T>
+class SumObserver : public AsynchronousInstrument<T>,
+ virtual public opentelemetry::metrics::SumObserver<T>
+{
+
+public:
+ SumObserver() = default;
+
+ SumObserver(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<T>))
+ : AsynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ callback,
+ opentelemetry::metrics::InstrumentKind::SumObserver)
+ {}
+
+ /*
+ * 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 opentelemetry::common::KeyValueIterable &labels) override
+ {
+ this->mu_.lock();
+ std::string labelset = KvToString(labels);
+ if (boundAggregators_.find(labelset) == boundAggregators_.end())
+ {
+ auto sp1 = std::shared_ptr<Aggregator<T>>(new CounterAggregator<T>(this->kind_));
+ boundAggregators_.insert(std::make_pair(labelset, sp1));
+ if (value < 0)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Counter instrument updates must be non-negative.");
+# else
+ std::terminate();
+# endif
+ }
+ else
+ {
+ sp1->update(value);
+ }
+ }
+ else
+ {
+ if (value < 0)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Counter instrument updates must be non-negative.");
+# else
+ std::terminate();
+# endif
+ }
+ else
+ {
+ boundAggregators_[labelset]->update(value);
+ }
+ }
+ this->mu_.unlock();
+ }
+
+ /*
+ * Activate the intsrument's callback function to record a measurement. This
+ * function will be called by the specified controller at a regular interval.
+ *
+ * @param none
+ * @return none
+ */
+ virtual void run() override
+ {
+ opentelemetry::metrics::ObserverResult<T> res(this);
+ this->callback_(res);
+ }
+
+ virtual std::vector<Record> GetRecords() override
+ {
+ this->mu_.lock();
+ std::vector<Record> ret;
+ for (auto x : boundAggregators_)
+ {
+ x.second->checkpoint();
+ ret.push_back(Record(this->GetName(), this->GetDescription(), x.first, x.second));
+ }
+ boundAggregators_.clear();
+ this->mu_.unlock();
+ return ret;
+ }
+
+ // Public mapping from labels (stored as strings) to their respective aggregators
+ std::unordered_map<std::string, std::shared_ptr<Aggregator<T>>> boundAggregators_;
+};
+
+template <class T>
+class UpDownSumObserver : public AsynchronousInstrument<T>,
+ virtual public opentelemetry::metrics::UpDownSumObserver<T>
+{
+
+public:
+ UpDownSumObserver() = default;
+
+ UpDownSumObserver(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<T>))
+ : AsynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ callback,
+ opentelemetry::metrics::InstrumentKind::UpDownSumObserver)
+ {}
+
+ /*
+ * 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 opentelemetry::common::KeyValueIterable &labels) override
+ {
+ this->mu_.lock();
+ std::string labelset = KvToString(labels);
+ if (boundAggregators_.find(labelset) == boundAggregators_.end())
+ {
+ auto sp1 = std::shared_ptr<Aggregator<T>>(new CounterAggregator<T>(this->kind_));
+ boundAggregators_.insert(std::make_pair(labelset, sp1));
+ sp1->update(value);
+ }
+ else
+ {
+ boundAggregators_[labelset]->update(value);
+ }
+ this->mu_.unlock();
+ }
+
+ /*
+ * Activate the intsrument's callback function to record a measurement. This
+ * function will be called by the specified controller at a regular interval.
+ *
+ * @param none
+ * @return none
+ */
+ virtual void run() override
+ {
+ opentelemetry::metrics::ObserverResult<T> res(this);
+ this->callback_(res);
+ }
+
+ virtual std::vector<Record> GetRecords() override
+ {
+ this->mu_.lock();
+ std::vector<Record> ret;
+ for (auto x : boundAggregators_)
+ {
+ x.second->checkpoint();
+ ret.push_back(Record(this->GetName(), this->GetDescription(), x.first, x.second));
+ }
+ boundAggregators_.clear();
+ this->mu_.unlock();
+ return ret;
+ }
+
+ // Public mapping from labels (stored as strings) to their respective aggregators
+ std::unordered_map<std::string, std::shared_ptr<Aggregator<T>>> boundAggregators_;
+};
+
+# if defined(_MSC_VER)
+# pragma warning(pop)
+# endif
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/controller.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/controller.h
new file mode 100644
index 000000000..66a57a2ef
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/controller.h
@@ -0,0 +1,154 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <atomic>
+# include <iostream>
+# include <sstream>
+# include <thread>
+# include <vector>
+
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/common/macros.h"
+# include "opentelemetry/nostd/unique_ptr.h"
+# include "opentelemetry/sdk/_metrics/exporter.h"
+# include "opentelemetry/sdk/_metrics/meter.h"
+# include "opentelemetry/sdk/_metrics/processor.h"
+# include "opentelemetry/sdk/_metrics/record.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class PushController
+{
+
+public:
+ PushController(nostd::shared_ptr<opentelemetry::metrics::Meter> meter,
+ nostd::unique_ptr<MetricsExporter> exporter,
+ nostd::shared_ptr<MetricsProcessor> processor,
+ double period,
+ int timeout = 30)
+ {
+ meter_ = meter;
+ exporter_ = std::move(exporter);
+ processor_ = processor;
+ timeout_ = (unsigned int)(timeout * 1000000); // convert seconds to microseconds
+ period_ = (unsigned int)(period * 1000000);
+ }
+
+ /*
+ * Used to check if the metrics pipeline is currently active
+ *
+ * @param none
+ * @return true when active, false when on standby. This is a best guess estimate
+ * and the boolean from start() should be used to determine wheher the pipeline
+ * was initiated successfully.
+ */
+ bool isActive() { return active_.load(); }
+
+ /*
+ * Begins the data processing and export pipeline. The function first ensures that the pipeline
+ * is not already running. If not, it begins and detaches a new thread for the Controller's run
+ * function which periodically polls the instruments for their data.
+ *
+ * @param none
+ * @return a boolean which is true when the pipeline is successfully started and false when
+ * already active
+ */
+ bool start()
+ {
+ if (!active_.exchange(true))
+ {
+ runner_ = std::thread(&PushController::run, this);
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * Ends the processing and export pipeline then exports metrics one last time
+ * before returning.
+ *
+ * @param none
+ * @return none
+ */
+ void stop()
+ {
+ if (active_.exchange(false))
+ {
+ if (runner_.joinable())
+ {
+ runner_.join();
+ }
+ tick(); // flush metrics sitting in the processor
+ }
+ }
+
+private:
+ /*
+ * Run the tick function at a regular interval. This function
+ * should be run in its own thread.
+ *
+ * Used to wait between collection intervals.
+ */
+ void run()
+ {
+ if (!running_.exchange(true))
+ {
+ while (active_.load())
+ {
+ tick();
+ std::this_thread::sleep_for(std::chrono::microseconds(period_));
+ }
+ running_.exchange(false);
+ }
+ }
+
+ /*
+ * Tick
+ *
+ * Called at regular intervals, this function collects all values from the
+ * member variable meter_, then sends them to the processor_ for
+ * processing. After the records have been processed they are sent to the
+ * exporter_ to be exported.
+ *
+ */
+ void tick()
+ {
+ this->mu_.lock();
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::vector<Record> collected = dynamic_cast<Meter *>(meter_.get())->Collect();
+# else
+ std::vector<Record> collected = static_cast<Meter *>(meter_.get())->Collect();
+# endif
+ for (const auto &rec : collected)
+ {
+ processor_->process(rec);
+ }
+ collected = processor_->CheckpointSelf();
+ processor_->FinishedCollection();
+ exporter_->Export(collected);
+ this->mu_.unlock();
+ }
+
+ nostd::shared_ptr<opentelemetry::metrics::Meter> meter_;
+ nostd::unique_ptr<MetricsExporter> exporter_;
+ nostd::shared_ptr<MetricsProcessor> processor_;
+ std::thread runner_;
+ std::mutex mu_;
+ std::atomic<bool> active_ = ATOMIC_VAR_INIT(false);
+ std::atomic<bool> running_ = ATOMIC_VAR_INIT(false);
+ unsigned int period_;
+ unsigned int timeout_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/exporter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/exporter.h
new file mode 100644
index 000000000..aae416527
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/exporter.h
@@ -0,0 +1,35 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <memory>
+# include "opentelemetry/sdk/_metrics/record.h"
+# include "opentelemetry/sdk/common/exporter_utils.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+/**
+ * MetricsExporter defines the interface that protocol-specific span exporters must
+ * implement.
+ */
+class MetricsExporter
+{
+public:
+ virtual ~MetricsExporter() = default;
+
+ /**
+ * Exports a vector of Records. This method must not be called
+ * concurrently for the same exporter instance.
+ * @param records a vector of unique pointers to metric records
+ */
+ virtual sdk::common::ExportResult Export(const std::vector<Record> &records) noexcept = 0;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/instrument.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/instrument.h
new file mode 100644
index 000000000..51111be5e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/instrument.h
@@ -0,0 +1,312 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <iostream>
+# include <map>
+# include <memory>
+# include <sstream>
+# include <string>
+# include <unordered_map>
+# include <vector>
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+# include "opentelemetry/sdk/_metrics/record.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+# if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable : 4250) // inheriting methods via dominance
+# endif
+
+class Instrument : virtual public opentelemetry::metrics::Instrument
+{
+
+public:
+ Instrument() = default;
+
+ Instrument(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ opentelemetry::metrics::InstrumentKind kind)
+ : name_(name), description_(description), unit_(unit), enabled_(enabled), kind_(kind)
+ {}
+
+ // Returns true if the instrument is enabled and collecting data
+ virtual bool IsEnabled() override { return enabled_; }
+
+ // Return the instrument name
+ virtual nostd::string_view GetName() override { return name_; }
+
+ // Return the instrument description
+ virtual nostd::string_view GetDescription() override { return description_; }
+
+ // Return the insrument's units of measurement
+ virtual nostd::string_view GetUnits() override { return unit_; }
+
+ virtual opentelemetry::metrics::InstrumentKind GetKind() override { return this->kind_; }
+
+protected:
+ std::string name_;
+ std::string description_;
+ std::string unit_;
+ bool enabled_;
+ std::mutex mu_;
+ opentelemetry::metrics::InstrumentKind kind_;
+};
+
+template <class T>
+class BoundSynchronousInstrument
+ : public Instrument,
+ virtual public opentelemetry::metrics::BoundSynchronousInstrument<T>
+{
+
+public:
+ BoundSynchronousInstrument() = default;
+
+ BoundSynchronousInstrument(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ opentelemetry::metrics::InstrumentKind kind,
+ std::shared_ptr<Aggregator<T>> agg)
+ : Instrument(name, description, unit, enabled, kind), agg_(agg)
+ {
+ this->inc_ref(); // increase reference count when instantiated
+ }
+
+ /**
+ * 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() override
+ {
+ this->mu_.lock();
+ ref_ -= 1;
+ this->mu_.unlock();
+ }
+
+ /**
+ * Increments the reference count. This function is used when binding or instantiating.
+ *
+ * @param none
+ * @return void
+ */
+ virtual void inc_ref() override
+ {
+ this->mu_.lock();
+ ref_ += 1;
+ this->mu_.unlock();
+ }
+
+ /**
+ * Returns the current reference count of the instrument. This value is used to
+ * later in the pipeline remove stale instruments.
+ *
+ * @param none
+ * @return current ref count of the instrument
+ */
+ virtual int get_ref() override
+ {
+ this->mu_.lock();
+ auto ret = ref_;
+ this->mu_.unlock();
+ return ret;
+ }
+
+ /**
+ * Records a single synchronous metric event via 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) override
+ {
+ this->mu_.lock();
+ agg_->update(value);
+ this->mu_.unlock();
+ }
+
+ /**
+ * Returns the aggregator responsible for meaningfully combining update values.
+ *
+ * @param none
+ * @return the aggregator assigned to this instrument
+ */
+ virtual std::shared_ptr<Aggregator<T>> GetAggregator() final { return agg_; }
+
+private:
+ std::shared_ptr<Aggregator<T>> agg_;
+ int ref_ = 0;
+};
+
+template <class T>
+class SynchronousInstrument : public Instrument,
+ virtual public opentelemetry::metrics::SynchronousInstrument<T>
+{
+
+public:
+ SynchronousInstrument() = default;
+
+ SynchronousInstrument(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ opentelemetry::metrics::InstrumentKind kind)
+ : Instrument(name, description, unit, enabled, kind)
+ {}
+
+ /**
+ * 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<opentelemetry::metrics::BoundSynchronousInstrument<T>> bind(
+ const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ return nostd::shared_ptr<BoundSynchronousInstrument<T>>();
+ }
+
+ // This function is necessary for batch recording and should NOT be called by the user
+ virtual void update(T value, const opentelemetry::common::KeyValueIterable &labels) override = 0;
+
+ /**
+ * Checkpoints instruments and returns a set of records which are ready for processing.
+ * This method should ONLY be called by the Meter Class as part of the export pipeline
+ * as it also prunes bound instruments with no active references.
+ *
+ * @param none
+ * @return vector of Records which hold the data attached to this synchronous instrument
+ */
+ virtual std::vector<Record> GetRecords() = 0;
+};
+
+template <class T>
+class AsynchronousInstrument : public Instrument,
+ virtual public opentelemetry::metrics::AsynchronousInstrument<T>
+{
+
+public:
+ AsynchronousInstrument() = default;
+
+ AsynchronousInstrument(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<T>),
+ opentelemetry::metrics::InstrumentKind kind)
+ : Instrument(name, description, unit, enabled, kind)
+ {
+ this->callback_ = callback;
+ }
+
+ /**
+ * 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 opentelemetry::common::KeyValueIterable &labels) override = 0;
+
+ virtual std::vector<Record> GetRecords() = 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;
+};
+
+// Helper functions for turning a common::KeyValueIterable into a string
+inline void print_value(std::stringstream &ss,
+ opentelemetry::common::AttributeValue &value,
+ bool jsonTypes = false)
+{
+ switch (value.index())
+ {
+ case opentelemetry::common::AttributeType::kTypeString:
+
+ ss << nostd::get<nostd::string_view>(value);
+
+ break;
+ default:
+# if __EXCEPTIONS
+ throw std::invalid_argument("Labels must be strings");
+# else
+ std::terminate();
+# endif
+ break;
+ }
+};
+
+// Utility function which converts maps to strings for better performance
+inline std::string mapToString(const std::map<std::string, std::string> &conv)
+{
+ std::stringstream ss;
+ ss << "{";
+ for (auto i : conv)
+ {
+ ss << i.first << ':' << i.second << ',';
+ }
+ ss << "}";
+ return ss.str();
+}
+
+inline std::string KvToString(const opentelemetry::common::KeyValueIterable &kv) noexcept
+{
+ std::stringstream ss;
+ ss << "{";
+ size_t size = kv.size();
+ if (size)
+ {
+ size_t i = 1;
+ kv.ForEachKeyValue(
+ [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
+ ss << key << ":";
+ print_value(ss, value, true);
+ if (size != i)
+ {
+ ss << ",";
+ }
+ i++;
+ return true;
+ });
+ };
+ ss << "}";
+ return ss.str();
+}
+
+# if defined(_MSC_VER)
+# pragma warning(pop)
+# endif
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter.h
new file mode 100644
index 000000000..a91a3ed2b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter.h
@@ -0,0 +1,392 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/_metrics/meter.h"
+# include "opentelemetry/nostd/shared_ptr.h"
+# include "opentelemetry/sdk/_metrics/async_instruments.h"
+# include "opentelemetry/sdk/_metrics/instrument.h"
+# include "opentelemetry/sdk/_metrics/record.h"
+# include "opentelemetry/sdk/_metrics/sync_instruments.h"
+
+# include <unordered_set>
+# include <vector>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class Meter : public opentelemetry::metrics::Meter
+{
+public:
+ explicit Meter(std::string library_name, std::string library_version = "")
+ {
+ library_name_ = library_name;
+ library_version_ = library_version;
+ }
+
+ /**
+ * Creates a Counter with the passed characteristics and returns a shared_ptr to that Counter.
+ *
+ * @param name the name of the new Counter.
+ * @param description a brief description of what the Counter is used for.
+ * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
+ * @param enabled a boolean value that turns on or off the metric instrument.
+ * @return a shared pointer to the created Counter.
+ * @throws invalid_argument exception if name is null or does not conform to OTel syntax.
+ */
+ nostd::shared_ptr<opentelemetry::metrics::Counter<short>> NewShortCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::Counter<int>> NewIntCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::Counter<float>> NewFloatCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::Counter<double>> NewDoubleCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ /**
+ * Creates an UpDownCounter with the passed characteristics and returns a shared_ptr to that
+ * UpDownCounter.
+ *
+ * @param name the name of the new UpDownCounter.
+ * @param description a brief description of what the UpDownCounter is used for.
+ * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
+ * @param enabled a boolean value that turns on or off the metric instrument.
+ * @return a shared pointer to the created UpDownCounter.
+ * @throws invalid_argument exception if name is null or does not conform to OTel syntax.
+ */
+ nostd::shared_ptr<opentelemetry::metrics::UpDownCounter<short>> NewShortUpDownCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownCounter<int>> NewIntUpDownCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownCounter<float>> NewFloatUpDownCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownCounter<double>> NewDoubleUpDownCounter(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ /**
+ * Creates a ValueRecorder with the passed characteristics and returns a shared_ptr to that
+ * ValueRecorder.
+ *
+ * @param name the name of the new ValueRecorder.
+ * @param description a brief description of what the ValueRecorder is used for.
+ * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
+ * @param enabled a boolean value that turns on or off the metric instrument.
+ * @return a shared pointer to the created DoubleValueRecorder.
+ * @throws invalid_argument exception if name is null or does not conform to OTel syntax.
+ */
+ nostd::shared_ptr<opentelemetry::metrics::ValueRecorder<short>> NewShortValueRecorder(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::ValueRecorder<int>> NewIntValueRecorder(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::ValueRecorder<float>> NewFloatValueRecorder(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::ValueRecorder<double>> NewDoubleValueRecorder(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled) override;
+
+ /**
+ * Creates a SumObserver with the passed characteristics and returns a shared_ptr to that
+ * SumObserver.
+ *
+ * @param name the name of the new SumObserver.
+ * @param description a brief description of what the SumObserver is used for.
+ * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
+ * @param enabled a boolean value that turns on or off the metric instrument.
+ * @param callback the function to be observed by the instrument.
+ * @return a shared pointer to the created SumObserver.
+ * @throws invalid_argument exception if name is null or does not conform to OTel syntax.
+ */
+ nostd::shared_ptr<opentelemetry::metrics::SumObserver<short>> NewShortSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<short>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::SumObserver<int>> NewIntSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<int>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::SumObserver<float>> NewFloatSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<float>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::SumObserver<double>> NewDoubleSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double>)) override;
+
+ /**
+ * Creates an UpDownSumObserver with the passed characteristics and returns a shared_ptr to
+ * that UpDowNSumObserver.
+ *
+ * @param name the name of the new UpDownSumObserver.
+ * @param description a brief description of what the UpDownSumObserver is used for.
+ * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
+ * @param enabled a boolean value that turns on or off the metric instrument.
+ * @param callback the function to be observed by the instrument.
+ * @return a shared pointer to the created UpDownSumObserver.
+ * @throws invalid_argument exception if name is null or does not conform to OTel syntax.
+ */
+ nostd::shared_ptr<opentelemetry::metrics::UpDownSumObserver<short>> NewShortUpDownSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<short>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownSumObserver<int>> NewIntUpDownSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<int>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownSumObserver<float>> NewFloatUpDownSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<float>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownSumObserver<double>> NewDoubleUpDownSumObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double>)) override;
+
+ /**
+ * Creates a ValueObserver with the passed characteristics and returns a shared_ptr to that
+ * ValueObserver.
+ *
+ * @param name the name of the new ValueObserver.
+ * @param description a brief description of what the ValueObserver is used for.
+ * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html.
+ * @param enabled a boolean value that turns on or off the metric instrument.
+ * @param callback the function to be observed by the instrument.
+ * @return a shared pointer to the created ValueObserver.
+ * @throws invalid_argument exception if name is null or does not conform to OTel syntax.
+ */
+ nostd::shared_ptr<opentelemetry::metrics::ValueObserver<short>> NewShortValueObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<short>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::ValueObserver<int>> NewIntValueObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<int>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::ValueObserver<float>> NewFloatValueObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<float>)) override;
+
+ nostd::shared_ptr<opentelemetry::metrics::ValueObserver<double>> NewDoubleValueObserver(
+ nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ const bool enabled,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double>)) override;
+
+ /**
+ * Utility method that allows users to atomically record measurements to a set of
+ * synchronous metric instruments with a common set of labels.
+ *
+ * @param labels the set of labels to associate with this recorder.
+ * @param values a span of pairs where the first element of the pair is a metric instrument
+ * to record to, and the second element is the value to update that instrument with.
+ */
+ void RecordShortBatch(
+ const opentelemetry::common::KeyValueIterable &labels,
+ nostd::span<opentelemetry::metrics::SynchronousInstrument<short> *> instruments,
+ nostd::span<const short> values) noexcept override;
+
+ void RecordIntBatch(const opentelemetry::common::KeyValueIterable &labels,
+ nostd::span<opentelemetry::metrics::SynchronousInstrument<int> *> instruments,
+ nostd::span<const int> values) noexcept override;
+
+ void RecordFloatBatch(
+ const opentelemetry::common::KeyValueIterable &labels,
+ nostd::span<opentelemetry::metrics::SynchronousInstrument<float> *> instruments,
+ nostd::span<const float> values) noexcept override;
+
+ void RecordDoubleBatch(
+ const opentelemetry::common::KeyValueIterable &labels,
+ nostd::span<opentelemetry::metrics::SynchronousInstrument<double> *> instruments,
+ nostd::span<const double> values) noexcept override;
+
+ /**
+ * An SDK-only function that checkpoints the aggregators of all instruments created from
+ * this meter, creates a {@code Record} out of them, and sends them for export.
+ *
+ * @return A vector of {@code Records} to be sent to the processor.
+ */
+ std::vector<Record> Collect() noexcept;
+
+private:
+ /**
+ * A private function that creates records from all synchronous instruments created from
+ * this meter.
+ *
+ * @param records A reference to the vector to push the new records to.
+ */
+ void CollectMetrics(std::vector<Record> &records);
+
+ /**
+ * Helper function to collect Records from a single synchronous instrument
+ *
+ * @tparam T The integral type of the instrument to collect from.
+ * @param i A map iterator pointing to the instrument to collect from
+ * @param records The vector to add the new records to.
+ */
+ template <typename T>
+ void CollectSingleSyncInstrument(
+ typename std::map<std::string,
+ std::shared_ptr<opentelemetry::metrics::SynchronousInstrument<T>>>::iterator
+ i,
+ std::vector<Record> &records);
+
+ /**
+ * A private function that creates records from all asynchronous instruments created from
+ * this meter.
+ *
+ * @param records A reference to the vector to push the new records to.
+ */
+ void CollectObservers(std::vector<Record> &records);
+
+ /**
+ * Helper function to collect Records from a single asynchronous instrument
+ *
+ * @tparam T The integral type of the instrument to collect from.
+ * @param i A map iterator pointing to the instrument to collect from
+ * @param records The vector to add the new records to.
+ */
+ template <typename T>
+ void CollectSingleAsyncInstrument(
+ typename std::map<
+ std::string,
+ std::shared_ptr<opentelemetry::metrics::AsynchronousInstrument<T>>>::iterator i,
+ std::vector<Record> &records);
+
+ /**
+ * Utility function used by the meter that checks if a user-passed name abides by OpenTelemetry
+ * naming rules. The rules are as follows:
+ * 1. The name must not be empty.
+ * 2. The name must not start with a digit, a space, or any punctuation.
+ * 3. The name must only have the following chaacters:
+ * All alphanumeric characters, '.', '_' and '-'.
+ *
+ * @param name The name to be examined for legality.
+ * @return A bool representing whether the name is valid by the OpenTelemetry syntax rules.
+ */
+ bool IsValidName(nostd::string_view name);
+
+ /**
+ * A utility function used by the meter to determine whether an instrument of a specified
+ * name already exists in this meter.
+ *
+ * @param name The name to examine.
+ * @return A boolean representing whether the name has already been used by this meter.
+ */
+ bool NameAlreadyUsed(nostd::string_view name);
+
+ /*
+ * All instruments must be stored in a map so the meter can collect on these instruments.
+ * Additionally, when creating a new instrument, the meter must check if an instrument of the same
+ * name already exists.
+ */
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::SynchronousInstrument<short>>>
+ short_metrics_;
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::SynchronousInstrument<int>>>
+ int_metrics_;
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::SynchronousInstrument<float>>>
+ float_metrics_;
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::SynchronousInstrument<double>>>
+ double_metrics_;
+
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::AsynchronousInstrument<short>>>
+ short_observers_;
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::AsynchronousInstrument<int>>>
+ int_observers_;
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::AsynchronousInstrument<float>>>
+ float_observers_;
+ std::map<std::string, std::shared_ptr<opentelemetry::metrics::AsynchronousInstrument<double>>>
+ double_observers_;
+
+ std::unordered_set<std::string> names_;
+
+ std::string library_name_;
+ std::string library_version_;
+
+ std::mutex metrics_lock_;
+ std::mutex observers_lock_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter_provider.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter_provider.h
new file mode 100644
index 000000000..da218ceac
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/meter_provider.h
@@ -0,0 +1,37 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/_metrics/meter_provider.h"
+# include "opentelemetry/nostd/shared_ptr.h"
+# include "opentelemetry/sdk/_metrics/meter.h"
+
+# include <memory>
+# include <string>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class MeterProvider final : public opentelemetry::metrics::MeterProvider
+{
+public:
+ /**
+ * Initialize a new meter provider
+ */
+ explicit MeterProvider(std::string library_name = "", std::string library_version = "") noexcept;
+
+ opentelemetry::nostd::shared_ptr<opentelemetry::metrics::Meter> GetMeter(
+ nostd::string_view library_name,
+ nostd::string_view library_version = "") noexcept override;
+
+private:
+ std::shared_ptr<opentelemetry::metrics::Meter> meter_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/processor.h
new file mode 100644
index 000000000..dd6c421fb
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/processor.h
@@ -0,0 +1,38 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/nostd/string_view.h"
+# include "opentelemetry/sdk/_metrics/record.h"
+# include "opentelemetry/version.h"
+
+# include <iostream>
+# include <string>
+# include <unordered_map>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+
+namespace sdk
+{
+namespace metrics
+{
+
+class MetricsProcessor
+{
+public:
+ virtual ~MetricsProcessor() = default;
+
+ virtual std::vector<opentelemetry::sdk::metrics::Record> CheckpointSelf() noexcept = 0;
+
+ virtual void FinishedCollection() noexcept = 0;
+
+ virtual void process(opentelemetry::sdk::metrics::Record record) noexcept = 0;
+};
+
+} // namespace metrics
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/record.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/record.h
new file mode 100644
index 000000000..a07c1595c
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/record.h
@@ -0,0 +1,50 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <memory>
+# include "opentelemetry/_metrics/instrument.h"
+# include "opentelemetry/nostd/variant.h"
+# include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+
+namespace sdk
+{
+namespace metrics
+{
+using AggregatorVariant = nostd::variant<std::shared_ptr<Aggregator<short>>,
+ std::shared_ptr<Aggregator<int>>,
+ std::shared_ptr<Aggregator<float>>,
+ std::shared_ptr<Aggregator<double>>>;
+class Record
+{
+public:
+ explicit Record(nostd::string_view name,
+ nostd::string_view description,
+ std::string labels,
+ AggregatorVariant aggregator)
+ {
+ name_ = std::string(name);
+ description_ = std::string(description);
+ labels_ = labels;
+ aggregator_ = aggregator;
+ }
+
+ std::string GetName() { return name_; }
+ std::string GetDescription() { return description_; }
+ std::string GetLabels() { return labels_; }
+ AggregatorVariant GetAggregator() { return aggregator_; }
+
+private:
+ std::string name_;
+ std::string description_;
+ std::string labels_;
+ AggregatorVariant aggregator_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h
new file mode 100644
index 000000000..80d9b6092
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h
@@ -0,0 +1,465 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <map>
+# include <memory>
+# include <sstream>
+# include <stdexcept>
+# include <vector>
+
+# include "opentelemetry/_metrics/sync_instruments.h"
+# include "opentelemetry/common/macros.h"
+# include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h"
+# include "opentelemetry/sdk/_metrics/instrument.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+# if defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable : 4250) // inheriting methods via dominance
+# endif
+
+template <class T>
+class BoundCounter final : public BoundSynchronousInstrument<T>,
+ public opentelemetry::metrics::BoundCounter<T>
+{
+
+public:
+ BoundCounter() = default;
+
+ BoundCounter(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled)
+ : BoundSynchronousInstrument<T>(
+ name,
+ description,
+ unit,
+ enabled,
+ opentelemetry::metrics::InstrumentKind::Counter,
+ std::shared_ptr<Aggregator<T>>(new CounterAggregator<T>(
+ opentelemetry::metrics::InstrumentKind::Counter))) // Aggregator is chosen here
+ {}
+
+ /*
+ * 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) override
+ {
+ if (value < 0)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Counter instrument updates must be non-negative.");
+# else
+ std::terminate();
+# endif
+ }
+ else
+ {
+ this->update(value);
+ }
+ }
+};
+
+template <class T>
+class Counter final : public SynchronousInstrument<T>, public opentelemetry::metrics::Counter<T>
+{
+
+public:
+ Counter() = default;
+
+ Counter(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled)
+ : SynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ opentelemetry::metrics::InstrumentKind::Counter)
+ {}
+
+ /*
+ * 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 BoundCounter tied to the specified labels
+ */
+
+ virtual nostd::shared_ptr<opentelemetry::metrics::BoundCounter<T>> bindCounter(
+ const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ this->mu_.lock();
+ std::string labelset = KvToString(labels);
+ if (boundInstruments_.find(labelset) == boundInstruments_.end())
+ {
+ auto sp1 = nostd::shared_ptr<opentelemetry::metrics::BoundCounter<T>>(
+ new BoundCounter<T>(this->name_, this->description_, this->unit_, this->enabled_));
+ boundInstruments_[labelset] = sp1;
+ this->mu_.unlock();
+ return sp1;
+ }
+ else
+ {
+ boundInstruments_[labelset]->inc_ref();
+ auto ret = boundInstruments_[labelset];
+ this->mu_.unlock();
+ return ret;
+ }
+ }
+
+ /*
+ * 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 opentelemetry::common::KeyValueIterable &labels) override
+ {
+ if (value < 0)
+ {
+# if __EXCEPTIONS
+ throw std::invalid_argument("Counter instrument updates must be non-negative.");
+# else
+ std::terminate();
+# endif
+ }
+ else
+ {
+ auto sp = bindCounter(labels);
+ sp->update(value);
+ sp->unbind();
+ }
+ }
+
+ virtual std::vector<Record> GetRecords() override
+ {
+ this->mu_.lock();
+ std::vector<Record> ret;
+ std::vector<std::string> toDelete;
+ for (const auto &x : boundInstruments_)
+ {
+ if (x.second->get_ref() == 0)
+ {
+ toDelete.push_back(x.first);
+ }
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ auto agg_ptr = dynamic_cast<BoundCounter<T> *>(x.second.get())->GetAggregator();
+# else
+ auto agg_ptr = static_cast<BoundCounter<T> *>(x.second.get())->GetAggregator();
+# endif
+ if (agg_ptr->is_updated())
+ {
+ agg_ptr->checkpoint();
+ ret.push_back(Record(x.second->GetName(), x.second->GetDescription(), x.first, agg_ptr));
+ }
+ }
+ for (const auto &x : toDelete)
+ {
+ boundInstruments_.erase(x);
+ }
+ this->mu_.unlock();
+ return ret;
+ }
+
+ virtual void update(T val, const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ add(val, labels);
+ }
+
+ // A collection of the bound instruments created by this unbound instrument identified by their
+ // labels.
+ std::unordered_map<std::string, nostd::shared_ptr<opentelemetry::metrics::BoundCounter<T>>>
+ boundInstruments_;
+};
+
+template <class T>
+class BoundUpDownCounter final : public BoundSynchronousInstrument<T>,
+ virtual public opentelemetry::metrics::BoundUpDownCounter<T>
+{
+
+public:
+ BoundUpDownCounter() = default;
+
+ BoundUpDownCounter(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled)
+ : BoundSynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ opentelemetry::metrics::InstrumentKind::UpDownCounter,
+ std::shared_ptr<Aggregator<T>>(new CounterAggregator<T>(
+ opentelemetry::metrics::InstrumentKind::UpDownCounter)))
+ {}
+
+ /*
+ * 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) override { this->update(value); }
+};
+
+template <class T>
+class UpDownCounter final : public SynchronousInstrument<T>,
+ public opentelemetry::metrics::UpDownCounter<T>
+{
+
+public:
+ UpDownCounter() = default;
+
+ UpDownCounter(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled)
+ : SynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ opentelemetry::metrics::InstrumentKind::UpDownCounter)
+ {}
+
+ /*
+ * 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
+ */
+ nostd::shared_ptr<opentelemetry::metrics::BoundUpDownCounter<T>> bindUpDownCounter(
+ const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ this->mu_.lock();
+ std::string labelset = KvToString(labels);
+ if (boundInstruments_.find(labelset) == boundInstruments_.end())
+ {
+ auto sp1 = nostd::shared_ptr<opentelemetry::metrics::BoundUpDownCounter<T>>(
+ new BoundUpDownCounter<T>(this->name_, this->description_, this->unit_, this->enabled_));
+ boundInstruments_[labelset] = sp1;
+ this->mu_.unlock();
+ return sp1;
+ }
+ else
+ {
+ boundInstruments_[labelset]->inc_ref();
+ auto ret = boundInstruments_[labelset];
+ this->mu_.unlock();
+ return ret;
+ }
+ }
+
+ /*
+ * 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
+ */
+ void add(T value, const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ auto sp = bindUpDownCounter(labels);
+ sp->update(value);
+ sp->unbind();
+ }
+
+ virtual std::vector<Record> GetRecords() override
+ {
+ this->mu_.lock();
+ std::vector<Record> ret;
+ std::vector<std::string> toDelete;
+ for (const auto &x : boundInstruments_)
+ {
+ if (x.second->get_ref() == 0)
+ {
+ toDelete.push_back(x.first);
+ }
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ auto agg_ptr = dynamic_cast<BoundUpDownCounter<T> *>(x.second.get())->GetAggregator();
+# else
+ auto agg_ptr = static_cast<BoundUpDownCounter<T> *>(x.second.get())->GetAggregator();
+# endif
+ if (agg_ptr->is_updated())
+ {
+ agg_ptr->checkpoint();
+ ret.push_back(Record(x.second->GetName(), x.second->GetDescription(), x.first, agg_ptr));
+ }
+ }
+ for (const auto &x : toDelete)
+ {
+ boundInstruments_.erase(x);
+ }
+ this->mu_.unlock();
+ return ret;
+ }
+
+ virtual void update(T val, const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ add(val, labels);
+ }
+
+ std::unordered_map<std::string, nostd::shared_ptr<opentelemetry::metrics::BoundUpDownCounter<T>>>
+ boundInstruments_;
+};
+
+template <class T>
+class BoundValueRecorder final : public BoundSynchronousInstrument<T>,
+ public opentelemetry::metrics::BoundValueRecorder<T>
+{
+
+public:
+ BoundValueRecorder() = default;
+
+ BoundValueRecorder(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled)
+ : BoundSynchronousInstrument<T>(
+ name,
+ description,
+ unit,
+ enabled,
+ opentelemetry::metrics::InstrumentKind::ValueRecorder,
+ std::shared_ptr<Aggregator<T>>(new MinMaxSumCountAggregator<T>(
+ opentelemetry::metrics::InstrumentKind::ValueRecorder)))
+ {}
+
+ /*
+ * 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
+ */
+ void record(T value) { this->update(value); }
+};
+
+template <class T>
+class ValueRecorder final : public SynchronousInstrument<T>,
+ public opentelemetry::metrics::ValueRecorder<T>
+{
+
+public:
+ ValueRecorder() = default;
+
+ ValueRecorder(nostd::string_view name,
+ nostd::string_view description,
+ nostd::string_view unit,
+ bool enabled)
+ : SynchronousInstrument<T>(name,
+ description,
+ unit,
+ enabled,
+ opentelemetry::metrics::InstrumentKind::ValueRecorder)
+ {}
+
+ /*
+ * 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
+ */
+ nostd::shared_ptr<opentelemetry::metrics::BoundValueRecorder<T>> bindValueRecorder(
+ const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ this->mu_.lock();
+ std::string labelset = KvToString(labels);
+ if (boundInstruments_.find(labelset) == boundInstruments_.end())
+ {
+ auto sp1 = nostd::shared_ptr<opentelemetry::metrics::BoundValueRecorder<T>>(
+ new BoundValueRecorder<T>(this->name_, this->description_, this->unit_, this->enabled_));
+ boundInstruments_[labelset] = sp1;
+ this->mu_.unlock();
+ return sp1;
+ }
+ else
+ {
+ boundInstruments_[labelset]->inc_ref();
+ auto ret = boundInstruments_[labelset];
+ this->mu_.unlock();
+ return ret;
+ }
+ }
+
+ /*
+ * 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
+ */
+ void record(T value, const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ auto sp = bindValueRecorder(labels);
+ sp->update(value);
+ sp->unbind();
+ }
+
+ virtual std::vector<Record> GetRecords() override
+ {
+ this->mu_.lock();
+ std::vector<Record> ret;
+ std::vector<std::string> toDelete;
+ for (const auto &x : boundInstruments_)
+ {
+ if (x.second->get_ref() == 0)
+ {
+ toDelete.push_back(x.first);
+ }
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ auto agg_ptr = dynamic_cast<BoundValueRecorder<T> *>(x.second.get())->GetAggregator();
+# else
+ auto agg_ptr = static_cast<BoundValueRecorder<T> *>(x.second.get())->GetAggregator();
+# endif
+ if (agg_ptr->is_updated())
+ {
+ agg_ptr->checkpoint();
+ ret.push_back(Record(x.second->GetName(), x.second->GetDescription(), x.first, agg_ptr));
+ }
+ }
+ for (const auto &x : toDelete)
+ {
+ boundInstruments_.erase(x);
+ }
+ this->mu_.unlock();
+ return ret;
+ }
+
+ virtual void update(T value, const opentelemetry::common::KeyValueIterable &labels) override
+ {
+ record(value, labels);
+ }
+
+ std::unordered_map<std::string, nostd::shared_ptr<opentelemetry::metrics::BoundValueRecorder<T>>>
+ boundInstruments_;
+};
+
+# if defined(_MSC_VER)
+# pragma warning(pop)
+# endif
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h
new file mode 100644
index 000000000..cc13ae52b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h
@@ -0,0 +1,365 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_METRICS_PREVIEW
+
+# include <map>
+
+# include "opentelemetry/common/macros.h"
+# include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/exact_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/gauge_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/histogram_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h"
+# include "opentelemetry/sdk/_metrics/aggregator/sketch_aggregator.h"
+# include "opentelemetry/sdk/_metrics/processor.h"
+# include "opentelemetry/sdk/_metrics/record.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+
+namespace sdk
+{
+
+namespace metrics
+{
+
+struct KeyStruct
+{
+ std::string name;
+ std::string description;
+ std::string labels;
+ opentelemetry::metrics::InstrumentKind ins_kind;
+
+ // constructor
+ KeyStruct(std::string name,
+ std::string description,
+ std::string labels,
+ opentelemetry::metrics::InstrumentKind ins_kind)
+ {
+ this->name = name;
+ this->description = description;
+ this->labels = labels;
+ this->ins_kind = ins_kind;
+ }
+
+ // operator== is required to compare keys in case of hash collision
+ bool operator==(const KeyStruct &p) const
+ {
+ return name == p.name && description == p.description && labels == p.labels &&
+ ins_kind == p.ins_kind;
+ }
+};
+
+struct KeyStruct_Hash
+{
+ std::size_t operator()(const KeyStruct &keystruct) const
+ {
+ std::size_t name_size = keystruct.name.length();
+ std::size_t desc_size = keystruct.description.length();
+ std::size_t labels_size = keystruct.labels.length();
+ std::size_t ins_size = (int)keystruct.ins_kind;
+
+ return (name_size ^ desc_size ^ labels_size) + ins_size;
+ }
+};
+
+class UngroupedMetricsProcessor : public MetricsProcessor
+{
+public:
+ explicit UngroupedMetricsProcessor(bool stateful);
+
+ std::vector<opentelemetry::sdk::metrics::Record> CheckpointSelf() noexcept override;
+
+ virtual void FinishedCollection() noexcept override;
+
+ virtual void process(opentelemetry::sdk::metrics::Record record) noexcept override;
+
+private:
+ bool stateful_;
+ std::unordered_map<KeyStruct, opentelemetry::sdk::metrics::AggregatorVariant, KeyStruct_Hash>
+ batch_map_;
+
+ /**
+ * get_instrument returns the instrument from the passed in AggregatorVariant. We have to
+ * unpack the variant then get the instrument from the Aggreagtor.
+ */
+ opentelemetry::metrics::InstrumentKind get_instrument(
+ opentelemetry::sdk::metrics::AggregatorVariant aggregator)
+ {
+ if (nostd::holds_alternative<std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<short>>>(
+ aggregator))
+ {
+ return nostd::get<std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<short>>>(aggregator)
+ ->get_instrument_kind();
+ }
+ else if (nostd::holds_alternative<
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<int>>>(aggregator))
+ {
+ return nostd::get<std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<int>>>(aggregator)
+ ->get_instrument_kind();
+ }
+ else if (nostd::holds_alternative<
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<float>>>(aggregator))
+ {
+ return nostd::get<std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<float>>>(aggregator)
+ ->get_instrument_kind();
+ }
+ else if (nostd::holds_alternative<
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<double>>>(aggregator))
+ {
+ return nostd::get<std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<double>>>(
+ aggregator)
+ ->get_instrument_kind();
+ }
+
+ return opentelemetry::metrics::InstrumentKind::Counter;
+ }
+
+ /**
+ * aggregator_copy creates a copy of the aggregtor passed through process() for a
+ * stateful processor. For Sketch, Histogram and Exact we also need to pass in
+ * additional constructor values
+ */
+ template <typename T>
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>> aggregator_copy(
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>> aggregator)
+ {
+ auto ins_kind = aggregator->get_instrument_kind();
+ auto agg_kind = aggregator->get_aggregator_kind();
+
+ switch (agg_kind)
+ {
+ case opentelemetry::sdk::metrics::AggregatorKind::Counter:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+
+ case opentelemetry::sdk::metrics::AggregatorKind::MinMaxSumCount:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>(ins_kind));
+
+ case opentelemetry::sdk::metrics::AggregatorKind::Gauge:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::GaugeAggregator<T>(ins_kind));
+
+ case opentelemetry::sdk::metrics::AggregatorKind::Sketch:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::SketchAggregator<T>(
+ ins_kind, aggregator->get_error_bound(), aggregator->get_max_buckets()));
+
+ case opentelemetry::sdk::metrics::AggregatorKind::Histogram:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::HistogramAggregator<T>(ins_kind,
+ aggregator->get_boundaries()));
+
+ case opentelemetry::sdk::metrics::AggregatorKind::Exact:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::ExactAggregator<T>(
+ ins_kind, aggregator->get_quant_estimation()));
+
+ default:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+ }
+ };
+
+ /**
+ * aggregator_for will return an Aggregator based off the instrument passed in. This should be
+ * the function that we assign Aggreagtors for instruments, but is currently unused in our
+ * pipeline.
+ */
+ template <typename T>
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>> aggregator_for(
+ opentelemetry::metrics::InstrumentKind ins_kind)
+ {
+ switch (ins_kind)
+ {
+ case opentelemetry::metrics::InstrumentKind::Counter:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+
+ case opentelemetry::metrics::InstrumentKind::UpDownCounter:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+
+ case opentelemetry::metrics::InstrumentKind::ValueRecorder:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>(ins_kind));
+
+ case opentelemetry::metrics::InstrumentKind::SumObserver:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+
+ case opentelemetry::metrics::InstrumentKind::UpDownSumObserver:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+
+ case opentelemetry::metrics::InstrumentKind::ValueObserver:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>(ins_kind));
+
+ default:
+ return std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>>(
+ new opentelemetry::sdk::metrics::CounterAggregator<T>(ins_kind));
+ }
+ };
+
+ /**
+ * merge_aggreagtors takes in two shared pointers to aggregators of the same kind.
+ * We first need to dynamically cast to the actual Aggregator that is held in the
+ * Aggregator<T> wrapper. Then we must get the underlying pointer from the shared
+ * pointer and merge them together.
+ */
+ template <typename T>
+ void merge_aggregators(std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>> batch_agg,
+ std::shared_ptr<opentelemetry::sdk::metrics::Aggregator<T>> record_agg)
+ {
+ auto agg_kind = batch_agg->get_aggregator_kind();
+ if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Counter)
+ {
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::shared_ptr<opentelemetry::sdk::metrics::CounterAggregator<T>> temp_batch_agg_counter =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::CounterAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::CounterAggregator<T>> temp_record_agg_counter =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::CounterAggregator<T>>(record_agg);
+# else
+ std::shared_ptr<opentelemetry::sdk::metrics::CounterAggregator<T>> temp_batch_agg_counter =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::CounterAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::CounterAggregator<T>> temp_record_agg_counter =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::CounterAggregator<T>>(record_agg);
+# endif
+ auto temp_batch_agg_raw_counter = temp_batch_agg_counter.get();
+ auto temp_record_agg_raw_counter = temp_record_agg_counter.get();
+
+ temp_batch_agg_raw_counter->merge(*temp_record_agg_raw_counter);
+ }
+ else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::MinMaxSumCount)
+ {
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::shared_ptr<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>
+ temp_batch_agg_mmsc =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>(
+ batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>
+ temp_record_agg_mmsc =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>(
+ record_agg);
+# else
+ std::shared_ptr<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>
+ temp_batch_agg_mmsc =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>(
+ batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>
+ temp_record_agg_mmsc =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::MinMaxSumCountAggregator<T>>(
+ record_agg);
+# endif
+
+ auto temp_batch_agg_raw_mmsc = temp_batch_agg_mmsc.get();
+ auto temp_record_agg_raw_mmsc = temp_record_agg_mmsc.get();
+
+ temp_batch_agg_raw_mmsc->merge(*temp_record_agg_raw_mmsc);
+ }
+ else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Gauge)
+ {
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::shared_ptr<opentelemetry::sdk::metrics::GaugeAggregator<T>> temp_batch_agg_gauge =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::GaugeAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::GaugeAggregator<T>> temp_record_agg_gauge =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::GaugeAggregator<T>>(record_agg);
+# else
+ std::shared_ptr<opentelemetry::sdk::metrics::GaugeAggregator<T>> temp_batch_agg_gauge =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::GaugeAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::GaugeAggregator<T>> temp_record_agg_gauge =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::GaugeAggregator<T>>(record_agg);
+# endif
+
+ auto temp_batch_agg_raw_gauge = temp_batch_agg_gauge.get();
+ auto temp_record_agg_raw_gauge = temp_record_agg_gauge.get();
+
+ temp_batch_agg_raw_gauge->merge(*temp_record_agg_raw_gauge);
+ }
+ else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Sketch)
+ {
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::shared_ptr<opentelemetry::sdk::metrics::SketchAggregator<T>> temp_batch_agg_sketch =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::SketchAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::SketchAggregator<T>> temp_record_agg_sketch =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::SketchAggregator<T>>(record_agg);
+# else
+ std::shared_ptr<opentelemetry::sdk::metrics::SketchAggregator<T>> temp_batch_agg_sketch =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::SketchAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::SketchAggregator<T>> temp_record_agg_sketch =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::SketchAggregator<T>>(record_agg);
+# endif
+ auto temp_batch_agg_raw_sketch = temp_batch_agg_sketch.get();
+ auto temp_record_agg_raw_sketch = temp_record_agg_sketch.get();
+
+ temp_batch_agg_raw_sketch->merge(*temp_record_agg_raw_sketch);
+ }
+ else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Histogram)
+ {
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::shared_ptr<opentelemetry::sdk::metrics::HistogramAggregator<T>>
+ temp_batch_agg_histogram =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::HistogramAggregator<T>>(
+ batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::HistogramAggregator<T>>
+ temp_record_agg_histogram =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::HistogramAggregator<T>>(
+ record_agg);
+# else
+ std::shared_ptr<opentelemetry::sdk::metrics::HistogramAggregator<T>>
+ temp_batch_agg_histogram =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::HistogramAggregator<T>>(
+ batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::HistogramAggregator<T>>
+ temp_record_agg_histogram =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::HistogramAggregator<T>>(
+ record_agg);
+# endif
+
+ auto temp_batch_agg_raw_histogram = temp_batch_agg_histogram.get();
+ auto temp_record_agg_raw_histogram = temp_record_agg_histogram.get();
+
+ temp_batch_agg_raw_histogram->merge(*temp_record_agg_raw_histogram);
+ }
+ else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Exact)
+ {
+# ifdef OPENTELEMETRY_RTTI_ENABLED
+ std::shared_ptr<opentelemetry::sdk::metrics::ExactAggregator<T>> temp_batch_agg_exact =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::ExactAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::ExactAggregator<T>> temp_record_agg_exact =
+ std::dynamic_pointer_cast<opentelemetry::sdk::metrics::ExactAggregator<T>>(record_agg);
+# else
+ std::shared_ptr<opentelemetry::sdk::metrics::ExactAggregator<T>> temp_batch_agg_exact =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::ExactAggregator<T>>(batch_agg);
+
+ std::shared_ptr<opentelemetry::sdk::metrics::ExactAggregator<T>> temp_record_agg_exact =
+ std::static_pointer_cast<opentelemetry::sdk::metrics::ExactAggregator<T>>(record_agg);
+# endif
+
+ auto temp_batch_agg_raw_exact = temp_batch_agg_exact.get();
+ auto temp_record_agg_raw_exact = temp_record_agg_exact.get();
+
+ temp_batch_agg_raw_exact->merge(*temp_record_agg_raw_exact);
+ }
+ }
+};
+} // namespace metrics
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_shared_ptr.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_shared_ptr.h
new file mode 100644
index 000000000..07e19ac0f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_shared_ptr.h
@@ -0,0 +1,62 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+/**
+ * A wrapper to provide atomic shared pointers.
+ *
+ * This wrapper relies on a mutex for gcc 4.8, and specializations of
+ * std::atomic_store and std::atomic_load for all other instances.
+ */
+#if (__GNUC__ == 4 && (__GNUC_MINOR__ >= 8))
+template <class T>
+class AtomicSharedPtr
+{
+public:
+ explicit AtomicSharedPtr(std::shared_ptr<T> ptr) noexcept : ptr_{std::move(ptr)} {}
+
+ void store(const std::shared_ptr<T> &other) noexcept
+ {
+ std::lock_guard<std::mutex> lock_guard{mu_};
+ ptr_ = other;
+ }
+
+ std::shared_ptr<T> load() const noexcept
+ {
+ std::lock_guard<std::mutex> lock_guard{mu_};
+ return ptr_;
+ }
+
+private:
+ std::shared_ptr<T> ptr_;
+ mutable std::mutex mu_;
+};
+#else
+template <class T>
+class AtomicSharedPtr
+{
+public:
+ explicit AtomicSharedPtr(std::shared_ptr<T> ptr) noexcept : ptr_{std::move(ptr)} {}
+
+ void store(const std::shared_ptr<T> &other) noexcept { std::atomic_store(&ptr_, other); }
+
+ std::shared_ptr<T> load() const noexcept { return std::atomic_load(&ptr_); }
+
+private:
+ std::shared_ptr<T> ptr_;
+};
+#endif
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h
new file mode 100644
index 000000000..5945df98c
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h
@@ -0,0 +1,87 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <atomic>
+#include <memory>
+
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+/**
+ * An owning pointer similar to std::unique_ptr but with methods for atomic
+ * operations.
+ */
+template <class T>
+class AtomicUniquePtr
+{
+public:
+ AtomicUniquePtr() noexcept {}
+
+ explicit AtomicUniquePtr(std::unique_ptr<T> &&other) noexcept : ptr_(other.release()) {}
+
+ ~AtomicUniquePtr() noexcept { Reset(); }
+
+ T &operator*() const noexcept { return *Get(); }
+
+ T *operator->() const noexcept { return Get(); }
+
+ /**
+ * @return the underly pointer managed.
+ */
+ T *Get() const noexcept { return ptr_; }
+
+ /**
+ * @return true if the pointer is null
+ */
+ bool IsNull() const noexcept { return ptr_.load() == nullptr; }
+
+ /**
+ * Atomically swap the pointer only if it's null.
+ * @param owner the pointer to swap with
+ * @return true if the swap was successful
+ */
+ bool SwapIfNull(std::unique_ptr<T> &owner) noexcept
+ {
+ auto ptr = owner.get();
+ T *expected = nullptr;
+ auto was_successful = ptr_.compare_exchange_weak(expected, ptr, std::memory_order_release,
+ std::memory_order_relaxed);
+ if (was_successful)
+ {
+ owner.release();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Atomically swap the pointer with another.
+ * @param ptr the pointer to swap with
+ */
+ void Swap(std::unique_ptr<T> &other) noexcept { other.reset(ptr_.exchange(other.release())); }
+
+ /**
+ * Set the pointer to a new value and delete the current value if non-null.
+ * @param ptr the new pointer value to set
+ */
+ void Reset(T *ptr = nullptr) noexcept
+ {
+ ptr = ptr_.exchange(ptr);
+ if (ptr != nullptr)
+ {
+ delete ptr;
+ }
+ }
+
+private:
+ std::atomic<T *> ptr_{nullptr};
+};
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attribute_utils.h
new file mode 100644
index 000000000..68b09f044
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attribute_utils.h
@@ -0,0 +1,199 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <map>
+#include <string>
+#include <unordered_map>
+#include <vector>
+#include "opentelemetry/common/attribute_value.h"
+#include "opentelemetry/common/key_value_iterable_view.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+/**
+ * A counterpart to AttributeValue that makes sure a value is owned. This
+ * replaces all non-owning references with owned copies.
+ *
+ * The following types are not currently supported by the OpenTelemetry
+ * specification, but reserved for future use:
+ * - uint64_t
+ * - std::vector<uint64_t>
+ * - std::vector<uint8_t>
+ */
+using OwnedAttributeValue = nostd::variant<bool,
+ int32_t,
+ uint32_t,
+ int64_t,
+ double,
+ std::string,
+ std::vector<bool>,
+ std::vector<int32_t>,
+ std::vector<uint32_t>,
+ std::vector<int64_t>,
+ std::vector<double>,
+ std::vector<std::string>,
+ uint64_t,
+ std::vector<uint64_t>,
+ std::vector<uint8_t>>;
+
+enum OwnedAttributeType
+{
+ kTypeBool,
+ kTypeInt,
+ kTypeUInt,
+ kTypeInt64,
+ kTypeDouble,
+ kTypeString,
+ kTypeSpanBool,
+ kTypeSpanInt,
+ kTypeSpanUInt,
+ kTypeSpanInt64,
+ kTypeSpanDouble,
+ kTypeSpanString,
+ kTypeUInt64,
+ kTypeSpanUInt64,
+ kTypeSpanByte
+};
+
+/**
+ * Creates an owned copy (OwnedAttributeValue) of a non-owning AttributeValue.
+ */
+struct AttributeConverter
+{
+ OwnedAttributeValue operator()(bool v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(int32_t v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(uint32_t v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(int64_t v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(uint64_t v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(double v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(nostd::string_view v)
+ {
+ return OwnedAttributeValue(std::string(v));
+ }
+ OwnedAttributeValue operator()(std::string v) { return OwnedAttributeValue(v); }
+ OwnedAttributeValue operator()(const char *v) { return OwnedAttributeValue(std::string(v)); }
+ OwnedAttributeValue operator()(nostd::span<const uint8_t> v) { return convertSpan<uint8_t>(v); }
+ OwnedAttributeValue operator()(nostd::span<const bool> v) { return convertSpan<bool>(v); }
+ OwnedAttributeValue operator()(nostd::span<const int32_t> v) { return convertSpan<int32_t>(v); }
+ OwnedAttributeValue operator()(nostd::span<const uint32_t> v) { return convertSpan<uint32_t>(v); }
+ OwnedAttributeValue operator()(nostd::span<const int64_t> v) { return convertSpan<int64_t>(v); }
+ OwnedAttributeValue operator()(nostd::span<const uint64_t> v) { return convertSpan<uint64_t>(v); }
+ OwnedAttributeValue operator()(nostd::span<const double> v) { return convertSpan<double>(v); }
+ OwnedAttributeValue operator()(nostd::span<const nostd::string_view> v)
+ {
+ return convertSpan<std::string>(v);
+ }
+
+ template <typename T, typename U = T>
+ OwnedAttributeValue convertSpan(nostd::span<const U> vals)
+ {
+ const std::vector<T> copy(vals.begin(), vals.end());
+ return OwnedAttributeValue(std::move(copy));
+ }
+};
+
+/**
+ * Class for storing attributes.
+ */
+class AttributeMap : public std::unordered_map<std::string, OwnedAttributeValue>
+{
+public:
+ // Contruct empty attribute map
+ AttributeMap() : std::unordered_map<std::string, OwnedAttributeValue>(){};
+
+ // Contruct attribute map and populate with attributes
+ AttributeMap(const opentelemetry::common::KeyValueIterable &attributes) : AttributeMap()
+ {
+ attributes.ForEachKeyValue(
+ [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
+ SetAttribute(key, value);
+ return true;
+ });
+ }
+
+ // Construct map from initializer list by applying `SetAttribute` transform for every attribute
+ AttributeMap(
+ std::initializer_list<std::pair<nostd::string_view, opentelemetry::common::AttributeValue>>
+ attributes)
+ : AttributeMap()
+ {
+ for (auto &kv : attributes)
+ {
+ SetAttribute(kv.first, kv.second);
+ }
+ }
+
+ // Returns a reference to this map
+ const std::unordered_map<std::string, OwnedAttributeValue> &GetAttributes() const noexcept
+ {
+ return (*this);
+ }
+
+ // Convert non-owning key-value to owning std::string(key) and OwnedAttributeValue(value)
+ void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept
+ {
+ (*this)[std::string(key)] = nostd::visit(converter_, value);
+ }
+
+private:
+ AttributeConverter converter_;
+};
+
+/**
+ * Class for storing attributes.
+ */
+class OrderedAttributeMap : public std::map<std::string, OwnedAttributeValue>
+{
+public:
+ // Contruct empty attribute map
+ OrderedAttributeMap() : std::map<std::string, OwnedAttributeValue>(){};
+
+ // Contruct attribute map and populate with attributes
+ OrderedAttributeMap(const opentelemetry::common::KeyValueIterable &attributes)
+ : OrderedAttributeMap()
+ {
+ attributes.ForEachKeyValue(
+ [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
+ SetAttribute(key, value);
+ return true;
+ });
+ }
+
+ // Construct map from initializer list by applying `SetAttribute` transform for every attribute
+ OrderedAttributeMap(
+ std::initializer_list<std::pair<nostd::string_view, opentelemetry::common::AttributeValue>>
+ attributes)
+ : OrderedAttributeMap()
+ {
+ for (auto &kv : attributes)
+ {
+ SetAttribute(kv.first, kv.second);
+ }
+ }
+
+ // Returns a reference to this map
+ const std::map<std::string, OwnedAttributeValue> &GetAttributes() const noexcept
+ {
+ return (*this);
+ }
+
+ // Convert non-owning key-value to owning std::string(key) and OwnedAttributeValue(value)
+ void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept
+ {
+ (*this)[std::string(key)] = nostd::visit(converter_, value);
+ }
+
+private:
+ AttributeConverter converter_;
+};
+
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attributemap_hash.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attributemap_hash.h
new file mode 100644
index 000000000..573f57eb1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/attributemap_hash.h
@@ -0,0 +1,62 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <iostream>
+#include <string>
+#include "opentelemetry/sdk/common/attribute_utils.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+
+template <class T>
+inline void GetHashForAttributeValue(size_t &seed, const T arg)
+{
+ std::hash<T> hasher;
+ // reference -
+ // https://www.boost.org/doc/libs/1_37_0/doc/html/hash/reference.html#boost.hash_combine
+ seed ^= hasher(arg) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+}
+
+template <class T>
+inline void GetHashForAttributeValue(size_t &seed, const std::vector<T> &arg)
+{
+ for (auto v : arg)
+ {
+ GetHashForAttributeValue<T>(seed, v);
+ }
+}
+
+struct GetHashForAttributeValueVisitor
+{
+ GetHashForAttributeValueVisitor(size_t &seed) : seed_(seed) {}
+ template <class T>
+ void operator()(T &v)
+ {
+ GetHashForAttributeValue(seed_, v);
+ }
+ size_t &seed_;
+};
+
+// Calculate hash of keys and values of attribute map
+inline size_t GetHashForAttributeMap(const OrderedAttributeMap &attribute_map)
+{
+ size_t seed = 0UL;
+ for (auto &kv : attribute_map)
+ {
+ std::hash<std::string> hasher;
+ // reference -
+ // https://www.boost.org/doc/libs/1_37_0/doc/html/hash/reference.html#boost.hash_combine
+ seed ^= hasher(kv.first) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ nostd::visit(GetHashForAttributeValueVisitor(seed), kv.second);
+ }
+ return seed;
+}
+
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer.h
new file mode 100644
index 000000000..6af900183
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer.h
@@ -0,0 +1,186 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <atomic>
+#include <cstdint>
+#include <memory>
+
+#include "opentelemetry/sdk/common/atomic_unique_ptr.h"
+#include "opentelemetry/sdk/common/circular_buffer_range.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+/*
+ * A lock-free circular buffer that supports multiple concurrent producers
+ * and a single consumer.
+ */
+template <class T>
+class CircularBuffer
+{
+public:
+ explicit CircularBuffer(size_t max_size)
+ : data_{new AtomicUniquePtr<T>[max_size + 1]}, capacity_{max_size + 1}
+ {}
+
+ /**
+ * @return a range of the elements in the circular buffer
+ *
+ * Note: This method must only be called from the consumer thread.
+ */
+ CircularBufferRange<const AtomicUniquePtr<T>> Peek() const noexcept
+ {
+ return const_cast<CircularBuffer *>(this)->PeekImpl();
+ }
+
+ /**
+ * Consume elements from the circular buffer's tail.
+ * @param n the number of elements to consume
+ * @param callback the callback to invoke with an AtomicUniquePtr to each
+ * consumed element.
+ *
+ * Note: The callback must set the passed AtomicUniquePtr to null.
+ *
+ * Note: This method must only be called from the consumer thread.
+ */
+ template <class Callback>
+ void Consume(size_t n, Callback callback) noexcept
+ {
+ assert(n <= static_cast<size_t>(head_ - tail_));
+ auto range = PeekImpl().Take(n);
+ static_assert(noexcept(callback(range)), "callback not allowed to throw");
+ tail_ += n;
+ callback(range);
+ }
+
+ /**
+ * Consume elements from the circular buffer's tail.
+ * @param n the number of elements to consume
+ *
+ * Note: This method must only be called from the consumer thread.
+ */
+ void Consume(size_t n) noexcept
+ {
+ Consume(n, [](CircularBufferRange<AtomicUniquePtr<T>> &range) noexcept {
+ range.ForEach([](AtomicUniquePtr<T> &ptr) noexcept {
+ ptr.Reset();
+ return true;
+ });
+ });
+ }
+
+ /**
+ * Adds an element into the circular buffer.
+ * @param ptr a pointer to the element to add
+ * @return true if the element was successfully added; false, otherwise.
+ */
+ bool Add(std::unique_ptr<T> &ptr) noexcept
+ {
+ while (true)
+ {
+ uint64_t tail = tail_;
+ uint64_t head = head_;
+
+ // The circular buffer is full, so return false.
+ if (head - tail >= capacity_ - 1)
+ {
+ return false;
+ }
+
+ uint64_t head_index = head % capacity_;
+ if (data_[head_index].SwapIfNull(ptr))
+ {
+ auto new_head = head + 1;
+ auto expected_head = head;
+ if (head_.compare_exchange_weak(expected_head, new_head, std::memory_order_release,
+ std::memory_order_relaxed))
+ {
+ // free the swapped out value
+ ptr.reset();
+
+ return true;
+ }
+
+ // If we reached this point (unlikely), it means that between the last
+ // iteration elements were added and then consumed from the circular
+ // buffer, so we undo the swap and attempt to add again.
+ data_[head_index].Swap(ptr);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Clear the circular buffer.
+ *
+ * Note: This method must only be called from the consumer thread.
+ */
+ void Clear() noexcept { Consume(size()); }
+
+ /**
+ * @return the maximum number of bytes that can be stored in the buffer.
+ */
+ size_t max_size() const noexcept { return capacity_ - 1; }
+
+ /**
+ * @return true if the buffer is empty.
+ */
+ bool empty() const noexcept { return head_ == tail_; }
+
+ /**
+ * @return the number of bytes stored in the circular buffer.
+ *
+ * Note: this method will only return a correct snapshot of the size if called
+ * from the consumer thread.
+ */
+ size_t size() const noexcept
+ {
+ uint64_t tail = tail_;
+ uint64_t head = head_;
+ assert(tail <= head);
+ return head - tail;
+ }
+
+ /**
+ * @return the number of elements consumed from the circular buffer.
+ */
+ uint64_t consumption_count() const noexcept { return tail_; }
+
+ /**
+ * @return the number of elements added to the circular buffer.
+ */
+ uint64_t production_count() const noexcept { return head_; }
+
+private:
+ std::unique_ptr<AtomicUniquePtr<T>[]> data_;
+ size_t capacity_;
+ std::atomic<uint64_t> head_{0};
+ std::atomic<uint64_t> tail_{0};
+
+ CircularBufferRange<AtomicUniquePtr<T>> PeekImpl() noexcept
+ {
+ uint64_t tail_index = tail_ % capacity_;
+ uint64_t head_index = head_ % capacity_;
+ if (head_index == tail_index)
+ {
+ return {};
+ }
+ auto data = data_.get();
+ if (tail_index < head_index)
+ {
+ return CircularBufferRange<AtomicUniquePtr<T>>{nostd::span<AtomicUniquePtr<T>>{
+ data + tail_index, static_cast<std::size_t>(head_index - tail_index)}};
+ }
+ return {nostd::span<AtomicUniquePtr<T>>{data + tail_index,
+ static_cast<std::size_t>(capacity_ - tail_index)},
+ nostd::span<AtomicUniquePtr<T>>{data, static_cast<std::size_t>(head_index)}};
+ }
+};
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer_range.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer_range.h
new file mode 100644
index 000000000..9ef3b66be
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/circular_buffer_range.h
@@ -0,0 +1,93 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <cassert>
+#include <iterator>
+#include <type_traits>
+#include <utility>
+
+#include "opentelemetry/nostd/span.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+/**
+ * A non-owning view into a range of elements in a circular buffer.
+ */
+template <class T>
+class CircularBufferRange
+{
+public:
+ CircularBufferRange() noexcept = default;
+
+ explicit CircularBufferRange(nostd::span<T> first) noexcept : first_{first} {}
+
+ CircularBufferRange(nostd::span<T> first, nostd::span<T> second) noexcept
+ : first_{first}, second_{second}
+ {}
+
+ operator CircularBufferRange<const T>() const noexcept { return {first_, second_}; }
+
+ /**
+ * Iterate over the elements in the range.
+ * @param callback the callback to call for each element
+ * @return true if we iterated over all elements
+ */
+ template <class Callback>
+ bool ForEach(Callback callback) const
+ noexcept(noexcept(std::declval<Callback>()(std::declval<T &>())))
+ {
+ for (auto &value : first_)
+ {
+ if (!callback(value))
+ {
+ return false;
+ }
+ }
+ for (auto &value : second_)
+ {
+ if (!callback(value))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return the number of elements in the range
+ */
+ size_t size() const noexcept { return first_.size() + second_.size(); }
+
+ /**
+ * @return true if the range is empty
+ */
+ bool empty() const noexcept { return first_.empty(); }
+
+ /**
+ * Return a subrange taken from the start of this range.
+ * @param n the number of element to take in the subrange
+ * @return a subrange of the first n elements in this range
+ */
+ CircularBufferRange Take(size_t n) const noexcept
+ {
+ assert(n <= size());
+ if (first_.size() >= n)
+ {
+ return CircularBufferRange{nostd::span<T>{first_.data(), n}};
+ }
+ return {first_, nostd::span<T>{second_.data(), n - first_.size()}};
+ }
+
+private:
+ nostd::span<T> first_;
+ nostd::span<T> second_;
+};
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/empty_attributes.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/empty_attributes.h
new file mode 100644
index 000000000..4f740bf10
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/empty_attributes.h
@@ -0,0 +1,34 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/common/key_value_iterable_view.h"
+#include "opentelemetry/common/macros.h"
+
+#include <array>
+#include <map>
+#include <string>
+#include <utility>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+/**
+ * Maintain a static empty array of pairs that represents empty (default) attributes.
+ * This helps to avoid constructing a new empty container every time a call is made
+ * with default attributes.
+ */
+OPENTELEMETRY_MAYBE_UNUSED static const opentelemetry::common::KeyValueIterableView<
+ std::array<std::pair<std::string, int>, 0>>
+ &GetEmptyAttributes() noexcept
+{
+ static const std::array<std::pair<std::string, int>, 0> array{};
+ static const opentelemetry::common::KeyValueIterableView<
+ std::array<std::pair<std::string, int>, 0>>
+ kEmptyAttributes(array);
+
+ return kEmptyAttributes;
+}
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/env_variables.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/env_variables.h
new file mode 100644
index 000000000..be955ee86
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/env_variables.h
@@ -0,0 +1,53 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <string>
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+
+#if defined(_MSC_VER)
+inline int setenv(const char *name, const char *value, int)
+{
+ return _putenv_s(name, value);
+}
+
+inline int unsetenv(const char *name)
+{
+ return setenv(name, "", 1);
+}
+#endif
+
+// Returns the env variable set.
+inline const std::string GetEnvironmentVariable(const char *env_var_name)
+{
+#if !defined(NO_GETENV)
+ const char *endpoint_from_env = nullptr;
+# if defined(_MSC_VER)
+ // avoid calling std::getenv which is deprecated in MSVC.
+ size_t required_size = 0;
+ getenv_s(&required_size, nullptr, 0, env_var_name);
+ std::unique_ptr<char> endpoint_buffer;
+ if (required_size > 0)
+ {
+ endpoint_buffer = std::unique_ptr<char>{new char[required_size]};
+ getenv_s(&required_size, endpoint_buffer.get(), required_size, env_var_name);
+ endpoint_from_env = endpoint_buffer.get();
+ }
+# else
+ endpoint_from_env = std::getenv(env_var_name);
+# endif // defined(_MSC_VER)
+ return endpoint_from_env == nullptr ? std::string{} : std::string{endpoint_from_env};
+#else
+ return std::string{};
+#endif // !defined(NO_GETENV)
+}
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/exporter_utils.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/exporter_utils.h
new file mode 100644
index 000000000..091f481f9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/exporter_utils.h
@@ -0,0 +1,34 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+/**
+ * ExportResult is returned as result of exporting a batch of Records.
+ */
+enum class ExportResult
+{
+ // Batch was exported successfully.
+ kSuccess = 0,
+
+ // Batch exporting failed, caller must not retry exporting the same batch
+ // and the batch must be dropped.
+ kFailure = 1,
+
+ // The collection does not have enough space to receive the export batch.
+ kFailureFull = 2,
+
+ // The export() function was passed an invalid argument.
+ kFailureInvalidArgument = 3
+};
+
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/global_log_handler.h
new file mode 100644
index 000000000..99cf48b82
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/common/global_log_handler.h
@@ -0,0 +1,222 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <iostream>
+#include <sstream>
+#include <utility>
+
+#include "opentelemetry/nostd/shared_ptr.h"
+#include "opentelemetry/sdk/common/attribute_utils.h"
+#include "opentelemetry/version.h"
+
+#define OTEL_INTERNAL_LOG_LEVEL_ERROR 0
+#define OTEL_INTERNAL_LOG_LEVEL_WARN 1
+#define OTEL_INTERNAL_LOG_LEVEL_INFO 2
+#define OTEL_INTERNAL_LOG_LEVEL_DEBUG 3
+#ifndef OTEL_INTERNAL_LOG_LEVEL
+// DEBUG by default, we can change log level on runtime
+# define OTEL_INTERNAL_LOG_LEVEL OTEL_INTERNAL_LOG_LEVEL_DEBUG
+#endif
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace common
+{
+namespace internal_log
+{
+
+enum class LogLevel
+{
+ Error = 0,
+ Warning,
+ Info,
+ Debug
+};
+
+inline std::string LevelToString(LogLevel level)
+{
+ switch (level)
+ {
+ case LogLevel::Error:
+ return "Error";
+ case LogLevel::Warning:
+ return "Warning";
+ case LogLevel::Info:
+ return "Info";
+ case LogLevel::Debug:
+ return "Debug";
+ }
+ return {};
+}
+
+class LogHandler
+{
+public:
+ virtual ~LogHandler();
+
+ virtual void Handle(LogLevel level,
+ const char *file,
+ int line,
+ const char *msg,
+ const sdk::common::AttributeMap &attributes) noexcept = 0;
+};
+
+class DefaultLogHandler : public LogHandler
+{
+public:
+ void Handle(LogLevel level,
+ const char *file,
+ int line,
+ const char *msg,
+ const sdk::common::AttributeMap &attributes) noexcept override;
+};
+
+class NoopLogHandler : public LogHandler
+{
+public:
+ void Handle(LogLevel level,
+ const char *file,
+ int line,
+ const char *msg,
+ const sdk::common::AttributeMap &error_attributes) noexcept override;
+};
+
+/**
+ * Stores the singleton global LogHandler.
+ */
+class GlobalLogHandler
+{
+public:
+ /**
+ * Returns the singleton LogHandler.
+ *
+ * By default, a default LogHandler is returned.
+ */
+ static inline const nostd::shared_ptr<LogHandler> &GetLogHandler() noexcept
+ {
+ return GetHandlerAndLevel().first;
+ }
+
+ /**
+ * Changes the singleton LogHandler.
+ * This should be called once at the start of application before creating any Provider
+ * instance.
+ */
+ static inline void SetLogHandler(nostd::shared_ptr<LogHandler> eh) noexcept
+ {
+ GetHandlerAndLevel().first = eh;
+ }
+
+ /**
+ * Returns the singleton log level.
+ *
+ * By default, a default log level is returned.
+ */
+ static inline LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().second; }
+
+ /**
+ * Changes the singleton Log level.
+ * This should be called once at the start of application before creating any Provider
+ * instance.
+ */
+ static inline void SetLogLevel(LogLevel level) noexcept { GetHandlerAndLevel().second = level; }
+
+private:
+ static std::pair<nostd::shared_ptr<LogHandler>, LogLevel> &GetHandlerAndLevel() noexcept;
+};
+
+} // namespace internal_log
+} // namespace common
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+
+/**
+ * We can not decide the destroying order of signaltons.
+ * Which means, the destructors of other singletons (GlobalLogHandler,TracerProvider and etc.)
+ * may be called after destroying of global LogHandler and use OTEL_INTERNAL_LOG_* in it.We can do
+ * nothing but ignore the log in this situation.
+ */
+#define OTEL_INTERNAL_LOG_DISPATCH(level, message, attributes) \
+ do \
+ { \
+ using opentelemetry::sdk::common::internal_log::GlobalLogHandler; \
+ using opentelemetry::sdk::common::internal_log::LogHandler; \
+ if (level > GlobalLogHandler::GetLogLevel()) \
+ { \
+ break; \
+ } \
+ const opentelemetry::nostd::shared_ptr<LogHandler> &log_handler = \
+ GlobalLogHandler::GetLogHandler(); \
+ if (!log_handler) \
+ { \
+ break; \
+ } \
+ std::stringstream tmp_stream; \
+ tmp_stream << message; \
+ log_handler->Handle(level, __FILE__, __LINE__, tmp_stream.str().c_str(), attributes); \
+ } while (false);
+
+#define OTEL_INTERNAL_LOG_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
+
+#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_ERROR
+# define OTEL_INTERNAL_LOG_ERROR_1_ARGS(message) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Error, message, \
+ {})
+# define OTEL_INTERNAL_LOG_ERROR_2_ARGS(message, attributes) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Error, message, \
+ attributes)
+# define OTEL_INTERNAL_LOG_ERROR_MACRO(...) \
+ OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_ERROR_2_ARGS, \
+ OTEL_INTERNAL_LOG_ERROR_1_ARGS)
+# define OTEL_INTERNAL_LOG_ERROR(...) OTEL_INTERNAL_LOG_ERROR_MACRO(__VA_ARGS__)(__VA_ARGS__)
+#else
+# define OTEL_INTERNAL_LOG_ERROR(...)
+#endif
+
+#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_WARN
+# define OTEL_INTERNAL_LOG_WARN_1_ARGS(message) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Warning, \
+ message, {})
+# define OTEL_INTERNAL_LOG_WARN_2_ARGS(message, attributes) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Warning, \
+ message, attributes)
+# define OTEL_INTERNAL_LOG_WARN_MACRO(...) \
+ OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_WARN_2_ARGS, \
+ OTEL_INTERNAL_LOG_WARN_1_ARGS)
+# define OTEL_INTERNAL_LOG_WARN(...) OTEL_INTERNAL_LOG_WARN_MACRO(__VA_ARGS__)(__VA_ARGS__)
+#else
+# define OTEL_INTERNAL_LOG_ERROR(...)
+#endif
+
+#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_DEBUG
+# define OTEL_INTERNAL_LOG_DEBUG_1_ARGS(message) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Debug, message, \
+ {})
+# define OTEL_INTERNAL_LOG_DEBUG_2_ARGS(message, attributes) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Debug, message, \
+ attributes)
+# define OTEL_INTERNAL_LOG_DEBUG_MACRO(...) \
+ OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_DEBUG_2_ARGS, \
+ OTEL_INTERNAL_LOG_DEBUG_1_ARGS)
+# define OTEL_INTERNAL_LOG_DEBUG(...) OTEL_INTERNAL_LOG_DEBUG_MACRO(__VA_ARGS__)(__VA_ARGS__)
+#else
+# define OTEL_INTERNAL_LOG_DEBUG(...)
+#endif
+
+#if OTEL_INTERNAL_LOG_LEVEL >= OTEL_INTERNAL_LOG_LEVEL_INFO
+# define OTEL_INTERNAL_LOG_INFO_1_ARGS(message) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Info, message, \
+ {})
+# define OTEL_INTERNAL_LOG_INFO_2_ARGS(message, attributes) \
+ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Info, message, \
+ attributes)
+# define OTEL_INTERNAL_LOG_INFO_MACRO(...) \
+ OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_INFO_2_ARGS, \
+ OTEL_INTERNAL_LOG_INFO_1_ARGS)
+# define OTEL_INTERNAL_LOG_INFO(...) OTEL_INTERNAL_LOG_INFO_MACRO(__VA_ARGS__)(__VA_ARGS__)
+#else
+# define OTEL_INTERNAL_LOG_INFO(...)
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h
new file mode 100644
index 000000000..20f82a5d1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h
@@ -0,0 +1,96 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/nostd/unique_ptr.h"
+#include "opentelemetry/version.h"
+
+#include <functional>
+#include <string>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+
+namespace sdk
+{
+namespace instrumentationlibrary
+{
+
+class InstrumentationLibrary
+{
+public:
+ InstrumentationLibrary(const InstrumentationLibrary &) = default;
+
+ /**
+ * Returns a newly created InstrumentationLibrary with the specified library name and version.
+ * @param name name of the instrumentation library.
+ * @param version version of the instrumentation library.
+ * @param schema_url schema url of the telemetry emitted by the library.
+ * @returns the newly created InstrumentationLibrary.
+ */
+ static nostd::unique_ptr<InstrumentationLibrary> Create(nostd::string_view name,
+ nostd::string_view version = "",
+ nostd::string_view schema_url = "")
+ {
+ return nostd::unique_ptr<InstrumentationLibrary>(
+ new InstrumentationLibrary{name, version, schema_url});
+ }
+
+ std::size_t HashCode() const noexcept { return hash_code_; }
+
+ /**
+ * Compare 2 instrumentation libraries.
+ * @param other the instrumentation library to compare to.
+ * @returns true if the 2 instrumentation libraries are equal, false otherwise.
+ */
+ bool operator==(const InstrumentationLibrary &other) const
+ {
+ return equal(other.name_, other.version_, other.schema_url_);
+ }
+
+ /**
+ * Check whether the instrumentation library has given name and version.
+ * This could be used to check version equality and avoid heap allocation.
+ * @param name name of the instrumentation library to compare.
+ * @param version version of the instrumentatoin library to compare.
+ * @param schema_url schema url of the telemetry emitted by the library.
+ * @returns true if name and version in this instrumentation library are equal with the given name
+ * and version.
+ */
+ bool equal(const nostd::string_view name,
+ const nostd::string_view version,
+ const nostd::string_view schema_url = "") const
+ {
+ return this->name_ == name && this->version_ == version && this->schema_url_ == schema_url;
+ }
+
+ const std::string &GetName() const { return name_; }
+ const std::string &GetVersion() const { return version_; }
+ const std::string &GetSchemaURL() const { return schema_url_; }
+
+private:
+ InstrumentationLibrary(nostd::string_view name,
+ nostd::string_view version,
+ nostd::string_view schema_url = "")
+ : name_(name), version_(version), schema_url_(schema_url)
+ {
+ std::string hash_data;
+ hash_data.reserve(name_.size() + version_.size() + schema_url_.size());
+ hash_data += name_;
+ hash_data += version_;
+ hash_data += schema_url_;
+ hash_code_ = std::hash<std::string>{}(hash_data);
+ }
+
+private:
+ std::string name_;
+ std::string version_;
+ std::string schema_url_;
+ std::size_t hash_code_;
+};
+
+} // namespace instrumentationlibrary
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h
new file mode 100644
index 000000000..1b6d443c8
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h
@@ -0,0 +1,128 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include "opentelemetry/sdk/common/circular_buffer.h"
+# include "opentelemetry/sdk/logs/exporter.h"
+# include "opentelemetry/sdk/logs/processor.h"
+
+# include <atomic>
+# include <condition_variable>
+# include <thread>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+
+namespace logs
+{
+
+/**
+ * This is an implementation of the LogProcessor which creates batches of finished logs and passes
+ * the export-friendly log data representations to the configured LogExporter.
+ */
+class BatchLogProcessor : public LogProcessor
+{
+public:
+ /**
+ * Creates a batch log processor by configuring the specified exporter and other parameters
+ * as per the official, language-agnostic opentelemetry specs.
+ *
+ * @param exporter - The backend exporter to pass the logs to
+ * @param max_queue_size - The maximum buffer/queue size. After the size is reached, logs are
+ * dropped.
+ * @param scheduled_delay_millis - The time interval between two consecutive exports.
+ * @param max_export_batch_size - The maximum batch size of every export. It must be smaller or
+ * equal to max_queue_size
+ */
+ explicit BatchLogProcessor(
+ std::unique_ptr<LogExporter> &&exporter,
+ const size_t max_queue_size = 2048,
+ const std::chrono::milliseconds scheduled_delay_millis = std::chrono::milliseconds(5000),
+ const size_t max_export_batch_size = 512);
+
+ /** Makes a new recordable **/
+ std::unique_ptr<Recordable> MakeRecordable() noexcept override;
+
+ /**
+ * Called when the Logger's log method creates a log record
+ * @param record the log record
+ */
+
+ void OnReceive(std::unique_ptr<Recordable> &&record) noexcept override;
+
+ /**
+ * Export all log records that have not been exported yet.
+ *
+ * NOTE: Timeout functionality not supported yet.
+ */
+ bool ForceFlush(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+ /**
+ * Shuts down the processor and does any cleanup required. Completely drains the buffer/queue of
+ * all its logs and passes them to the exporter. Any subsequent calls to
+ * ForceFlush or Shutdown will return immediately without doing anything.
+ *
+ * NOTE: Timeout functionality not supported yet.
+ */
+ bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+ /**
+ * Class destructor which invokes the Shutdown() method.
+ */
+ virtual ~BatchLogProcessor() override;
+
+private:
+ /**
+ * The background routine performed by the worker thread.
+ */
+ void DoBackgroundWork();
+
+ /**
+ * Exports all logs to the configured exporter.
+ *
+ * @param was_force_flush_called - A flag to check if the current export is the result
+ * of a call to ForceFlush method. If true, then we have to
+ * notify the main thread to wake it up in the ForceFlush
+ * method.
+ */
+ void Export(const bool was_for_flush_called);
+
+ /**
+ * Called when Shutdown() is invoked. Completely drains the queue of all log records and
+ * passes them to the exporter.
+ */
+ void DrainQueue();
+
+ /* The configured backend log exporter */
+ std::unique_ptr<LogExporter> exporter_;
+
+ /* Configurable parameters as per the official *trace* specs */
+ const size_t max_queue_size_;
+ const std::chrono::milliseconds scheduled_delay_millis_;
+ const size_t max_export_batch_size_;
+
+ /* Synchronization primitives */
+ std::condition_variable cv_, force_flush_cv_;
+ std::mutex cv_m_, force_flush_cv_m_, shutdown_m_;
+
+ /* The buffer/queue to which the ended logs are added */
+ common::CircularBuffer<Recordable> buffer_;
+
+ /* Important boolean flags to handle the workflow of the processor */
+ std::atomic<bool> is_shutdown_{false};
+ std::atomic<bool> is_force_flush_{false};
+ std::atomic<bool> is_force_flush_notified_{false};
+
+ /* The background worker thread */
+ std::thread worker_thread_;
+};
+
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/exporter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/exporter.h
new file mode 100644
index 000000000..85c58e9f1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/exporter.h
@@ -0,0 +1,62 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <memory>
+# include <vector>
+# include "opentelemetry/nostd/span.h"
+# include "opentelemetry/sdk/common/exporter_utils.h"
+# include "opentelemetry/sdk/logs/processor.h"
+# include "opentelemetry/sdk/logs/recordable.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+/**
+ * LogExporter defines the interface that log exporters must implement.
+ */
+class LogExporter
+{
+public:
+ virtual ~LogExporter() = default;
+
+ /**
+ * Create a log recordable. This object will be used to record log data and
+ * will subsequently be passed to LogExporter::Export. Vendors can implement
+ * custom recordables or use the default LogRecord recordable provided by the
+ * SDK.
+ * @return a newly initialized Recordable object
+ *
+ * Note: This method must be callable from multiple threads.
+ */
+ virtual std::unique_ptr<Recordable> MakeRecordable() noexcept = 0;
+
+ /**
+ * Exports the batch of log records to their export destination.
+ * This method must not be called concurrently for the same exporter instance.
+ * The exporter may attempt to retry sending the batch, but should drop
+ * and return kFailure after a certain timeout.
+ * @param records a span of unique pointers to log records
+ * @returns an ExportResult code (whether export was success or failure)
+ */
+ virtual sdk::common::ExportResult Export(
+ const nostd::span<std::unique_ptr<Recordable>> &records) noexcept = 0;
+
+ /**
+ * Marks the exporter as ShutDown and cleans up any resources as required.
+ * Shutdown should be called only once for each Exporter instance.
+ * @param timeout minimum amount of microseconds to wait for shutdown before giving up and
+ * returning failure.
+ * @return true if the exporter shutdown succeeded, false otherwise
+ */
+ virtual bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0;
+};
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/log_record.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/log_record.h
new file mode 100644
index 000000000..2a3a78289
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/log_record.h
@@ -0,0 +1,193 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <map>
+# include <unordered_map>
+# include "opentelemetry/sdk/common/attribute_utils.h"
+# include "opentelemetry/sdk/logs/recordable.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+
+/**
+ * A default Recordable implemenation to be passed in log statements,
+ * matching the 10 fields of the Log Data Model.
+ * (https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#log-and-event-record-definition)
+ *
+ */
+class LogRecord final : public Recordable
+{
+private:
+ // Default values are set by the respective data structures' constructors for all fields,
+ // except the severity field, which must be set manually (an enum with no default value).
+ opentelemetry::logs::Severity severity_ = opentelemetry::logs::Severity::kInvalid;
+ const opentelemetry::sdk::resource::Resource *resource_ = nullptr;
+ common::AttributeMap attributes_map_;
+ std::string body_; // Currently a simple string, but should be changed to "Any" type
+ opentelemetry::trace::TraceId trace_id_;
+ opentelemetry::trace::SpanId span_id_;
+ opentelemetry::trace::TraceFlags trace_flags_;
+ opentelemetry::common::SystemTimestamp timestamp_; // uint64 nanoseconds since Unix epoch
+
+public:
+ /********** Setters for each field (overrides methods from the Recordable interface) ************/
+
+ /**
+ * Set the severity for this log.
+ * @param severity the severity of the event
+ */
+ void SetSeverity(opentelemetry::logs::Severity severity) noexcept override
+ {
+ severity_ = severity;
+ }
+
+ /**
+ * Set body field for this log.
+ * @param message the body to set
+ */
+ void SetBody(nostd::string_view message) noexcept override { body_ = std::string(message); }
+
+ /**
+ * Set Resource of this log
+ * @param Resource the resource to set
+ */
+ void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept override
+ {
+ resource_ = &resource;
+ }
+
+ /**
+ * Set an attribute of a log.
+ * @param name the name of the attribute
+ * @param value the attribute value
+ */
+
+ void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept override
+ {
+ attributes_map_.SetAttribute(key, value);
+ }
+
+ /**
+ * Set trace id for this log.
+ * @param trace_id the trace id to set
+ */
+ void SetTraceId(opentelemetry::trace::TraceId trace_id) noexcept override
+ {
+ trace_id_ = trace_id;
+ }
+
+ /**
+ * Set span id for this log.
+ * @param span_id the span id to set
+ */
+ virtual void SetSpanId(opentelemetry::trace::SpanId span_id) noexcept override
+ {
+ span_id_ = span_id;
+ }
+
+ /**
+ * Inject a trace_flags for this log.
+ * @param trace_flags the span id to set
+ */
+ void SetTraceFlags(opentelemetry::trace::TraceFlags trace_flags) noexcept override
+ {
+ trace_flags_ = trace_flags;
+ }
+
+ /**
+ * Set the timestamp for this log.
+ * @param timestamp the timestamp of the event
+ */
+ void SetTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept override
+ {
+ timestamp_ = timestamp;
+ }
+
+ /************************** Getters for each field ****************************/
+
+ /**
+ * Get the severity for this log
+ * @return the severity for this log
+ */
+ opentelemetry::logs::Severity GetSeverity() const noexcept { return severity_; }
+
+ /**
+ * Get the body of this log
+ * @return the body of this log
+ */
+ std::string GetBody() const noexcept { return body_; }
+
+ /**
+ * Get the resource for this log
+ * @return the resource for this log
+ */
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept
+ {
+ if (nullptr == resource_)
+ {
+ return sdk::resource::Resource::GetDefault();
+ }
+ return *resource_;
+ }
+
+ /**
+ * Get the attributes for this log
+ * @return the attributes for this log
+ */
+ const std::unordered_map<std::string, common::OwnedAttributeValue> &GetAttributes() const noexcept
+ {
+ return attributes_map_.GetAttributes();
+ }
+
+ /**
+ * Get the trace id for this log
+ * @return the trace id for this log
+ */
+ opentelemetry::trace::TraceId GetTraceId() const noexcept { return trace_id_; }
+
+ /**
+ * Get the span id for this log
+ * @return the span id for this log
+ */
+ opentelemetry::trace::SpanId GetSpanId() const noexcept { return span_id_; }
+
+ /**
+ * Get the trace flags for this log
+ * @return the trace flags for this log
+ */
+ opentelemetry::trace::TraceFlags GetTraceFlags() const noexcept { return trace_flags_; }
+
+ /**
+ * Get the timestamp for this log
+ * @return the timestamp for this log
+ */
+ opentelemetry::common::SystemTimestamp GetTimestamp() const noexcept { return timestamp_; }
+
+ /**
+ * Set instrumentation_library for this log.
+ * @param instrumentation_library the instrumentation library to set
+ */
+ void SetInstrumentationLibrary(
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ &instrumentation_library) noexcept
+ {
+ instrumentation_library_ = &instrumentation_library;
+ }
+
+private:
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ *instrumentation_library_ = nullptr;
+};
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger.h
new file mode 100644
index 000000000..4eeca2da1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger.h
@@ -0,0 +1,77 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include "opentelemetry/logs/logger.h"
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+# include "opentelemetry/sdk/logs/logger_context.h"
+# include "opentelemetry/sdk/logs/logger_provider.h"
+
+# include <vector>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+class LoggerProvider;
+
+class Logger final : public opentelemetry::logs::Logger
+{
+public:
+ /**
+ * Initialize a new logger.
+ * @param name The name of this logger instance
+ * @param context The logger provider that owns this logger.
+ */
+ explicit Logger(
+ opentelemetry::nostd::string_view name,
+ std::shared_ptr<LoggerContext> context,
+ std::unique_ptr<instrumentationlibrary::InstrumentationLibrary> instrumentation_library =
+ instrumentationlibrary::InstrumentationLibrary::Create("")) noexcept;
+
+ /**
+ * Returns the name of this logger.
+ */
+ const opentelemetry::nostd::string_view GetName() noexcept override;
+
+ /**
+ * Writes a log record into the processor.
+ * @param severity the severity level of the log event.
+ * @param message the string message of the log (perhaps support std::fmt or fmt-lib format).
+ * with the log event.
+ * @param attributes the attributes, stored as a 2D list of key/value pairs, that are associated
+ * with the log event.
+ * @param trace_id the trace id associated with the log event.
+ * @param span_id the span id associate with the log event.
+ * @param trace_flags the trace flags associated with the log event.
+ * @param timestamp the timestamp the log record was created.
+ * @throws No exceptions under any circumstances. */
+ void Log(opentelemetry::logs::Severity severity,
+ nostd::string_view body,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ opentelemetry::trace::TraceId trace_id,
+ opentelemetry::trace::SpanId span_id,
+ opentelemetry::trace::TraceFlags trace_flags,
+ opentelemetry::common::SystemTimestamp timestamp) noexcept override;
+
+ /** Returns the associated instruementation library */
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary &
+ GetInstrumentationLibrary() const noexcept;
+
+private:
+ // The name of this logger
+ std::string logger_name_;
+
+ // order of declaration is important here - instrumentation library should destroy after
+ // logger-context.
+ std::unique_ptr<instrumentationlibrary::InstrumentationLibrary> instrumentation_library_;
+ std::shared_ptr<LoggerContext> context_;
+};
+
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_context.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_context.h
new file mode 100644
index 000000000..01c2f7dd8
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_context.h
@@ -0,0 +1,81 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include "opentelemetry/sdk/logs/processor.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+/**
+ * A class which stores the LoggerContext context.
+ *
+ * This class meets the following design criteria:
+ * - A shared reference between LoggerProvider and Logger instantiated.
+ * - A thread-safe class that allows updating/altering processor/exporter pipelines
+ * and sampling config.
+ * - The owner/destroyer of Processors/Exporters. These will remain active until
+ * this class is destroyed. I.e. Sampling, Exporting, flushing, Custom Iterator etc. are all ok
+ * if this object is alive, and they will work together. If this object is destroyed, then no shared
+ * references to Processor, Exporter, Recordable, Custom Iterator etc. should exist, and all
+ * associated pipelines will have been flushed.
+ */
+class LoggerContext
+{
+public:
+ explicit LoggerContext(std::vector<std::unique_ptr<LogProcessor>> &&processors,
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({})) noexcept;
+
+ /**
+ * Attaches a log processor to list of configured processors to this tracer context.
+ * Processor once attached can't be removed.
+ * @param processor The new log processor for this tracer. This must not be
+ * a nullptr. Ownership is given to the `TracerContext`.
+ *
+ * Note: This method is not thread safe.
+ */
+ void AddProcessor(std::unique_ptr<LogProcessor> processor) noexcept;
+
+ /**
+ * Obtain the configured (composite) processor.
+ *
+ * Note: When more than one processor is active, this will
+ * return an "aggregate" processor
+ */
+ LogProcessor &GetProcessor() const noexcept;
+
+ /**
+ * Obtain the resource associated with this tracer context.
+ * @return The resource for this tracer context.
+ */
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept;
+
+ /**
+ * Force all active LogProcessors to flush any buffered logs
+ * within the given timeout.
+ */
+ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;
+
+ /**
+ * Shutdown the log processor associated with this tracer provider.
+ */
+ bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept;
+
+private:
+ // order of declaration is important here - resource object should be destroyed after processor.
+ opentelemetry::sdk::resource::Resource resource_;
+ std::unique_ptr<LogProcessor> processor_;
+};
+} // namespace logs
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_provider.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_provider.h
new file mode 100755
index 000000000..9afb67ba0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/logger_provider.h
@@ -0,0 +1,131 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0/
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <memory>
+# include <mutex>
+# include <string>
+# include <vector>
+
+# include "opentelemetry/logs/logger_provider.h"
+# include "opentelemetry/logs/noop.h"
+# include "opentelemetry/nostd/shared_ptr.h"
+# include "opentelemetry/sdk/common/atomic_shared_ptr.h"
+# include "opentelemetry/sdk/logs/logger.h"
+# include "opentelemetry/sdk/logs/logger_context.h"
+# include "opentelemetry/sdk/logs/processor.h"
+
+// Define the maximum number of loggers that are allowed to be registered to the loggerprovider.
+// TODO: Add link to logging spec once this is added to it
+# define MAX_LOGGER_COUNT 100
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+class Logger;
+
+class LoggerProvider final : public opentelemetry::logs::LoggerProvider
+{
+public:
+ /**
+ * Initialize a new logger provider
+ * @param processor The span processor for this logger provider. This must
+ * not be a nullptr.
+ * @param resource The resources for this logger provider.
+ * @param sampler The sampler for this logger provider. This must
+ * not be a nullptr.
+ * @param id_generator The custom id generator for this logger provider. This must
+ * not be a nullptr
+ */
+ explicit LoggerProvider(std::unique_ptr<LogProcessor> &&processor,
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({})) noexcept;
+
+ explicit LoggerProvider(std::vector<std::unique_ptr<LogProcessor>> &&processors,
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({})) noexcept;
+
+ /**
+ * Initialize a new logger provider. A processor must later be assigned
+ * to this logger provider via the AddProcessor() method.
+ */
+ explicit LoggerProvider() noexcept;
+
+ /**
+ * Initialize a new logger provider with a specified context
+ * @param context The shared logger configuration/pipeline for this provider.
+ */
+ explicit LoggerProvider(std::shared_ptr<sdk::logs::LoggerContext> context) noexcept;
+
+ ~LoggerProvider();
+
+ /**
+ * Creates a logger with the given name, and returns a shared pointer to it.
+ * If a logger with that name already exists, return a shared pointer to it
+ * @param logger_name The name of the logger to be created.
+ * @param options The options for the logger. TODO: Once the logging spec defines it,
+ * give a list of options that the logger supports.
+ * @param library_name The version of the library.
+ * @param library_version The version of the library.
+ * @param schema_url The schema URL.
+ */
+ nostd::shared_ptr<opentelemetry::logs::Logger> GetLogger(
+ nostd::string_view logger_name,
+ nostd::string_view options,
+ nostd::string_view library_name,
+ nostd::string_view library_version = "",
+ nostd::string_view schema_url = "") noexcept override;
+ /**
+ * Creates a logger with the given name, and returns a shared pointer to it.
+ * If a logger with that name already exists, return a shared pointer to it
+ * @param name The name of the logger to be created.
+ * @param args The arguments for the logger. TODO: Once the logging spec defines it,
+ * give a list of arguments that the logger supports.
+ * @param library_name The version of the library.
+ * @param library_version The version of the library.
+ * @param schema_url The schema URL.
+ */
+ nostd::shared_ptr<opentelemetry::logs::Logger> GetLogger(
+ nostd::string_view logger_name,
+ nostd::span<nostd::string_view> args,
+ nostd::string_view library_name,
+ nostd::string_view library_version = "",
+ nostd::string_view schema_url = "") noexcept override;
+
+ /**
+ * Add the processor that is stored internally in the logger provider.
+ * @param processor The processor to be stored inside the logger provider.
+ * This must not be a nullptr.
+ */
+ void AddProcessor(std::unique_ptr<LogProcessor> processor) noexcept;
+
+ /**
+ * Obtain the resource associated with this logger provider.
+ * @return The resource for this logger provider.
+ */
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept;
+
+ /**
+ * Shutdown the log processor associated with this log provider.
+ */
+ bool Shutdown() noexcept;
+
+ /**
+ * Force flush the log processor associated with this log provider.
+ */
+ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;
+
+private:
+ // order of declaration is important here - loggers should destroy only after context.
+ std::vector<std::shared_ptr<opentelemetry::sdk::logs::Logger>> loggers_;
+ std::shared_ptr<sdk::logs::LoggerContext> context_;
+ std::mutex lock_;
+};
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h
new file mode 100644
index 000000000..c1bda24a0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h
@@ -0,0 +1,69 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <memory>
+# include <vector>
+
+# include "opentelemetry/sdk/logs/multi_recordable.h"
+# include "opentelemetry/sdk/logs/processor.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+
+/**
+ * Log processor allow hooks for receive method invocations.
+ *
+ * Built-in log processors are responsible for batching and conversion of
+ * logs to exportable representation and passing batches to exporters.
+ */
+class MultiLogProcessor : public LogProcessor
+{
+public:
+ MultiLogProcessor(std::vector<std::unique_ptr<LogProcessor>> &&processors);
+ ~MultiLogProcessor();
+
+ void AddProcessor(std::unique_ptr<LogProcessor> &&processor);
+
+ std::unique_ptr<Recordable> MakeRecordable() noexcept override;
+
+ /**
+ * OnReceive is called by the SDK once a log record has been successfully created.
+ * @param record the log record
+ */
+ void OnReceive(std::unique_ptr<Recordable> &&record) noexcept override;
+
+ /**
+ * Exports all log records that have not yet been exported to the configured Exporter.
+ * @param timeout that the forceflush is required to finish within.
+ * @return a result code indicating whether it succeeded, failed or timed out
+ */
+ bool ForceFlush(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+ /**
+ * Shuts down the processor and does any cleanup required.
+ * ShutDown should only be called once for each processor.
+ * @param timeout minimum amount of microseconds to wait for
+ * shutdown before giving up and returning failure.
+ * @return true if the shutdown succeeded, false otherwise
+ */
+ bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+private:
+ std::vector<std::unique_ptr<LogProcessor>> processors_;
+};
+} // namespace logs
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_recordable.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_recordable.h
new file mode 100644
index 000000000..db3df9622
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/multi_recordable.h
@@ -0,0 +1,104 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <cstddef>
+# include <memory>
+# include <unordered_map>
+
+# include "opentelemetry/sdk/logs/processor.h"
+# include "opentelemetry/sdk/logs/recordable.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+class MultiRecordable final : public Recordable
+{
+public:
+ void AddRecordable(const LogProcessor &processor,
+ std::unique_ptr<Recordable> recordable) noexcept;
+
+ const std::unique_ptr<Recordable> &GetRecordable(const LogProcessor &processor) const noexcept;
+
+ std::unique_ptr<Recordable> ReleaseRecordable(const LogProcessor &processor) noexcept;
+
+ /**
+ * Set the timestamp for this log.
+ * @param timestamp the timestamp to set
+ */
+ void SetTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept override;
+
+ /**
+ * Set the severity for this log.
+ * @param severity the severity of the event
+ */
+ void SetSeverity(opentelemetry::logs::Severity severity) noexcept override;
+
+ /**
+ * Set body field for this log.
+ * @param message the body to set
+ */
+ void SetBody(nostd::string_view message) noexcept override;
+
+ /**
+ * Set Resource of this log
+ * @param Resource the resource to set
+ */
+ void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept override;
+
+ /**
+ * Set an attribute of a log.
+ * @param key the name of the attribute
+ * @param value the attribute value
+ */
+ void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept override;
+
+ /**
+ * Set the trace id for this log.
+ * @param trace_id the trace id to set
+ */
+ void SetTraceId(opentelemetry::trace::TraceId trace_id) noexcept override;
+
+ /**
+ * Set the span id for this log.
+ * @param span_id the span id to set
+ */
+ void SetSpanId(opentelemetry::trace::SpanId span_id) noexcept override;
+
+ /**
+ * Inject trace_flags for this log.
+ * @param trace_flags the trace flags to set
+ */
+ void SetTraceFlags(opentelemetry::trace::TraceFlags trace_flags) noexcept override;
+
+ /**
+ * Set instrumentation_library for this log.
+ * @param instrumentation_library the instrumentation library to set
+ */
+ void SetInstrumentationLibrary(
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ &instrumentation_library) noexcept override;
+
+ /** Returns the associated instruementation library */
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary &
+ GetInstrumentationLibrary() const noexcept;
+
+private:
+ std::unordered_map<std::size_t, std::unique_ptr<Recordable>> recordables_;
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ *instrumentation_library_ = nullptr;
+};
+} // namespace logs
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
+
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/processor.h
new file mode 100644
index 000000000..36da036f3
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/processor.h
@@ -0,0 +1,61 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <chrono>
+# include <memory>
+# include "opentelemetry/sdk/logs/recordable.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+/**
+ * The Log Processor is responsible for passing log records
+ * to the configured exporter.
+ */
+class LogProcessor
+{
+public:
+ virtual ~LogProcessor() = default;
+
+ /**
+ * Create a log recordable. This requests a new log recordable from the
+ * associated exporter.
+ * @return a newly initialized recordable
+ *
+ * Note: This method must be callable from multiple threads.
+ */
+ virtual std::unique_ptr<Recordable> MakeRecordable() noexcept = 0;
+
+ /**
+ * OnReceive is called by the SDK once a log record has been successfully created.
+ * @param record the log record
+ */
+ virtual void OnReceive(std::unique_ptr<Recordable> &&record) noexcept = 0;
+
+ /**
+ * Exports all log records that have not yet been exported to the configured Exporter.
+ * @param timeout that the forceflush is required to finish within.
+ * @return a result code indicating whether it succeeded, failed or timed out
+ */
+ virtual bool ForceFlush(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0;
+
+ /**
+ * Shuts down the processor and does any cleanup required.
+ * ShutDown should only be called once for each processor.
+ * @param timeout minimum amount of microseconds to wait for
+ * shutdown before giving up and returning failure.
+ * @return true if the shutdown succeeded, false otherwise
+ */
+ virtual bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0;
+};
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/recordable.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/recordable.h
new file mode 100644
index 000000000..4a3227373
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/recordable.h
@@ -0,0 +1,97 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include "opentelemetry/common/attribute_value.h"
+# include "opentelemetry/common/key_value_iterable.h"
+# include "opentelemetry/common/timestamp.h"
+# include "opentelemetry/logs/severity.h"
+# include "opentelemetry/sdk/common/empty_attributes.h"
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/trace/span.h"
+# include "opentelemetry/trace/span_context.h"
+# include "opentelemetry/trace/span_id.h"
+# include "opentelemetry/trace/trace_flags.h"
+# include "opentelemetry/trace/trace_id.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+/**
+ * Maintains a representation of a log in a format that can be processed by a recorder.
+ *
+ * This class is thread-compatible.
+ */
+class Recordable
+{
+public:
+ virtual ~Recordable() = default;
+
+ /**
+ * Set the timestamp for this log.
+ * @param timestamp the timestamp to set
+ */
+ virtual void SetTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept = 0;
+
+ /**
+ * Set the severity for this log.
+ * @param severity the severity of the event
+ */
+ virtual void SetSeverity(opentelemetry::logs::Severity severity) noexcept = 0;
+
+ /**
+ * Set body field for this log.
+ * @param message the body to set
+ */
+ virtual void SetBody(nostd::string_view message) noexcept = 0;
+
+ /**
+ * Set Resource of this log
+ * @param Resource the resource to set
+ */
+ virtual void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept = 0;
+
+ /**
+ * Set an attribute of a log.
+ * @param key the name of the attribute
+ * @param value the attribute value
+ */
+ virtual void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept = 0;
+
+ /**
+ * Set the trace id for this log.
+ * @param trace_id the trace id to set
+ */
+ virtual void SetTraceId(opentelemetry::trace::TraceId trace_id) noexcept = 0;
+
+ /**
+ * Set the span id for this log.
+ * @param span_id the span id to set
+ */
+ virtual void SetSpanId(opentelemetry::trace::SpanId span_id) noexcept = 0;
+
+ /**
+ * Inject trace_flags for this log.
+ * @param trace_flags the trace flags to set
+ */
+ virtual void SetTraceFlags(opentelemetry::trace::TraceFlags trace_flags) noexcept = 0;
+
+ /**
+ * Set instrumentation_library for this log.
+ * @param instrumentation_library the instrumentation library to set
+ */
+ virtual void SetInstrumentationLibrary(
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ &instrumentation_library) noexcept = 0;
+};
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h
new file mode 100644
index 000000000..cc3aec47b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h
@@ -0,0 +1,55 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifdef ENABLE_LOGS_PREVIEW
+
+# include <atomic>
+# include <mutex>
+
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/logs/exporter.h"
+# include "opentelemetry/sdk/logs/processor.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace logs
+{
+/**
+ * The simple log processor passes all log records
+ * in a batch of 1 to the configured
+ * LogExporter.
+ *
+ * All calls to the configured LogExporter are synchronized using a
+ * spin-lock on an atomic_flag.
+ */
+class SimpleLogProcessor : public LogProcessor
+{
+
+public:
+ explicit SimpleLogProcessor(std::unique_ptr<LogExporter> &&exporter);
+ virtual ~SimpleLogProcessor() = default;
+
+ std::unique_ptr<Recordable> MakeRecordable() noexcept override;
+
+ void OnReceive(std::unique_ptr<Recordable> &&record) noexcept override;
+
+ bool ForceFlush(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+ bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+private:
+ // The configured exporter
+ std::unique_ptr<LogExporter> exporter_;
+ // The lock used to ensure the exporter is not called concurrently
+ opentelemetry::common::SpinLockMutex lock_;
+ // The atomic boolean flag to ensure the ShutDown() function is only called once
+ std::atomic_flag shutdown_latch_ = ATOMIC_FLAG_INIT;
+};
+} // namespace logs
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h
new file mode 100644
index 000000000..7ec9a6ea2
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h
@@ -0,0 +1,55 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/nostd/string_view.h"
+# include "opentelemetry/sdk/metrics/data/metric_data.h"
+# include "opentelemetry/sdk/metrics/data/point_data.h"
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class Aggregation
+{
+public:
+ virtual void Aggregate(long value, const PointAttributes &attributes = {}) noexcept = 0;
+
+ virtual void Aggregate(double value, const PointAttributes &attributes = {}) noexcept = 0;
+
+ /**
+ * Returns the result of the merge of the two aggregations.
+ *
+ * This should always assume that the aggregations do not overlap and merge together for a new
+ * cumulative report.
+ *
+ * @param delta the newly captured (delta) aggregation
+ * @return the result of the merge of the given aggregation.
+ */
+
+ virtual std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept = 0;
+
+ /**
+ * Returns a new delta aggregation by comparing two cumulative measurements.
+ *
+ * @param next the newly captured (cumulative) aggregation.
+ * @return The resulting delta aggregation.
+ */
+ virtual std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept = 0;
+
+ /**
+ * Returns the point data that the aggregation will produce.
+ *
+ * @return PointType
+ */
+
+ virtual PointType ToPoint() const noexcept = 0;
+
+ virtual ~Aggregation() = default;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h
new file mode 100644
index 000000000..887e1beb9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h
@@ -0,0 +1,146 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
+# include "opentelemetry/sdk/metrics/aggregation/drop_aggregation.h"
+# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h"
+# include "opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h"
+# include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+
+# include <mutex>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class DefaultAggregation
+{
+public:
+ static std::unique_ptr<Aggregation> CreateAggregation(
+ const opentelemetry::sdk::metrics::InstrumentDescriptor &instrument_descriptor)
+ {
+ switch (instrument_descriptor.type_)
+ {
+ case InstrumentType::kCounter:
+ case InstrumentType::kUpDownCounter:
+ case InstrumentType::kObservableCounter:
+ case InstrumentType::kObservableUpDownCounter:
+ return (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ ? std::move(std::unique_ptr<Aggregation>(new LongSumAggregation()))
+ : std::move(std::unique_ptr<Aggregation>(new DoubleSumAggregation()));
+ break;
+ case InstrumentType::kHistogram:
+ return (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ ? std::move(std::unique_ptr<Aggregation>(new LongHistogramAggregation()))
+ : std::move(std::unique_ptr<Aggregation>(new DoubleHistogramAggregation()));
+ break;
+ case InstrumentType::kObservableGauge:
+ return (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ ? std::move(std::unique_ptr<Aggregation>(new LongLastValueAggregation()))
+ : std::move(std::unique_ptr<Aggregation>(new DoubleLastValueAggregation()));
+ break;
+ default:
+ return std::move(std::unique_ptr<Aggregation>(new DropAggregation()));
+ };
+ }
+
+ static std::unique_ptr<Aggregation> CreateAggregation(AggregationType aggregation_type,
+ InstrumentDescriptor instrument_descriptor)
+ {
+ switch (aggregation_type)
+ {
+ case AggregationType::kDrop:
+ return std::unique_ptr<Aggregation>(new DropAggregation());
+ break;
+ case AggregationType::kHistogram:
+ if (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ {
+ return std::unique_ptr<Aggregation>(new LongHistogramAggregation());
+ }
+ else
+ {
+ return std::unique_ptr<Aggregation>(new DoubleHistogramAggregation());
+ }
+ break;
+ case AggregationType::kLastValue:
+ if (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ {
+ return std::unique_ptr<Aggregation>(new LongLastValueAggregation());
+ }
+ else
+ {
+ return std::unique_ptr<Aggregation>(new DoubleLastValueAggregation());
+ }
+ break;
+ case AggregationType::kSum:
+ if (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ {
+ return std::unique_ptr<Aggregation>(new LongSumAggregation());
+ }
+ else
+ {
+ return std::unique_ptr<Aggregation>(new DoubleSumAggregation());
+ }
+ break;
+ default:
+ return DefaultAggregation::CreateAggregation(instrument_descriptor);
+ }
+ }
+
+ static std::unique_ptr<Aggregation> CloneAggregation(AggregationType aggregation_type,
+ InstrumentDescriptor instrument_descriptor,
+ const Aggregation &to_copy)
+ {
+ const PointType point_data = to_copy.ToPoint();
+ switch (aggregation_type)
+ {
+ case AggregationType::kDrop:
+ return std::unique_ptr<Aggregation>(new DropAggregation());
+ case AggregationType::kHistogram:
+ if (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ {
+ return std::unique_ptr<Aggregation>(
+ new LongHistogramAggregation(nostd::get<HistogramPointData>(point_data)));
+ }
+ else
+ {
+ return std::unique_ptr<Aggregation>(
+ new DoubleHistogramAggregation(nostd::get<HistogramPointData>(point_data)));
+ }
+ case AggregationType::kLastValue:
+ if (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ {
+ return std::unique_ptr<Aggregation>(
+ new LongLastValueAggregation(nostd::get<LastValuePointData>(point_data)));
+ }
+ else
+ {
+ return std::unique_ptr<Aggregation>(
+ new DoubleLastValueAggregation(nostd::get<LastValuePointData>(point_data)));
+ }
+ case AggregationType::kSum:
+ if (instrument_descriptor.value_type_ == InstrumentValueType::kLong)
+ {
+ return std::unique_ptr<Aggregation>(
+ new LongSumAggregation(nostd::get<SumPointData>(point_data)));
+ }
+ else
+ {
+ return std::unique_ptr<Aggregation>(
+ new DoubleSumAggregation(nostd::get<SumPointData>(point_data)));
+ }
+ default:
+ return DefaultAggregation::CreateAggregation(instrument_descriptor);
+ }
+ }
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h
new file mode 100644
index 000000000..6c3d89d24
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h
@@ -0,0 +1,51 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
+
+# include <mutex>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+/**
+ * A null Aggregation which denotes no aggregation should occur.
+ */
+
+class DropAggregation : public Aggregation
+{
+public:
+ DropAggregation() = default;
+
+ DropAggregation(const DropPointData &) {}
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {}
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {}
+
+ std::unique_ptr<Aggregation> Merge(const Aggregation &) const noexcept override
+ {
+ return std::unique_ptr<Aggregation>(new DropAggregation());
+ }
+
+ std::unique_ptr<Aggregation> Diff(const Aggregation &) const noexcept override
+ {
+ return std::unique_ptr<Aggregation>(new DropAggregation());
+ }
+
+ PointType ToPoint() const noexcept override
+ {
+ static DropPointData point_data;
+ return point_data;
+ }
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h
new file mode 100644
index 000000000..e2a55fba5
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h
@@ -0,0 +1,103 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
+
+# include <mutex>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class LongHistogramAggregation : public Aggregation
+{
+public:
+ LongHistogramAggregation();
+ LongHistogramAggregation(HistogramPointData &&);
+ LongHistogramAggregation(const HistogramPointData &);
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override;
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {}
+
+ /* Returns the result of merge of the existing aggregation with delta aggregation with same
+ * boundaries */
+ std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept override;
+
+ /* Returns the new delta aggregation by comparing existing aggregation with next aggregation with
+ * same boundaries. Data points for `next` aggregation (sum , bucket-counts) should be more than
+ * the current aggregation - which is the normal scenario as measurements values are monotonic
+ * increasing.
+ */
+ std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept override;
+
+ PointType ToPoint() const noexcept override;
+
+private:
+ opentelemetry::common::SpinLockMutex lock_;
+ HistogramPointData point_data_;
+};
+
+class DoubleHistogramAggregation : public Aggregation
+{
+public:
+ DoubleHistogramAggregation();
+ DoubleHistogramAggregation(HistogramPointData &&);
+ DoubleHistogramAggregation(const HistogramPointData &);
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {}
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override;
+
+ /* Returns the result of merge of the existing aggregation with delta aggregation with same
+ * boundaries */
+ std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept override;
+
+ /* Returns the new delta aggregation by comparing existing aggregation with next aggregation with
+ * same boundaries. Data points for `next` aggregation (sum , bucket-counts) should be more than
+ * the current aggregation - which is the normal scenario as measurements values are monotonic
+ * increasing.
+ */
+ std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept override;
+
+ PointType ToPoint() const noexcept override;
+
+private:
+ mutable opentelemetry::common::SpinLockMutex lock_;
+ mutable HistogramPointData point_data_;
+};
+
+template <class T>
+void HistogramMerge(HistogramPointData &current,
+ HistogramPointData &delta,
+ HistogramPointData &merge)
+{
+ for (size_t i = 0; i < current.counts_.size(); i++)
+ {
+ merge.counts_[i] = current.counts_[i] + delta.counts_[i];
+ }
+ merge.boundaries_ = current.boundaries_;
+ merge.sum_ = nostd::get<T>(current.sum_) + nostd::get<T>(delta.sum_);
+ merge.count_ = current.count_ + delta.count_;
+}
+
+template <class T>
+void HistogramDiff(HistogramPointData &current, HistogramPointData &next, HistogramPointData &diff)
+{
+ for (size_t i = 0; i < current.counts_.size(); i++)
+ {
+ diff.counts_[i] = next.counts_[i] - current.counts_[i];
+ }
+ diff.boundaries_ = current.boundaries_;
+ diff.count_ = next.count_ - current.count_;
+}
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h
new file mode 100644
index 000000000..3b2c08f8c
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h
@@ -0,0 +1,63 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
+
+# include <mutex>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class LongLastValueAggregation : public Aggregation
+{
+public:
+ LongLastValueAggregation();
+ LongLastValueAggregation(LastValuePointData &&);
+ LongLastValueAggregation(const LastValuePointData &);
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override;
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {}
+
+ std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept override;
+
+ std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept override;
+
+ PointType ToPoint() const noexcept override;
+
+private:
+ opentelemetry::common::SpinLockMutex lock_;
+ LastValuePointData point_data_;
+};
+
+class DoubleLastValueAggregation : public Aggregation
+{
+public:
+ DoubleLastValueAggregation();
+ DoubleLastValueAggregation(LastValuePointData &&);
+ DoubleLastValueAggregation(const LastValuePointData &);
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {}
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override;
+
+ virtual std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept override;
+
+ virtual std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept override;
+
+ PointType ToPoint() const noexcept override;
+
+private:
+ mutable opentelemetry::common::SpinLockMutex lock_;
+ mutable LastValuePointData point_data_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h
new file mode 100644
index 000000000..14f13bd72
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h
@@ -0,0 +1,64 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
+
+# include <mutex>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class LongSumAggregation : public Aggregation
+{
+public:
+ LongSumAggregation();
+ LongSumAggregation(SumPointData &&);
+ LongSumAggregation(const SumPointData &);
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override;
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {}
+
+ std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept override;
+
+ std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept override;
+
+ PointType ToPoint() const noexcept override;
+
+private:
+ opentelemetry::common::SpinLockMutex lock_;
+ SumPointData point_data_;
+};
+
+class DoubleSumAggregation : public Aggregation
+{
+public:
+ DoubleSumAggregation();
+ DoubleSumAggregation(SumPointData &&);
+ DoubleSumAggregation(const SumPointData &);
+
+ void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {}
+
+ void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override;
+
+ std::unique_ptr<Aggregation> Merge(const Aggregation &delta) const noexcept override;
+
+ std::unique_ptr<Aggregation> Diff(const Aggregation &next) const noexcept override;
+
+ PointType ToPoint() const noexcept override;
+
+private:
+ mutable opentelemetry::common::SpinLockMutex lock_;
+ SumPointData point_data_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/async_instruments.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/async_instruments.h
new file mode 100644
index 000000000..8b1f76377
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/async_instruments.h
@@ -0,0 +1,115 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/metrics/async_instruments.h"
+# include "opentelemetry/metrics/observer_result.h"
+# include "opentelemetry/nostd/string_view.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+template <class T>
+class Asynchronous
+{
+public:
+ Asynchronous(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<T> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : name_(name), callback_(callback), description_(description), unit_(unit)
+ {}
+
+protected:
+ std::string name_;
+ void (*callback_)(opentelemetry::metrics::ObserverResult<T> &);
+ std::string description_;
+ std::string unit_;
+};
+
+class LongObservableCounter : public opentelemetry::metrics::ObservableCounter<long>,
+ public Asynchronous<long>
+{
+public:
+ LongObservableCounter(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<long> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : Asynchronous(name, callback, description, unit)
+
+ {}
+};
+
+class DoubleObservableCounter : public opentelemetry::metrics::ObservableCounter<double>,
+ public Asynchronous<double>
+{
+public:
+ DoubleObservableCounter(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : Asynchronous(name, callback, description, unit)
+
+ {}
+};
+
+class LongObservableGauge : public opentelemetry::metrics::ObservableGauge<long>,
+ public Asynchronous<long>
+{
+public:
+ LongObservableGauge(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<long> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : Asynchronous(name, callback, description, unit)
+
+ {}
+};
+
+class DoubleObservableGauge : public opentelemetry::metrics::ObservableGauge<double>,
+ public Asynchronous<double>
+{
+public:
+ DoubleObservableGauge(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : Asynchronous(name, callback, description, unit)
+
+ {}
+};
+
+class LongObservableUpDownCounter : public opentelemetry::metrics::ObservableUpDownCounter<long>,
+ public Asynchronous<long>
+{
+public:
+ LongObservableUpDownCounter(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<long> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : Asynchronous(name, callback, description, unit)
+
+ {}
+};
+
+class DoubleObservableUpDownCounter
+ : public opentelemetry::metrics::ObservableUpDownCounter<double>,
+ public Asynchronous<double>
+{
+public:
+ DoubleObservableUpDownCounter(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double> &),
+ nostd::string_view description = "",
+ nostd::string_view unit = "")
+ : Asynchronous(name, callback, description, unit)
+ {}
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h
new file mode 100644
index 000000000..738d4540f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h
@@ -0,0 +1,42 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/nostd/variant.h"
+# include "opentelemetry/sdk/common/attribute_utils.h"
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+# include "opentelemetry/sdk/metrics/data/point_data.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+using PointAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
+using PointType = opentelemetry::nostd::
+ variant<SumPointData, HistogramPointData, LastValuePointData, DropPointData>;
+
+struct PointDataAttributes
+{
+ PointAttributes attributes;
+ PointType point_data;
+};
+
+class MetricData
+{
+public:
+ InstrumentDescriptor instrument_descriptor;
+ opentelemetry::common::SystemTimestamp start_ts;
+ opentelemetry::common::SystemTimestamp end_ts;
+ std::vector<PointDataAttributes> point_data_attr_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/point_data.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/point_data.h
new file mode 100644
index 000000000..714f96c9a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/data/point_data.h
@@ -0,0 +1,78 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/timestamp.h"
+# include "opentelemetry/nostd/variant.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/version.h"
+
+# include <list>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+using ValueType = nostd::variant<long, double>;
+using ListType = nostd::variant<std::list<long>, std::list<double>>;
+
+// TODO: remove ctors and initializers from below classes when GCC<5 stops shipping on Ubuntu
+
+class SumPointData
+{
+public:
+ // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu
+ SumPointData(SumPointData &&) = default;
+ SumPointData(const SumPointData &) = default;
+ SumPointData &operator=(SumPointData &&) = default;
+ SumPointData() = default;
+
+ ValueType value_ = {};
+};
+
+class LastValuePointData
+{
+public:
+ // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu
+ LastValuePointData(LastValuePointData &&) = default;
+ LastValuePointData(const LastValuePointData &) = default;
+ LastValuePointData &operator=(LastValuePointData &&) = default;
+ LastValuePointData() = default;
+
+ ValueType value_ = {};
+ bool is_lastvalue_valid_ = {};
+ opentelemetry::common::SystemTimestamp sample_ts_ = {};
+};
+
+class HistogramPointData
+{
+public:
+ // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu
+ HistogramPointData(HistogramPointData &&) = default;
+ HistogramPointData &operator=(HistogramPointData &&) = default;
+ HistogramPointData(const HistogramPointData &) = default;
+ HistogramPointData() = default;
+
+ ListType boundaries_ = {};
+ ValueType sum_ = {};
+ std::vector<uint64_t> counts_ = {};
+ uint64_t count_ = {};
+};
+
+class DropPointData
+{
+public:
+ // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu
+ DropPointData(DropPointData &&) = default;
+ DropPointData(const DropPointData &) = default;
+ DropPointData() = default;
+ DropPointData &operator=(DropPointData &&) = default;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h
new file mode 100644
index 000000000..5e7f0436e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h
@@ -0,0 +1,43 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/metrics/exemplar/filter.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class AlwaysSampleFilter final : public ExemplarFilter
+{
+public:
+ static nostd::shared_ptr<ExemplarFilter> GetAlwaysSampleFilter()
+ {
+ static nostd::shared_ptr<ExemplarFilter> alwaysSampleFilter{new AlwaysSampleFilter{}};
+ return alwaysSampleFilter;
+ }
+
+ bool ShouldSampleMeasurement(long value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ return true;
+ }
+
+ bool ShouldSampleMeasurement(double value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ return true;
+ }
+
+private:
+ explicit AlwaysSampleFilter() = default;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h
new file mode 100644
index 000000000..14eac6249
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h
@@ -0,0 +1,45 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/timestamp.h"
+# include "opentelemetry/context/context.h"
+# include "opentelemetry/sdk/common/attribute_utils.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
+/**
+ * A sample input measurement.
+ *
+ * Exemplars also hold information about the environment when the measurement was recorded, for
+ * example the span and trace ID of the active span when the exemplar was recorded.
+ */
+class ExemplarData
+{
+public:
+ /**
+ * The set of key/value pairs that were filtered out by the aggregator, but recorded alongside the
+ * original measurement. Only key/value pairs that were filtered out by the aggregator should be
+ * included
+ */
+ MetricAttributes GetFilteredAttributes();
+
+ /** Returns the timestamp in nanos when measurement was collected. */
+ opentelemetry::common::SystemTimestamp GetEpochNanos();
+
+ /**
+ * Returns the SpanContext associated with this exemplar. If the exemplar was not recorded
+ * inside a sampled trace, the Context will be invalid.
+ */
+ opentelemetry::context::Context GetSpanContext();
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h
new file mode 100644
index 000000000..4b512e131
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h
@@ -0,0 +1,39 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/context/context.h"
+# include "opentelemetry/sdk/common/attribute_utils.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
+
+/**
+ * Exemplar filters are used to pre-filter measurements before attempting to store them in a
+ * reservoir.
+ */
+class ExemplarFilter
+{
+public:
+ // Returns whether or not a reservoir should attempt to filter a measurement.
+ virtual bool ShouldSampleMeasurement(long value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context) noexcept = 0;
+
+ // Returns whether or not a reservoir should attempt to filter a measurement.
+ virtual bool ShouldSampleMeasurement(double value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context) noexcept = 0;
+
+ virtual ~ExemplarFilter() = default;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h
new file mode 100644
index 000000000..38f51778c
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h
@@ -0,0 +1,43 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/metrics/exemplar/filter.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class NeverSampleFilter final : public ExemplarFilter
+{
+public:
+ static nostd::shared_ptr<ExemplarFilter> GetNeverSampleFilter()
+ {
+ nostd::shared_ptr<ExemplarFilter> neverSampleFilter{new NeverSampleFilter{}};
+ return neverSampleFilter;
+ }
+
+ bool ShouldSampleMeasurement(long value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ return false;
+ }
+
+ bool ShouldSampleMeasurement(double value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ return false;
+ }
+
+private:
+ explicit NeverSampleFilter() = default;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h
new file mode 100644
index 000000000..1fe0586d2
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h
@@ -0,0 +1,55 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <vector>
+# include "opentelemetry/context/context.h"
+# include "opentelemetry/nostd/shared_ptr.h"
+# include "opentelemetry/sdk/common/attribute_utils.h"
+# include "opentelemetry/sdk/metrics/exemplar/reservoir.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class NoExemplarReservoir final : public ExemplarReservoir
+{
+
+public:
+ static nostd::shared_ptr<ExemplarReservoir> GetNoExemplarReservoir()
+ {
+ return nostd::shared_ptr<ExemplarReservoir>{new NoExemplarReservoir{}};
+ }
+
+ void OfferMeasurement(long value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context,
+ const opentelemetry::common::SystemTimestamp &timestamp) noexcept override
+ {
+ // Stores nothing
+ }
+
+ void OfferMeasurement(double value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context,
+ const opentelemetry::common::SystemTimestamp &timestamp) noexcept override
+ {
+ // Stores nothing.
+ }
+
+ std::vector<ExemplarData> CollectAndReset(
+ const MetricAttributes &pointAttributes) noexcept override
+ {
+ return std::vector<ExemplarData>{};
+ }
+
+private:
+ explicit NoExemplarReservoir() = default;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h
new file mode 100644
index 000000000..25e8421d6
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h
@@ -0,0 +1,55 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <vector>
+# include "opentelemetry/sdk/metrics/exemplar/data.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+/**
+ * An interface for an exemplar reservoir of samples.
+ *
+ * <p>This represents a reservoir for a specific "point" of metric data.
+ */
+class ExemplarReservoir
+{
+public:
+ virtual ~ExemplarReservoir() = default;
+
+ /** Offers a long measurement to be sampled. */
+ virtual void OfferMeasurement(
+ long value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context,
+ const opentelemetry::common::SystemTimestamp &timestamp) noexcept = 0;
+
+ /** Offers a double measurement to be sampled. */
+ virtual void OfferMeasurement(
+ double value,
+ const MetricAttributes &attributes,
+ const opentelemetry::context::Context &context,
+ const opentelemetry::common::SystemTimestamp &timestamp) noexcept = 0;
+
+ /**
+ * Builds vector of Exemplars for exporting from the current reservoir.
+ *
+ * <p>Additionally, clears the reservoir for the next sampling period.
+ *
+ * @param pointAttributes the Attributes associated with the metric point.
+ * ExemplarDatas should filter these out of their final data state.
+ * @return A vector of sampled exemplars for this point. Implementers are expected to
+ * filter out pointAttributes from the original recorded attributes.
+ */
+ virtual std::vector<ExemplarData> CollectAndReset(
+ const MetricAttributes &pointAttributes) noexcept = 0;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h
new file mode 100644
index 000000000..d3b38759a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h
@@ -0,0 +1,57 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+# include "opentelemetry/sdk/metrics/data/metric_data.h"
+# include "opentelemetry/sdk/resource/resource.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+/**
+ * Metric Data to be exported along with resources and
+ * Instrumentation library.
+ */
+struct InstrumentationInfoMetrics
+{
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ *instrumentation_library_;
+ std::vector<MetricData> metric_data_;
+};
+
+struct ResourceMetrics
+{
+ const opentelemetry::sdk::resource::Resource *resource_;
+ std::vector<InstrumentationInfoMetrics> instrumentation_info_metric_data_;
+};
+
+/**
+ * MetricProducer is the interface that is used to make metric data available to the
+ * OpenTelemetry exporters. Implementations should be stateful, in that each call to
+ * `Collect` will return any metric generated since the last call was made.
+ *
+ * <p>Implementations must be thread-safe.
+ */
+
+class MetricProducer
+{
+public:
+ /**
+ * The callback to be called for each metric exporter. This will only be those
+ * metrics that have been produced since the last time this method was called.
+ *
+ * @return a status of completion of method.
+ */
+ virtual bool Collect(
+ nostd::function_ref<bool(ResourceMetrics &metric_data)> callback) noexcept = 0;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h
new file mode 100644
index 000000000..29125a6ea
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h
@@ -0,0 +1,72 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/sdk/metrics/metric_reader.h"
+# include "opentelemetry/version.h"
+
+# include <atomic>
+# include <chrono>
+# include <condition_variable>
+# include <thread>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class MetricExporter;
+/**
+ * Struct to hold PeriodicExortingMetricReader options.
+ */
+
+constexpr std::chrono::milliseconds kExportIntervalMillis = std::chrono::milliseconds(60000);
+constexpr std::chrono::milliseconds kExportTimeOutMillis = std::chrono::milliseconds(30000);
+struct PeriodicExportingMetricReaderOptions
+{
+
+ /* The time interval between two consecutive exports. */
+ std::chrono::milliseconds export_interval_millis =
+ std::chrono::milliseconds(kExportIntervalMillis);
+
+ /* how long the export can run before it is cancelled. */
+ std::chrono::milliseconds export_timeout_millis = std::chrono::milliseconds(kExportTimeOutMillis);
+};
+
+class PeriodicExportingMetricReader : public MetricReader
+{
+
+public:
+ PeriodicExportingMetricReader(
+ std::unique_ptr<MetricExporter> exporter,
+ const PeriodicExportingMetricReaderOptions &option,
+ AggregationTemporality aggregation_temporality = AggregationTemporality::kCumulative);
+
+private:
+ bool OnForceFlush(std::chrono::microseconds timeout) noexcept override;
+
+ bool OnShutDown(std::chrono::microseconds timeout) noexcept override;
+
+ void OnInitialized() noexcept override;
+
+ std::unique_ptr<MetricExporter> exporter_;
+ std::chrono::milliseconds export_interval_millis_;
+ std::chrono::milliseconds export_timeout_millis_;
+
+ void DoBackgroundWork();
+
+ /* The background worker thread */
+ std::thread worker_thread_;
+
+ /* Synchronization primitives */
+ std::condition_variable cv_;
+ std::mutex cv_m_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/instruments.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/instruments.h
new file mode 100644
index 000000000..5d8535714
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/instruments.h
@@ -0,0 +1,70 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/common/attribute_utils.h"
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+enum class InstrumentType
+{
+ kCounter,
+ kHistogram,
+ kUpDownCounter,
+ kObservableCounter,
+ kObservableGauge,
+ kObservableUpDownCounter
+};
+
+enum class InstrumentValueType
+{
+ kInt,
+ kLong,
+ kFloat,
+ kDouble
+};
+
+enum class AggregationType
+{
+ kDrop,
+ kHistogram,
+ kLastValue,
+ kSum,
+ kDefault
+};
+
+enum class AggregationTemporality
+{
+ kUnspecified,
+ kDelta,
+ kCumulative
+};
+
+struct InstrumentDescriptor
+{
+ std::string name_;
+ std::string description_;
+ std::string unit_;
+ InstrumentType type_;
+ InstrumentValueType value_type_;
+};
+
+using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
+
+/*class InstrumentSelector {
+public:
+InstrumentSelector(opentelemetry::nostd::string_view name,
+opentelemetry::sdk::metrics::InstrumentType type): name_(name.data()), type_(type) {} InstrumentType
+GetType(){return type_;} std::string GetNameFilter() { return name_;}
+
+private:
+std::string name_;
+InstrumentType type_;
+};*/
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter.h
new file mode 100644
index 000000000..44e54adf1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter.h
@@ -0,0 +1,156 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <chrono>
+# include "opentelemetry/metrics/meter.h"
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/sdk/metrics/meter_context.h"
+# include "opentelemetry/sdk/metrics/state/async_metric_storage.h"
+
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class MetricStorage;
+class WritableMetricStorage;
+
+class Meter final : public opentelemetry::metrics::Meter
+{
+public:
+ /** Construct a new Meter with the given pipeline. */
+ explicit Meter(std::shared_ptr<sdk::metrics::MeterContext> meter_context,
+ std::unique_ptr<opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary>
+ instrumentation_library =
+ opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create(
+ "")) noexcept;
+
+ nostd::shared_ptr<opentelemetry::metrics::Counter<long>> CreateLongCounter(
+ nostd::string_view name,
+ nostd::string_view description = "",
+ nostd::string_view unit = "") noexcept override;
+
+ nostd::shared_ptr<opentelemetry::metrics::Counter<double>> CreateDoubleCounter(
+ nostd::string_view name,
+ nostd::string_view description = "",
+ nostd::string_view unit = "") noexcept override;
+
+ void CreateLongObservableCounter(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<long> &,
+ void *),
+ nostd::string_view description = "",
+ nostd::string_view unit = "",
+ void *state = nullptr) noexcept override;
+
+ void CreateDoubleObservableCounter(
+ nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double> &, void *),
+ nostd::string_view description = "",
+ nostd::string_view unit = "",
+ void *state = nullptr) noexcept override;
+
+ nostd::shared_ptr<opentelemetry::metrics::Histogram<long>> CreateLongHistogram(
+ nostd::string_view name,
+ nostd::string_view description = "",
+ nostd::string_view unit = "") noexcept override;
+
+ nostd::shared_ptr<opentelemetry::metrics::Histogram<double>> CreateDoubleHistogram(
+ nostd::string_view name,
+ nostd::string_view description = "",
+ nostd::string_view unit = "") noexcept override;
+
+ void CreateLongObservableGauge(nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<long> &,
+ void *),
+ nostd::string_view description = "",
+ nostd::string_view unit = "",
+ void *state = nullptr) noexcept override;
+
+ void CreateDoubleObservableGauge(
+ nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double> &, void *),
+ nostd::string_view description = "",
+ nostd::string_view unit = "",
+ void *state = nullptr) noexcept override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownCounter<long>> CreateLongUpDownCounter(
+ nostd::string_view name,
+ nostd::string_view description = "",
+ nostd::string_view unit = "") noexcept override;
+
+ nostd::shared_ptr<opentelemetry::metrics::UpDownCounter<double>> CreateDoubleUpDownCounter(
+ nostd::string_view name,
+ nostd::string_view description = "",
+ nostd::string_view unit = "") noexcept override;
+
+ void CreateLongObservableUpDownCounter(
+ nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<long> &, void *),
+ nostd::string_view description = "",
+ nostd::string_view unit = "",
+ void *state = nullptr) noexcept override;
+
+ void CreateDoubleObservableUpDownCounter(
+ nostd::string_view name,
+ void (*callback)(opentelemetry::metrics::ObserverResult<double> &, void *),
+ nostd::string_view description = "",
+ nostd::string_view unit = "",
+ void *state = nullptr) noexcept override;
+
+ /** Returns the associated instruementation library */
+ const sdk::instrumentationlibrary::InstrumentationLibrary *GetInstrumentationLibrary()
+ const noexcept;
+
+ /** collect metrics across all the instruments configured for the meter **/
+ std::vector<MetricData> Collect(CollectorHandle *collector,
+ opentelemetry::common::SystemTimestamp collect_ts) noexcept;
+
+private:
+ // order of declaration is important here - instrumentation library should destroy after
+ // meter-context.
+ std::unique_ptr<sdk::instrumentationlibrary::InstrumentationLibrary> instrumentation_library_;
+ std::shared_ptr<sdk::metrics::MeterContext> meter_context_;
+ // Mapping between instrument-name and Aggregation Storage.
+ std::unordered_map<std::string, std::shared_ptr<MetricStorage>> storage_registry_;
+
+ std::unique_ptr<WritableMetricStorage> RegisterMetricStorage(
+ InstrumentDescriptor &instrument_descriptor);
+
+ template <class T>
+ void RegisterAsyncMetricStorage(InstrumentDescriptor &instrument_descriptor,
+ void (*callback)(opentelemetry::metrics::ObserverResult<T> &,
+ void *),
+ void *state = nullptr)
+ {
+ auto view_registry = meter_context_->GetViewRegistry();
+ auto success = view_registry->FindViews(
+ instrument_descriptor, *instrumentation_library_,
+ [this, &instrument_descriptor, callback, state](const View &view) {
+ auto view_instr_desc = instrument_descriptor;
+ if (!view.GetName().empty())
+ {
+ view_instr_desc.name_ = view.GetName();
+ }
+ if (!view.GetDescription().empty())
+ {
+ view_instr_desc.description_ = view.GetDescription();
+ }
+ auto storage = std::shared_ptr<AsyncMetricStorage<T>>(
+ new AsyncMetricStorage<T>(view_instr_desc, view.GetAggregationType(), callback,
+ &view.GetAttributesProcessor(), state));
+ storage_registry_[instrument_descriptor.name_] = storage;
+ return true;
+ });
+ }
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_context.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_context.h
new file mode 100644
index 000000000..e35700175
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_context.h
@@ -0,0 +1,133 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/metrics/state/metric_collector.h"
+# include "opentelemetry/sdk/metrics/view/instrument_selector.h"
+# include "opentelemetry/sdk/metrics/view/meter_selector.h"
+# include "opentelemetry/sdk/metrics/view/view_registry.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+# include <chrono>
+# include <memory>
+# include <vector>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+// forward declaration
+class Meter;
+class MetricReader;
+
+/**
+ * A class which stores the MeterProvider context.
+
+ */
+class MeterContext : public std::enable_shared_from_this<MeterContext>
+{
+public:
+ /**
+ * Initialize a new meter provider
+ * @param readers The readers to be configured with meter context.
+ * @param views The views to be configured with meter context.
+ * @param resource The resource for this meter context.
+ */
+ MeterContext(
+ std::unique_ptr<ViewRegistry> views = std::unique_ptr<ViewRegistry>(new ViewRegistry()),
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({})) noexcept;
+
+ /**
+ * Obtain the resource associated with this meter context.
+ * @return The resource for this meter context
+ */
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept;
+
+ /**
+ * Obtain the View Registry configured
+ * @return The reference to view registry
+ */
+ ViewRegistry *GetViewRegistry() const noexcept;
+
+ /**
+ * Obtain the configured meters.
+ *
+ */
+ nostd::span<std::shared_ptr<Meter>> GetMeters() noexcept;
+
+ /**
+ * Obtain the configured collectors.
+ *
+ */
+ nostd::span<std::shared_ptr<CollectorHandle>> GetCollectors() noexcept;
+
+ /**
+ * GET SDK Start time
+ *
+ */
+ opentelemetry::common::SystemTimestamp GetSDKStartTime() noexcept;
+
+ /**
+ * Attaches a metric reader to list of configured readers for this Meter context.
+ * @param reader The metric reader for this meter context. This
+ * must not be a nullptr.
+ *
+ * Note: This reader may not receive any in-flight meter data, but will get newly created meter
+ * data. Note: This method is not thread safe, and should ideally be called from main thread.
+ */
+ void AddMetricReader(std::unique_ptr<MetricReader> reader) noexcept;
+
+ /**
+ * Attaches a View to list of configured Views for this Meter context.
+ * @param view The Views for this meter context. This
+ * must not be a nullptr.
+ *
+ * Note: This view may not receive any in-flight meter data, but will get newly created meter
+ * data. Note: This method is not thread safe, and should ideally be called from main thread.
+ */
+ void AddView(std::unique_ptr<InstrumentSelector> instrument_selector,
+ std::unique_ptr<MeterSelector> meter_selector,
+ std::unique_ptr<View> view) noexcept;
+
+ /**
+ * Adds a meter to the list of configured meters.
+ * Note: This method is INTERNAL to sdk not thread safe.
+ *
+ * @param meter
+ */
+ void AddMeter(std::shared_ptr<Meter> meter);
+
+ /**
+ * Force all active Collectors to flush any buffered meter data
+ * within the given timeout.
+ */
+
+ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;
+
+ /**
+ * Shutdown the Collectors associated with this meter provider.
+ */
+ bool Shutdown() noexcept;
+
+private:
+ opentelemetry::sdk::resource::Resource resource_;
+ std::vector<std::shared_ptr<CollectorHandle>> collectors_;
+ std::unique_ptr<ViewRegistry> views_;
+ opentelemetry::common::SystemTimestamp sdk_start_ts_;
+ std::vector<std::shared_ptr<Meter>> meters_;
+
+ std::atomic_flag shutdown_latch_ = ATOMIC_FLAG_INIT;
+ opentelemetry::common::SpinLockMutex forceflush_lock_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_provider.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_provider.h
new file mode 100644
index 000000000..685f43e74
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/meter_provider.h
@@ -0,0 +1,95 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <memory>
+# include <mutex>
+# include <vector>
+# include "opentelemetry/metrics/meter.h"
+# include "opentelemetry/metrics/meter_provider.h"
+# include "opentelemetry/nostd/shared_ptr.h"
+# include "opentelemetry/sdk/metrics/meter.h"
+# include "opentelemetry/sdk/metrics/meter_context.h"
+# include "opentelemetry/sdk/resource/resource.h"
+# include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+// forward declaration
+class MetricCollector;
+class MetricReader;
+
+class MeterProvider final : public opentelemetry::metrics::MeterProvider
+{
+public:
+ /**
+ * Initialize a new meter provider
+ * @param views The views for this meter provider
+ * @param resource The resources for this meter provider.
+ */
+ MeterProvider(
+ std::unique_ptr<ViewRegistry> views = std::unique_ptr<ViewRegistry>(new ViewRegistry()),
+ sdk::resource::Resource resource = sdk::resource::Resource::Create({})) noexcept;
+
+ /**
+ * Initialize a new meter provider with a specified context
+ * @param context The shared meter configuration/pipeline for this provider.
+ */
+ explicit MeterProvider(std::shared_ptr<sdk::metrics::MeterContext> context) noexcept;
+
+ nostd::shared_ptr<opentelemetry::metrics::Meter> GetMeter(
+ nostd::string_view name,
+ nostd::string_view version = "",
+ nostd::string_view schema_url = "") noexcept override;
+
+ /**
+ * Obtain the resource associated with this meter provider.
+ * @return The resource for this meter provider.
+ */
+ const sdk::resource::Resource &GetResource() const noexcept;
+
+ /**
+ * Attaches a metric reader to list of configured readers for this Meter providers.
+ * @param reader The metric reader for this meter provider. This
+ * must not be a nullptr.
+ *
+ * Note: This reader may not receive any in-flight meter data, but will get newly created meter
+ * data. Note: This method is not thread safe, and should ideally be called from main thread.
+ */
+ void AddMetricReader(std::unique_ptr<MetricReader> reader) noexcept;
+
+ /**
+ * Attaches a View to list of configured Views for this Meter provider.
+ * @param view The Views for this meter provider. This
+ * must not be a nullptr.
+ *
+ * Note: This view may not receive any in-flight meter data, but will get newly created meter
+ * data. Note: This method is not thread safe, and should ideally be called from main thread.
+ */
+ void AddView(std::unique_ptr<InstrumentSelector> instrument_selector,
+ std::unique_ptr<MeterSelector> meter_selector,
+ std::unique_ptr<View> view) noexcept;
+
+ /**
+ * Shutdown the meter provider.
+ */
+ bool Shutdown() noexcept;
+
+ /**
+ * Force flush the meter provider.
+ */
+ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;
+
+private:
+ std::shared_ptr<sdk::metrics::MeterContext> context_;
+ std::mutex lock_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h
new file mode 100644
index 000000000..3217b83df
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h
@@ -0,0 +1,55 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+
+# include "opentelemetry/nostd/span.h"
+# include "opentelemetry/sdk/common/exporter_utils.h"
+# include "opentelemetry/sdk/metrics/export/metric_producer.h"
+# include "opentelemetry/version.h"
+
+# include <chrono>
+# include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class MetricData;
+/**
+ * MetricExporter defines the interface to be used by metrics libraries to
+ * push metrics data to the OpenTelemetry exporters.
+ */
+class MetricExporter
+{
+public:
+ virtual ~MetricExporter() = default;
+
+ /**
+ * Exports a batch of metrics data. This method must not be called
+ * concurrently for the same exporter instance.
+ * @param data metrics data
+ */
+ virtual opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &data) noexcept = 0;
+
+ /**
+ * Force flush the exporter.
+ */
+ virtual bool ForceFlush(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0;
+
+ /**
+ * Shut down the metric exporter.
+ * @param timeout an optional timeout.
+ * @return return the status of the operation.
+ */
+ virtual bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept = 0;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_reader.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_reader.h
new file mode 100644
index 000000000..94924315f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/metric_reader.h
@@ -0,0 +1,72 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/sdk/common/global_log_handler.h"
+# include "opentelemetry/sdk/metrics/data/metric_data.h"
+# include "opentelemetry/sdk/metrics/export/metric_producer.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/version.h"
+
+# include <chrono>
+# include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+/**
+ * MetricReader defines the interface to collect metrics from SDK
+ */
+class MetricReader
+{
+public:
+ MetricReader(
+ AggregationTemporality aggregation_temporality = AggregationTemporality::kCumulative);
+
+ void SetMetricProducer(MetricProducer *metric_producer);
+
+ /**
+ * Collect the metrics from SDK.
+ * @return return the status of the operation.
+ */
+ bool Collect(nostd::function_ref<bool(ResourceMetrics &metric_data)> callback) noexcept;
+
+ AggregationTemporality GetAggregationTemporality() const noexcept;
+
+ /**
+ * Shutdown the meter reader.
+ */
+ bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept;
+
+ /**
+ * Force flush the metric read by the reader.
+ */
+ bool ForceFlush(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept;
+
+ virtual ~MetricReader() = default;
+
+private:
+ virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept = 0;
+
+ virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept = 0;
+
+ virtual void OnInitialized() noexcept {}
+
+protected:
+ bool IsShutdown() const noexcept;
+
+private:
+ MetricProducer *metric_producer_;
+ AggregationTemporality aggregation_temporality_;
+ mutable opentelemetry::common::SpinLockMutex lock_;
+ bool shutdown_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/observer_result.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/observer_result.h
new file mode 100644
index 000000000..ca7227bc5
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/observer_result.h
@@ -0,0 +1,48 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/key_value_iterable.h"
+# include "opentelemetry/metrics/observer_result.h"
+# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h"
+# include "opentelemetry/sdk/metrics/view/attributes_processor.h"
+
+# include <map>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+template <class T>
+class ObserverResult final : public opentelemetry::metrics::ObserverResult<T>
+{
+public:
+ ObserverResult(const AttributesProcessor *attributes_processor)
+ : attributes_processor_(attributes_processor)
+ {}
+
+ void Observe(T value) noexcept override { data_.insert({{}, value}); }
+
+ void Observe(T value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override
+ {
+ auto attr = attributes_processor_->process(attributes);
+ data_.insert({attr, value});
+ }
+
+ const std::unordered_map<MetricAttributes, T, AttributeHashGenerator> &GetMeasurements()
+ {
+ return data_;
+ }
+
+private:
+ std::unordered_map<MetricAttributes, T, AttributeHashGenerator> data_;
+
+ const AttributesProcessor *attributes_processor_;
+};
+} // namespace metrics
+} // namespace sdk
+
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h
new file mode 100644
index 000000000..e5dcbc273
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h
@@ -0,0 +1,95 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/common/attributemap_hash.h"
+# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/sdk/metrics/observer_result.h"
+# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h"
+# include "opentelemetry/sdk/metrics/state/metric_collector.h"
+# include "opentelemetry/sdk/metrics/state/metric_storage.h"
+# include "opentelemetry/sdk/metrics/state/temporal_metric_storage.h"
+# include "opentelemetry/sdk/metrics/view/attributes_processor.h"
+
+# include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+template <class T>
+class AsyncMetricStorage : public MetricStorage
+{
+public:
+ AsyncMetricStorage(InstrumentDescriptor instrument_descriptor,
+ const AggregationType aggregation_type,
+ void (*measurement_callback)(opentelemetry::metrics::ObserverResult<T> &,
+ void *),
+ const AttributesProcessor *attributes_processor,
+ void *state = nullptr)
+ : instrument_descriptor_(instrument_descriptor),
+ aggregation_type_{aggregation_type},
+ measurement_collection_callback_{measurement_callback},
+ attributes_processor_{attributes_processor},
+ state_{state},
+ cumulative_hash_map_(new AttributesHashMap()),
+ temporal_metric_storage_(instrument_descriptor)
+ {}
+
+ bool Collect(CollectorHandle *collector,
+ nostd::span<std::shared_ptr<CollectorHandle>> collectors,
+ opentelemetry::common::SystemTimestamp sdk_start_ts,
+ opentelemetry::common::SystemTimestamp collection_ts,
+ nostd::function_ref<bool(MetricData)> metric_collection_callback) noexcept override
+ {
+ opentelemetry::sdk::metrics::ObserverResult<T> ob_res(attributes_processor_);
+
+ // read the measurement using configured callback
+ measurement_collection_callback_(ob_res, state_);
+ std::shared_ptr<AttributesHashMap> delta_hash_map(new AttributesHashMap());
+ // process the read measurements - aggregate and store in hashmap
+ for (auto &measurement : ob_res.GetMeasurements())
+ {
+ auto aggr = DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_);
+ aggr->Aggregate(measurement.second);
+ auto prev = cumulative_hash_map_->Get(measurement.first);
+ if (prev)
+ {
+ auto delta = prev->Diff(*aggr);
+ cumulative_hash_map_->Set(measurement.first,
+ DefaultAggregation::CloneAggregation(
+ aggregation_type_, instrument_descriptor_, *delta));
+ delta_hash_map->Set(measurement.first, std::move(delta));
+ }
+ else
+ {
+ cumulative_hash_map_->Set(
+ measurement.first,
+ DefaultAggregation::CloneAggregation(aggregation_type_, instrument_descriptor_, *aggr));
+ delta_hash_map->Set(measurement.first, std::move(aggr));
+ }
+ }
+
+ return temporal_metric_storage_.buildMetrics(collector, collectors, sdk_start_ts, collection_ts,
+ std::move(delta_hash_map),
+ metric_collection_callback);
+ }
+
+private:
+ InstrumentDescriptor instrument_descriptor_;
+ AggregationType aggregation_type_;
+ void (*measurement_collection_callback_)(opentelemetry::metrics::ObserverResult<T> &, void *);
+ const AttributesProcessor *attributes_processor_;
+ void *state_;
+ std::unique_ptr<AttributesHashMap> cumulative_hash_map_;
+ TemporalMetricStorage temporal_metric_storage_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h
new file mode 100644
index 000000000..50d40e0ae
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h
@@ -0,0 +1,124 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/spin_lock_mutex.h"
+# include "opentelemetry/nostd/function_ref.h"
+# include "opentelemetry/sdk/common/attribute_utils.h"
+# include "opentelemetry/sdk/common/attributemap_hash.h"
+# include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/version.h"
+
+# include <functional>
+# include <memory>
+# include <mutex>
+# include <unordered_map>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+using opentelemetry::sdk::common::OrderedAttributeMap;
+
+class AttributeHashGenerator
+{
+public:
+ size_t operator()(const MetricAttributes &attributes) const
+ {
+ return opentelemetry::sdk::common::GetHashForAttributeMap(attributes);
+ }
+};
+
+class AttributesHashMap
+{
+public:
+ Aggregation *Get(const MetricAttributes &attributes) const
+ {
+ std::lock_guard<opentelemetry::common::SpinLockMutex> guard(lock_);
+ auto it = hash_map_.find(attributes);
+ if (it != hash_map_.end())
+ {
+ return it->second.get();
+ }
+ return nullptr;
+ }
+
+ /**
+ * @return check if key is present in hash
+ *
+ */
+ bool Has(const MetricAttributes &attributes) const
+ {
+ std::lock_guard<opentelemetry::common::SpinLockMutex> guard(lock_);
+ return (hash_map_.find(attributes) == hash_map_.end()) ? false : true;
+ }
+
+ /**
+ * @return the pointer to value for given key if present.
+ * If not present, it uses the provided callback to generate
+ * value and store in the hash
+ */
+ Aggregation *GetOrSetDefault(const MetricAttributes &attributes,
+ std::function<std::unique_ptr<Aggregation>()> aggregation_callback)
+ {
+ std::lock_guard<opentelemetry::common::SpinLockMutex> guard(lock_);
+
+ auto it = hash_map_.find(attributes);
+ if (it != hash_map_.end())
+ {
+ return it->second.get();
+ }
+
+ hash_map_[attributes] = std::move(aggregation_callback());
+ return hash_map_[attributes].get();
+ }
+
+ /**
+ * Set the value for given key, overwriting the value if already present
+ */
+ void Set(const MetricAttributes &attributes, std::unique_ptr<Aggregation> value)
+ {
+ std::lock_guard<opentelemetry::common::SpinLockMutex> guard(lock_);
+ hash_map_[attributes] = std::move(value);
+ }
+
+ /**
+ * Iterate the hash to yield key and value stored in hash.
+ */
+ bool GetAllEnteries(
+ nostd::function_ref<bool(const MetricAttributes &, Aggregation &)> callback) const
+ {
+ std::lock_guard<opentelemetry::common::SpinLockMutex> guard(lock_);
+ for (auto &kv : hash_map_)
+ {
+ if (!callback(kv.first, *(kv.second.get())))
+ {
+ return false; // callback is not prepared to consume data
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return the size of hash.
+ */
+ size_t Size()
+ {
+ std::lock_guard<opentelemetry::common::SpinLockMutex> guard(lock_);
+ return hash_map_.size();
+ }
+
+private:
+ std::unordered_map<MetricAttributes, std::unique_ptr<Aggregation>, AttributeHashGenerator>
+ hash_map_;
+
+ mutable opentelemetry::common::SpinLockMutex lock_;
+};
+} // namespace metrics
+
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h
new file mode 100644
index 000000000..20372f520
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h
@@ -0,0 +1,57 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/metrics/data/metric_data.h"
+# include "opentelemetry/sdk/metrics/export/metric_producer.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class MetricReader;
+class MeterContext;
+
+class CollectorHandle
+{
+public:
+ virtual AggregationTemporality GetAggregationTemporality() noexcept = 0;
+};
+
+/**
+ * An internal opaque interface that the MetricReader receives as
+ * MetricProducer. It acts as the storage key to the internal metric stream
+ * state for each MetricReader.
+ */
+
+class MetricCollector : public MetricProducer, public CollectorHandle
+{
+public:
+ MetricCollector(std::shared_ptr<MeterContext> &&context,
+ std::unique_ptr<MetricReader> metric_reader);
+
+ AggregationTemporality GetAggregationTemporality() noexcept override;
+
+ /**
+ * The callback to be called for each metric exporter. This will only be those
+ * metrics that have been produced since the last time this method was called.
+ *
+ * @return a status of completion of method.
+ */
+ bool Collect(nostd::function_ref<bool(ResourceMetrics &metric_data)> callback) noexcept override;
+
+ bool ForceFlush(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept;
+
+ bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept;
+
+private:
+ std::shared_ptr<MeterContext> meter_context_;
+ std::shared_ptr<MetricReader> metric_reader_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h
new file mode 100644
index 000000000..e0ba55cbf
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h
@@ -0,0 +1,86 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/key_value_iterable_view.h"
+# include "opentelemetry/common/timestamp.h"
+# include "opentelemetry/context/context.h"
+# include "opentelemetry/sdk/metrics/data/metric_data.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+/* Represent the storage from which to collect the metrics */
+class CollectorHandle;
+
+class MetricStorage
+{
+public:
+ /* collect the metrics from this storage */
+ virtual bool Collect(CollectorHandle *collector,
+ nostd::span<std::shared_ptr<CollectorHandle>> collectors,
+ opentelemetry::common::SystemTimestamp sdk_start_ts,
+ opentelemetry::common::SystemTimestamp collection_ts,
+ nostd::function_ref<bool(MetricData)> callback) noexcept = 0;
+};
+
+class WritableMetricStorage
+{
+public:
+ virtual void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0;
+
+ virtual void RecordLong(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept = 0;
+
+ virtual void RecordDouble(double value,
+ const opentelemetry::context::Context &context) noexcept = 0;
+
+ virtual void RecordDouble(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept = 0;
+
+ virtual ~WritableMetricStorage() = default;
+};
+
+class NoopMetricStorage : public MetricStorage
+{
+public:
+ bool Collect(CollectorHandle *collector,
+ nostd::span<std::shared_ptr<CollectorHandle>> collectors,
+ opentelemetry::common::SystemTimestamp sdk_start_ts,
+ opentelemetry::common::SystemTimestamp collection_ts,
+ nostd::function_ref<bool(MetricData)> callback) noexcept override
+ {
+ MetricData metric_data;
+ return callback(std::move(metric_data));
+ }
+};
+
+class NoopWritableMetricStorage : public WritableMetricStorage
+{
+public:
+ void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0;
+
+ void RecordLong(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {}
+
+ void RecordDouble(double value, const opentelemetry::context::Context &context) noexcept override
+ {}
+
+ void RecordDouble(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {}
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h
new file mode 100644
index 000000000..ceeafa040
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h
@@ -0,0 +1,68 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/key_value_iterable_view.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/sdk/metrics/state/metric_storage.h"
+
+# include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+class MultiMetricStorage : public WritableMetricStorage
+{
+public:
+ void AddStorage(std::shared_ptr<WritableMetricStorage> storage) { storages_.push_back(storage); }
+
+ virtual void RecordLong(long value,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ for (auto &s : storages_)
+ {
+ s->RecordLong(value, context);
+ }
+ }
+
+ virtual void RecordLong(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ for (auto &s : storages_)
+ {
+ s->RecordLong(value, attributes, context);
+ }
+ }
+
+ virtual void RecordDouble(double value,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ for (auto &s : storages_)
+ {
+ s->RecordDouble(value, context);
+ }
+ }
+
+ virtual void RecordDouble(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ for (auto &s : storages_)
+ {
+ s->RecordDouble(value, attributes, context);
+ }
+ }
+
+private:
+ std::vector<std::shared_ptr<WritableMetricStorage>> storages_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h
new file mode 100644
index 000000000..278f7dbe3
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h
@@ -0,0 +1,119 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/key_value_iterable_view.h"
+# include "opentelemetry/sdk/common/attributemap_hash.h"
+# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
+# include "opentelemetry/sdk/metrics/exemplar/reservoir.h"
+# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h"
+# include "opentelemetry/sdk/metrics/state/metric_collector.h"
+# include "opentelemetry/sdk/metrics/state/metric_storage.h"
+
+# include "opentelemetry/sdk/metrics/state/temporal_metric_storage.h"
+# include "opentelemetry/sdk/metrics/view/attributes_processor.h"
+
+# include <list>
+# include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class SyncMetricStorage : public MetricStorage, public WritableMetricStorage
+{
+
+public:
+ SyncMetricStorage(InstrumentDescriptor instrument_descriptor,
+ const AggregationType aggregation_type,
+ const AttributesProcessor *attributes_processor,
+ nostd::shared_ptr<ExemplarReservoir> &&exemplar_reservoir)
+ : instrument_descriptor_(instrument_descriptor),
+ aggregation_type_{aggregation_type},
+ attributes_hashmap_(new AttributesHashMap()),
+ attributes_processor_{attributes_processor},
+ exemplar_reservoir_(exemplar_reservoir),
+ temporal_metric_storage_(instrument_descriptor)
+
+ {
+ create_default_aggregation_ = [&]() -> std::unique_ptr<Aggregation> {
+ return std::move(
+ DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_));
+ };
+ }
+
+ void RecordLong(long value, const opentelemetry::context::Context &context) noexcept override
+ {
+ if (instrument_descriptor_.value_type_ != InstrumentValueType::kLong)
+ {
+ return;
+ }
+ exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now());
+ attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value);
+ }
+
+ void RecordLong(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ if (instrument_descriptor_.value_type_ != InstrumentValueType::kLong)
+ {
+ return;
+ }
+
+ exemplar_reservoir_->OfferMeasurement(value, attributes, context,
+ std::chrono::system_clock::now());
+ auto attr = attributes_processor_->process(attributes);
+ attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value);
+ }
+
+ void RecordDouble(double value, const opentelemetry::context::Context &context) noexcept override
+ {
+ if (instrument_descriptor_.value_type_ != InstrumentValueType::kDouble)
+ {
+ return;
+ }
+ exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now());
+ attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value);
+ }
+
+ void RecordDouble(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override
+ {
+ exemplar_reservoir_->OfferMeasurement(value, attributes, context,
+ std::chrono::system_clock::now());
+ if (instrument_descriptor_.value_type_ != InstrumentValueType::kDouble)
+ {
+ return;
+ }
+ exemplar_reservoir_->OfferMeasurement(value, attributes, context,
+ std::chrono::system_clock::now());
+ auto attr = attributes_processor_->process(attributes);
+ attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value);
+ }
+
+ bool Collect(CollectorHandle *collector,
+ nostd::span<std::shared_ptr<CollectorHandle>> collectors,
+ opentelemetry::common::SystemTimestamp sdk_start_ts,
+ opentelemetry::common::SystemTimestamp collection_ts,
+ nostd::function_ref<bool(MetricData)> callback) noexcept override;
+
+private:
+ InstrumentDescriptor instrument_descriptor_;
+ AggregationType aggregation_type_;
+
+ // hashmap to maintain the metrics for delta collection (i.e, collection since last Collect call)
+ std::unique_ptr<AttributesHashMap> attributes_hashmap_;
+ const AttributesProcessor *attributes_processor_;
+ std::function<std::unique_ptr<Aggregation>()> create_default_aggregation_;
+ nostd::shared_ptr<ExemplarReservoir> exemplar_reservoir_;
+ TemporalMetricStorage temporal_metric_storage_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h
new file mode 100644
index 000000000..16659c14f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h
@@ -0,0 +1,50 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h"
+# include "opentelemetry/sdk/metrics/state/metric_collector.h"
+
+# include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+struct LastReportedMetrics
+{
+ std::unique_ptr<AttributesHashMap> attributes_map;
+ opentelemetry::common::SystemTimestamp collection_ts;
+};
+
+class TemporalMetricStorage
+{
+public:
+ TemporalMetricStorage(InstrumentDescriptor instrument_descriptor);
+
+ bool buildMetrics(CollectorHandle *collector,
+ nostd::span<std::shared_ptr<CollectorHandle>> collectors,
+ opentelemetry::common::SystemTimestamp sdk_start_ts,
+ opentelemetry::common::SystemTimestamp collection_ts,
+ std::shared_ptr<AttributesHashMap> delta_metrics,
+ nostd::function_ref<bool(MetricData)> callback) noexcept;
+
+private:
+ InstrumentDescriptor instrument_descriptor_;
+
+ // unreported metrics stash for all the collectors
+ std::unordered_map<CollectorHandle *, std::list<std::shared_ptr<AttributesHashMap>>>
+ unreported_metrics_;
+ // last reported metrics stash for all the collectors.
+ std::unordered_map<CollectorHandle *, LastReportedMetrics> last_reported_metrics_;
+
+ // Lock while building metrics
+ mutable opentelemetry::common::SpinLockMutex lock_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h
new file mode 100644
index 000000000..f4c9bae32
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h
@@ -0,0 +1,127 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/common/key_value_iterable.h"
+# include "opentelemetry/metrics/sync_instruments.h"
+# include "opentelemetry/nostd/string_view.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+// forward declaration
+class WritableMetricStorage;
+
+class Synchronous
+{
+public:
+ Synchronous(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage)
+ : instrument_descriptor_(instrument_descriptor), storage_(std::move(storage))
+ {}
+
+protected:
+ InstrumentDescriptor instrument_descriptor_;
+ std::unique_ptr<WritableMetricStorage> storage_;
+};
+
+class LongCounter : public Synchronous, public opentelemetry::metrics::Counter<long>
+{
+public:
+ LongCounter(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage);
+
+ void Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override;
+ void Add(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override;
+
+ void Add(long value) noexcept override;
+ void Add(long value, const opentelemetry::context::Context &context) noexcept override;
+};
+
+class DoubleCounter : public Synchronous, public opentelemetry::metrics::Counter<double>
+{
+
+public:
+ DoubleCounter(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage);
+
+ void Add(double value,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept override;
+ void Add(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override;
+
+ void Add(double value) noexcept override;
+ void Add(double value, const opentelemetry::context::Context &context) noexcept override;
+};
+
+class LongUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter<long>
+{
+public:
+ LongUpDownCounter(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage);
+
+ void Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override;
+ void Add(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override;
+
+ void Add(long value) noexcept override;
+ void Add(long value, const opentelemetry::context::Context &context) noexcept override;
+};
+
+class DoubleUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter<double>
+{
+public:
+ DoubleUpDownCounter(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage);
+
+ void Add(double value,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept override;
+ void Add(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override;
+
+ void Add(double value) noexcept override;
+ void Add(double value, const opentelemetry::context::Context &context) noexcept override;
+};
+
+class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogram<long>
+{
+public:
+ LongHistogram(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage);
+
+ void Record(long value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override;
+
+ void Record(long value, const opentelemetry::context::Context &context) noexcept override;
+};
+
+class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histogram<double>
+{
+public:
+ DoubleHistogram(InstrumentDescriptor instrument_descriptor,
+ std::unique_ptr<WritableMetricStorage> storage);
+
+ void Record(double value,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::context::Context &context) noexcept override;
+
+ void Record(double value, const opentelemetry::context::Context &context) noexcept override;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h
new file mode 100644
index 000000000..d82607357
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h
@@ -0,0 +1,81 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/sdk/common/attribute_utils.h"
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
+
+/**
+ * The AttributesProcessor is responsible for customizing which
+ * attribute(s) are to be reported as metrics dimension(s).
+ */
+
+class AttributesProcessor
+{
+public:
+ // Process the metric instrument attributes.
+ // @returns The processed attributes
+ virtual MetricAttributes process(
+ const opentelemetry::common::KeyValueIterable &attributes) const noexcept = 0;
+
+ virtual ~AttributesProcessor() = default;
+};
+
+/**
+ * DefaultAttributesProcessor returns copy of input instrument attributes without
+ * any modification.
+ */
+
+class DefaultAttributesProcessor : public AttributesProcessor
+{
+ MetricAttributes process(
+ const opentelemetry::common::KeyValueIterable &attributes) const noexcept override
+ {
+ MetricAttributes result(attributes);
+ return result;
+ }
+};
+
+/**
+ * FilteringAttributesProcessor filters by allowed attribute names and drops any names
+ * that are not in the allow list.
+ */
+
+class FilteringAttributesProcessor : public AttributesProcessor
+{
+public:
+ FilteringAttributesProcessor(
+ const std::unordered_map<std::string, bool> allowed_attribute_keys = {})
+ : allowed_attribute_keys_(std::move(allowed_attribute_keys))
+ {}
+
+ MetricAttributes process(
+ const opentelemetry::common::KeyValueIterable &attributes) const noexcept override
+ {
+ MetricAttributes result;
+ attributes.ForEachKeyValue(
+ [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
+ if (allowed_attribute_keys_.find(key.data()) != allowed_attribute_keys_.end())
+ {
+ result.SetAttribute(key, value);
+ return true;
+ }
+ return true;
+ });
+ return result;
+ }
+
+private:
+ std::unordered_map<std::string, bool> allowed_attribute_keys_;
+};
+
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h
new file mode 100644
index 000000000..e79a292c0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h
@@ -0,0 +1,36 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/nostd/string_view.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/sdk/metrics/view/predicate_factory.h"
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class InstrumentSelector
+{
+public:
+ InstrumentSelector(opentelemetry::sdk::metrics::InstrumentType instrument_type,
+ opentelemetry::nostd::string_view name)
+ : name_filter_{std::move(PredicateFactory::GetPredicate(name, PredicateType::kPattern))},
+ instrument_type_{instrument_type}
+ {}
+
+ // Returns name filter predicate. This shouldn't be deleted
+ const opentelemetry::sdk::metrics::Predicate *const GetNameFilter() { return name_filter_.get(); }
+
+ // Returns instrument filter.
+ InstrumentType GetInstrumentType() { return instrument_type_; }
+
+private:
+ std::unique_ptr<opentelemetry::sdk::metrics::Predicate> name_filter_;
+ opentelemetry::sdk::metrics::InstrumentType instrument_type_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/meter_selector.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/meter_selector.h
new file mode 100644
index 000000000..d0bc07ccb
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/meter_selector.h
@@ -0,0 +1,47 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/sdk/metrics/view/predicate_factory.h"
+#ifndef ENABLE_METRICS_PREVIEW
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class MeterSelector
+{
+public:
+ MeterSelector(opentelemetry::nostd::string_view name,
+ opentelemetry::nostd::string_view version,
+ opentelemetry::nostd::string_view schema)
+ : name_filter_{std::move(PredicateFactory::GetPredicate(name, PredicateType::kExact))},
+ version_filter_{std::move(PredicateFactory::GetPredicate(version, PredicateType::kExact))},
+ schema_filter_{std::move(PredicateFactory::GetPredicate(schema, PredicateType::kExact))}
+ {}
+
+ // Returns name filter predicate. This shouldn't be deleted
+ const opentelemetry::sdk::metrics::Predicate *const GetNameFilter() { return name_filter_.get(); }
+
+ // Returns version filter predicate. This shouldn't be deleted
+ const opentelemetry::sdk::metrics::Predicate *const GetVersionFilter()
+ {
+ return version_filter_.get();
+ }
+
+ // Returns schema filter predicate. This shouldn't be deleted
+ const opentelemetry::sdk::metrics::Predicate *const GetSchemaFilter()
+ {
+ return schema_filter_.get();
+ }
+
+private:
+ std::unique_ptr<opentelemetry::sdk::metrics::Predicate> name_filter_;
+ std::unique_ptr<opentelemetry::sdk::metrics::Predicate> version_filter_;
+ std::unique_ptr<opentelemetry::sdk::metrics::Predicate> schema_filter_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate.h
new file mode 100644
index 000000000..72de2979a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate.h
@@ -0,0 +1,82 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <vector>
+# if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9))
+# define HAVE_WORKING_REGEX 0
+# include "opentelemetry/sdk/common/global_log_handler.h"
+# else
+# include <regex>
+# define HAVE_WORKING_REGEX 1
+# endif
+
+# include "opentelemetry/nostd/string_view.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+class Predicate
+{
+public:
+ virtual ~Predicate() = default;
+ virtual bool Match(opentelemetry::nostd::string_view string) const noexcept = 0;
+};
+
+class PatternPredicate : public Predicate
+{
+public:
+ PatternPredicate(opentelemetry::nostd::string_view pattern) : reg_key_{pattern.data()} {}
+ bool Match(opentelemetry::nostd::string_view str) const noexcept override
+ {
+# if HAVE_WORKING_REGEX
+ return std::regex_match(str.data(), reg_key_);
+# else
+ // TBD - Support regex match for GCC4.8
+ OTEL_INTERNAL_LOG_ERROR(
+ "PatternPredicate::Match - failed. std::regex not fully supported for this compiler.");
+ return false; // not supported
+# endif
+ }
+
+private:
+# if HAVE_WORKING_REGEX
+ std::regex reg_key_;
+# else
+ std::string reg_key_;
+# endif
+};
+
+class ExactPredicate : public Predicate
+{
+public:
+ ExactPredicate(opentelemetry::nostd::string_view pattern) : pattern_{pattern} {}
+ bool Match(opentelemetry::nostd::string_view str) const noexcept override
+ {
+ if (pattern_ == str)
+ {
+ return true;
+ }
+ return false;
+ }
+
+private:
+ std::string pattern_;
+};
+
+class MatchEverythingPattern : public Predicate
+{
+ bool Match(opentelemetry::nostd::string_view str) const noexcept override { return true; }
+};
+
+class MatchNothingPattern : public Predicate
+{
+ bool Match(opentelemetry::nostd::string_view str) const noexcept override { return false; }
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate_factory.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate_factory.h
new file mode 100644
index 000000000..466fa76d5
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/predicate_factory.h
@@ -0,0 +1,45 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/sdk/metrics/view/predicate.h"
+#ifndef ENABLE_METRICS_PREVIEW
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+
+enum class PredicateType : uint8_t
+{
+ kPattern,
+ kExact
+};
+
+class PredicateFactory
+{
+public:
+ static std::unique_ptr<Predicate> GetPredicate(opentelemetry::nostd::string_view pattern,
+ PredicateType type)
+ {
+ if ((type == PredicateType::kPattern && pattern == "*") ||
+ (type == PredicateType::kExact && pattern == ""))
+ {
+ return std::move(std::unique_ptr<Predicate>(new MatchEverythingPattern()));
+ }
+ if (type == PredicateType::kPattern)
+ {
+ return std::move(std::unique_ptr<Predicate>(new PatternPredicate(pattern)));
+ }
+ if (type == PredicateType::kExact)
+ {
+ return std::move(std::unique_ptr<Predicate>(new ExactPredicate(pattern)));
+ }
+ return std::move(std::unique_ptr<Predicate>(new MatchNothingPattern()));
+ }
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view.h
new file mode 100644
index 000000000..3cd9f850e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view.h
@@ -0,0 +1,57 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/nostd/string_view.h"
+# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
+# include "opentelemetry/sdk/metrics/instruments.h"
+# include "opentelemetry/sdk/metrics/view/attributes_processor.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+/**
+ * View defines the interface to allow SDK user to
+ * customize the metrics before exported.
+ */
+
+class View
+{
+public:
+ View(const std::string &name,
+ const std::string &description = "",
+ AggregationType aggregation_type = AggregationType::kDefault,
+ std::unique_ptr<opentelemetry::sdk::metrics::AttributesProcessor> attributes_processor =
+ std::unique_ptr<opentelemetry::sdk::metrics::AttributesProcessor>(
+ new opentelemetry::sdk::metrics::DefaultAttributesProcessor()))
+ : name_(name),
+ description_(description),
+ aggregation_type_{aggregation_type},
+ attributes_processor_{std::move(attributes_processor)}
+ {}
+
+ virtual std::string GetName() const noexcept { return name_; }
+
+ virtual std::string GetDescription() const noexcept { return description_; }
+
+ virtual AggregationType GetAggregationType() const noexcept { return aggregation_type_; }
+
+ virtual const opentelemetry::sdk::metrics::AttributesProcessor &GetAttributesProcessor()
+ const noexcept
+ {
+ return *attributes_processor_.get();
+ }
+
+private:
+ std::string name_;
+ std::string description_;
+ AggregationType aggregation_type_;
+ std::unique_ptr<opentelemetry::sdk::metrics::AttributesProcessor> attributes_processor_;
+};
+} // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h
new file mode 100644
index 000000000..795049dd9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h
@@ -0,0 +1,102 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <unordered_map>
+# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+# include "opentelemetry/sdk/metrics/view/instrument_selector.h"
+# include "opentelemetry/sdk/metrics/view/meter_selector.h"
+# include "opentelemetry/sdk/metrics/view/view.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace metrics
+{
+struct RegisteredView
+{
+ RegisteredView(
+ std::unique_ptr<opentelemetry::sdk::metrics::InstrumentSelector> instrument_selector,
+ std::unique_ptr<opentelemetry::sdk::metrics::MeterSelector> meter_selector,
+ std::unique_ptr<opentelemetry::sdk::metrics::View> view)
+ : instrument_selector_{std::move(instrument_selector)},
+ meter_selector_{std::move(meter_selector)},
+ view_{std::move(view)}
+ {}
+ std::unique_ptr<opentelemetry::sdk::metrics::InstrumentSelector> instrument_selector_;
+ std::unique_ptr<opentelemetry::sdk::metrics::MeterSelector> meter_selector_;
+ std::unique_ptr<opentelemetry::sdk::metrics::View> view_;
+};
+
+class ViewRegistry
+{
+public:
+ void AddView(std::unique_ptr<opentelemetry::sdk::metrics::InstrumentSelector> instrument_selector,
+ std::unique_ptr<opentelemetry::sdk::metrics::MeterSelector> meter_selector,
+ std::unique_ptr<opentelemetry::sdk::metrics::View> view)
+ {
+ // TBD - thread-safe ?
+
+ auto registered_view = std::unique_ptr<RegisteredView>(new RegisteredView{
+ std::move(instrument_selector), std::move(meter_selector), std::move(view)});
+ registered_views_.push_back(std::move(registered_view));
+ }
+
+ bool FindViews(const opentelemetry::sdk::metrics::InstrumentDescriptor &instrument_descriptor,
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ &instrumentation_library,
+ nostd::function_ref<bool(const View &)> callback) const
+ {
+ bool found = false;
+ for (auto const &registered_view : registered_views_)
+ {
+ if (MatchMeter(registered_view->meter_selector_.get(), instrumentation_library) &&
+ MatchInstrument(registered_view->instrument_selector_.get(), instrument_descriptor))
+ {
+ found = true;
+ if (!callback(*(registered_view->view_.get())))
+ {
+ return false;
+ }
+ }
+ }
+ // return default view if none found;
+ if (!found)
+ {
+ static View view("otel-default-view");
+ if (!callback(view))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ ~ViewRegistry() = default;
+
+private:
+ std::vector<std::unique_ptr<RegisteredView>> registered_views_;
+ static bool MatchMeter(opentelemetry::sdk::metrics::MeterSelector *selector,
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ &instrumentation_library)
+ {
+ return selector->GetNameFilter()->Match(instrumentation_library.GetName()) &&
+ (instrumentation_library.GetVersion().size() == 0 ||
+ selector->GetVersionFilter()->Match(instrumentation_library.GetVersion())) &&
+ (instrumentation_library.GetSchemaURL().size() == 0 ||
+ selector->GetSchemaFilter()->Match(instrumentation_library.GetSchemaURL()));
+ }
+
+ static bool MatchInstrument(
+ opentelemetry::sdk::metrics::InstrumentSelector *selector,
+ const opentelemetry::sdk::metrics::InstrumentDescriptor &instrument_descriptor)
+ {
+ return selector->GetNameFilter()->Match(instrument_descriptor.name_) &&
+ (selector->GetInstrumentType() == instrument_descriptor.type_);
+ }
+};
+}; // namespace metrics
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/experimental_semantic_conventions.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/experimental_semantic_conventions.h
new file mode 100644
index 000000000..d9dc3630f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/experimental_semantic_conventions.h
@@ -0,0 +1,141 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// NOTE:
+// This implementation is based on the experimental specs for resource semantic convention as
+// defined here:
+// https://github.com/open-telemetry/opentelemetry-specification/tree/v1.0.0/specification/resource/semantic_conventions
+// and MAY will change in future.
+
+#pragma once
+
+#include <type_traits>
+#include <unordered_map>
+
+#include "opentelemetry/common/string_util.h"
+#include "opentelemetry/version.h"
+
+#define OTEL_GET_RESOURCE_ATTR(name) \
+ opentelemetry::sdk::resource::attr(OTEL_CPP_CONST_HASHCODE(name))
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace resource
+{
+
+static const std::unordered_map<uint32_t, const char *> attribute_ids = {
+ {OTEL_CPP_CONST_HASHCODE(AttrServiceName), "service.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrServiceNamespace), "service.namespace"},
+ {OTEL_CPP_CONST_HASHCODE(AttrServiceInstance), "service.instance.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrServiceVersion), "service.version"},
+
+ // telemetry attributes
+ {OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkName), "telemetry.sdk.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkLanguage), "telemetry.sdk.language"},
+ {OTEL_CPP_CONST_HASHCODE(AttrTelemetrySdkVersion), "telemetry.sdk.version"},
+ {OTEL_CPP_CONST_HASHCODE(AttrTelemetryAutoVersion), "telemetry.auto.version"},
+
+ // compute unit: container attributes
+ {OTEL_CPP_CONST_HASHCODE(AttrContainerName), "container.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrContainerId), "container.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrContainerRuntime), "container.runtime"},
+ {OTEL_CPP_CONST_HASHCODE(AttrContainerImageName), "container.image.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrContainerImageTag), "container.image.tag"},
+
+ // compute unit: faas attributes
+ {OTEL_CPP_CONST_HASHCODE(AttrFaasName), "faas.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrFaasId), "faas.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrFaasVersion), "faas.version"},
+ {OTEL_CPP_CONST_HASHCODE(AttrFaasInstance), "faas.instance"},
+ {OTEL_CPP_CONST_HASHCODE(AttrFaasMaxMemory), "faas.max_memory"},
+
+ // compute unit : process attributes
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessId), "process.pid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessExecutableName), "process.executable.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessExecutablePath), "process.executable.path"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessCommand), "process.command"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessCommandLine), "process.command_line"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessCommandArgs), "process.command_args"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessOwner), "process.owner"},
+
+ // compute : process runtimes
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessRuntimeName), "process.runtime.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessRuntimeVersion), "process.runtime.version"},
+ {OTEL_CPP_CONST_HASHCODE(AttrProcessRuntimeDescription), "process.runtime.description"},
+
+ // compute unit : WebEngine
+ {OTEL_CPP_CONST_HASHCODE(AttrWebEngineName), "webengine.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrWebEngineVersion), "webengine.version"},
+ {OTEL_CPP_CONST_HASHCODE(AttrWebEngineDescription), "webengine.description"},
+
+ // compute instance : host
+ {OTEL_CPP_CONST_HASHCODE(AttrHostId), "host.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrHostName), "host.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrHostType), "host.type"},
+ {OTEL_CPP_CONST_HASHCODE(AttrHostArch), "host.arch"},
+ {OTEL_CPP_CONST_HASHCODE(AttrHostImageName), "host.image.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrHostImageId), "host.image.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrHostImageVersion), "host.image.version"},
+
+ // env os attributes
+ {OTEL_CPP_CONST_HASHCODE(AttrOsType), "os.type"},
+ {OTEL_CPP_CONST_HASHCODE(AttrOsDescription), "os.description"},
+ {OTEL_CPP_CONST_HASHCODE(AttrOsName), "os.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrOsVersion), "os.version"},
+
+ // env device attributes
+ {OTEL_CPP_CONST_HASHCODE(AttrDeviceId), "device.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrDeviceModelIdentifier), "device.model.identifier"},
+ {OTEL_CPP_CONST_HASHCODE(AttrDeviceModelName), "device.model.name"},
+
+ // env cloud
+ {OTEL_CPP_CONST_HASHCODE(AttrCloudProvider), "cloud.provider"},
+ {OTEL_CPP_CONST_HASHCODE(AttrCloudAccountId), "cloud.account.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrCloudRegion), "cloud.region"},
+ {OTEL_CPP_CONST_HASHCODE(AttrCloudAvailabilityZone), "cloud.availability_zone"},
+ {OTEL_CPP_CONST_HASHCODE(AttrCloudPlatform), "cloud.platform"},
+
+ // env deployment
+ {OTEL_CPP_CONST_HASHCODE(AttrDeploymentEnvironment), "deployment.environment"},
+
+ // env kubernetes
+ // - cluster
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sClusterName), "k8s.cluster.name"},
+ // - node
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sNodeName), "k8s.node.name"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sNodeUid), "k8s.node.uid"},
+ // - namespace
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sNamespaceName), "k8s.namespace.name"},
+ // - pod
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sPodUid), "k8s.pod.uid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sPodName), "k8s.pod.name"},
+ // - container
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sContainerName), "k8s.container.name"},
+ // - replicaset
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sReplicaSetUid), "k8s.replicaset.uid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sReplicaSetName), "k8s.replicaset.name"},
+ // - deployment
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sDeploymentUid), "k8s.deployment.uid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sDeploymentName), "k8s.deployment.name"},
+ // - stateful-set
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sStatefulSetUid), "k8s.statefulset.uid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sStatefulSetName), "k8s.statefulset.name"},
+ // - daemon set
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sDaemonSetUid), "k8s.daemonset.uid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sDaemonSetName), "k8s.daemonset.name"},
+ // - job
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sJobUid), "k8s.job.uid"},
+ {OTEL_CPP_CONST_HASHCODE(AttrK8sJobName), "k8s.job.name"},
+ // - cronjob
+ {OTEL_CPP_CONST_HASHCODE(AttrCronjobUid), "k8s.cronjob.id"},
+ {OTEL_CPP_CONST_HASHCODE(AttrCronjobName), "k8s.cronjob.name"}};
+
+// function to generate hash code for semantic conventions attributes.
+inline const char *attr(uint32_t attr)
+{
+ return (attribute_ids.find(attr) != attribute_ids.end()) ? attribute_ids.at(attr) : "";
+}
+} // namespace resource
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource.h
new file mode 100644
index 000000000..120e871ab
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource.h
@@ -0,0 +1,86 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/common/attribute_value.h"
+#include "opentelemetry/common/key_value_iterable_view.h"
+
+#include "opentelemetry/sdk/common/attribute_utils.h"
+#include "opentelemetry/sdk/resource/resource_detector.h"
+#include "opentelemetry/sdk/version/version.h"
+#include "opentelemetry/version.h"
+
+#include <memory>
+#include <sstream>
+#include <unordered_map>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace resource
+{
+
+using ResourceAttributes = opentelemetry::sdk::common::AttributeMap;
+
+class Resource
+{
+public:
+ Resource(const Resource &) = default;
+
+ const ResourceAttributes &GetAttributes() const noexcept;
+ const std::string &GetSchemaURL() const noexcept;
+
+ /**
+ * Returns a new, merged {@link Resource} by merging the current Resource
+ * with the other Resource. In case of a collision, current Resource takes
+ * precedence.
+ *
+ * @param other the Resource that will be merged with this.
+ * @returns the newly merged Resource.
+ */
+
+ Resource Merge(const Resource &other) noexcept;
+
+ /**
+ * Returns a newly created Resource with the specified attributes.
+ * It adds (merge) SDK attributes and OTEL attributes before returning.
+ * @param attributes for this resource
+ * @returns the newly created Resource.
+ */
+
+ static Resource Create(const ResourceAttributes &attributes,
+ const std::string &schema_url = std::string{});
+
+ /**
+ * Returns an Empty resource.
+ */
+
+ static Resource &GetEmpty();
+
+ /**
+ * Returns a Resource that indentifies the SDK in use.
+ */
+
+ static Resource &GetDefault();
+
+protected:
+ /**
+ * The constructor is protected and only for use internally by the class and
+ * inside ResourceDetector class.
+ * Users should use the Create factory method to obtain a Resource
+ * instance.
+ */
+ Resource(const ResourceAttributes &attributes = ResourceAttributes(),
+ const std::string &schema_url = std::string{}) noexcept;
+
+private:
+ ResourceAttributes attributes_;
+ std::string schema_url_;
+
+ friend class OTELResourceDetector;
+};
+
+} // namespace resource
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource_detector.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource_detector.h
new file mode 100644
index 000000000..5f9d904af
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/resource/resource_detector.h
@@ -0,0 +1,38 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/nostd/unique_ptr.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace resource
+{
+
+class Resource;
+
+/**
+ * Interface for a Resource Detector
+ */
+class ResourceDetector
+{
+public:
+ virtual Resource Detect() = 0;
+};
+
+/**
+ * OTelResourceDetector to detect the presence of and create a Resource
+ * from the OTEL_RESOURCE_ATTRIBUTES environment variable.
+ */
+class OTELResourceDetector : public ResourceDetector
+{
+public:
+ Resource Detect() noexcept override;
+};
+
+} // namespace resource
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h
new file mode 100644
index 000000000..d25ff2d95
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h
@@ -0,0 +1,158 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/common/circular_buffer.h"
+#include "opentelemetry/sdk/trace/exporter.h"
+#include "opentelemetry/sdk/trace/processor.h"
+
+#include <atomic>
+#include <condition_variable>
+#include <thread>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+
+namespace trace
+{
+
+/**
+ * Struct to hold batch SpanProcessor options.
+ */
+struct BatchSpanProcessorOptions
+{
+ /**
+ * The maximum buffer/queue size. After the size is reached, spans are
+ * dropped.
+ */
+ size_t max_queue_size = 2048;
+
+ /* The time interval between two consecutive exports. */
+ std::chrono::milliseconds schedule_delay_millis = std::chrono::milliseconds(5000);
+
+ /**
+ * The maximum batch size of every export. It must be smaller or
+ * equal to max_queue_size.
+ */
+ size_t max_export_batch_size = 512;
+};
+
+/**
+ * This is an implementation of the SpanProcessor which creates batches of finished spans and passes
+ * the export-friendly span data representations to the configured SpanExporter.
+ */
+class BatchSpanProcessor : public SpanProcessor
+{
+public:
+ /**
+ * Creates a batch span processor by configuring the specified exporter and other parameters
+ * as per the official, language-agnostic opentelemetry specs.
+ *
+ * @param exporter - The backend exporter to pass the ended spans to.
+ * @param options - The batch SpanProcessor options.
+ */
+ BatchSpanProcessor(std::unique_ptr<SpanExporter> &&exporter,
+ const BatchSpanProcessorOptions &options);
+
+ /**
+ * Requests a Recordable(Span) from the configured exporter.
+ *
+ * @return A recordable generated by the backend exporter
+ */
+ std::unique_ptr<Recordable> MakeRecordable() noexcept override;
+
+ /**
+ * Called when a span is started.
+ *
+ * NOTE: This method is a no-op.
+ *
+ * @param span - The span that just started
+ * @param parent_context - The parent context of the span that just started
+ */
+ void OnStart(Recordable &span,
+ const opentelemetry::trace::SpanContext &parent_context) noexcept override;
+
+ /**
+ * Called when a span ends.
+ *
+ * @param span - A recordable for a span that just ended
+ */
+ void OnEnd(std::unique_ptr<Recordable> &&span) noexcept override;
+
+ /**
+ * Export all ended spans that have not been exported yet.
+ *
+ * NOTE: Timeout functionality not supported yet.
+ */
+ bool ForceFlush(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+ /**
+ * Shuts down the processor and does any cleanup required. Completely drains the buffer/queue of
+ * all its ended spans and passes them to the exporter. Any subsequent calls to OnStart, OnEnd,
+ * ForceFlush or Shutdown will return immediately without doing anything.
+ *
+ * NOTE: Timeout functionality not supported yet.
+ */
+ bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override;
+
+ /**
+ * Class destructor which invokes the Shutdown() method. The Shutdown() method is supposed to be
+ * invoked when the Tracer is shutdown (as per other languages), but the C++ Tracer only takes
+ * shared ownership of the processor, and thus doesn't call Shutdown (as the processor might be
+ * shared with other Tracers).
+ */
+ ~BatchSpanProcessor();
+
+private:
+ /**
+ * The background routine performed by the worker thread.
+ */
+ void DoBackgroundWork();
+
+ /**
+ * Exports all ended spans to the configured exporter.
+ *
+ * @param was_force_flush_called - A flag to check if the current export is the result
+ * of a call to ForceFlush method. If true, then we have to
+ * notify the main thread to wake it up in the ForceFlush
+ * method.
+ */
+ void Export(const bool was_for_flush_called);
+
+ /**
+ * Called when Shutdown() is invoked. Completely drains the queue of all its ended spans and
+ * passes them to the exporter.
+ */
+ void DrainQueue();
+
+ /* The configured backend exporter */
+ std::unique_ptr<SpanExporter> exporter_;
+
+ /* Configurable parameters as per the official specs */
+ const size_t max_queue_size_;
+ const std::chrono::milliseconds schedule_delay_millis_;
+ const size_t max_export_batch_size_;
+
+ /* Synchronization primitives */
+ std::condition_variable cv_, force_flush_cv_;
+ std::mutex cv_m_, force_flush_cv_m_, shutdown_m_;
+
+ /* The buffer/queue to which the ended spans are added */
+ common::CircularBuffer<Recordable> buffer_;
+
+ /* Important boolean flags to handle the workflow of the processor */
+ std::atomic<bool> is_shutdown_{false};
+ std::atomic<bool> is_force_flush_{false};
+ std::atomic<bool> is_force_flush_notified_{false};
+
+ /* The background worker thread */
+ std::thread worker_thread_;
+};
+
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/exporter.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/exporter.h
new file mode 100644
index 000000000..5826b5f45
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/exporter.h
@@ -0,0 +1,55 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <memory>
+#include "opentelemetry/nostd/span.h"
+#include "opentelemetry/sdk/common/exporter_utils.h"
+#include "opentelemetry/sdk/trace/recordable.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * SpanExporter defines the interface that protocol-specific span exporters must
+ * implement.
+ */
+class SpanExporter
+{
+public:
+ virtual ~SpanExporter() = default;
+
+ /**
+ * Create a span recordable. This object will be used to record span data and
+ * will subsequently be passed to SpanExporter::Export. Vendors can implement
+ * custom recordables or use the default SpanData recordable provided by the
+ * SDK.
+ * @return a newly initialized Recordable object
+ *
+ * Note: This method must be callable from multiple threads.
+ */
+ virtual std::unique_ptr<Recordable> MakeRecordable() noexcept = 0;
+
+ /**
+ * Exports a batch of span recordables. This method must not be called
+ * concurrently for the same exporter instance.
+ * @param spans a span of unique pointers to span recordables
+ */
+ virtual sdk::common::ExportResult Export(
+ const nostd::span<std::unique_ptr<opentelemetry::sdk::trace::Recordable>>
+ &spans) noexcept = 0;
+
+ /**
+ * Shut down the exporter.
+ * @param timeout an optional timeout.
+ * @return return the status of the operation.
+ */
+ virtual bool Shutdown(
+ std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/id_generator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/id_generator.h
new file mode 100644
index 000000000..da17effae
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/id_generator.h
@@ -0,0 +1,31 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include "opentelemetry/trace/span_id.h"
+#include "opentelemetry/trace/trace_id.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+
+/** IdGenerator provides an interface for generating Trace Id and Span Id */
+class IdGenerator
+{
+
+public:
+ virtual ~IdGenerator() = default;
+
+ /** Returns a SpanId represented by opaque 128-bit trace identifier */
+ virtual opentelemetry::trace::SpanId GenerateSpanId() noexcept = 0;
+
+ /** Returns a TraceId represented by opaque 64-bit trace identifier */
+ virtual opentelemetry::trace::TraceId GenerateTraceId() noexcept = 0;
+};
+} // namespace trace
+
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_recordable.h
new file mode 100644
index 000000000..be97dddc9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_recordable.h
@@ -0,0 +1,161 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/common/timestamp.h"
+#include "opentelemetry/sdk/trace/processor.h"
+#include "opentelemetry/sdk/trace/recordable.h"
+#include "opentelemetry/version.h"
+
+#include <map>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+namespace
+{
+std::size_t MakeKey(const SpanProcessor &processor)
+{
+ return reinterpret_cast<std::size_t>(&processor);
+}
+
+} // namespace
+
+class MultiRecordable : public Recordable
+{
+public:
+ void AddRecordable(const SpanProcessor &processor,
+ std::unique_ptr<Recordable> recordable) noexcept
+ {
+ recordables_[MakeKey(processor)] = std::move(recordable);
+ }
+
+ const std::unique_ptr<Recordable> &GetRecordable(const SpanProcessor &processor) const noexcept
+ {
+ // TODO - return nullptr ref on failed lookup?
+ auto i = recordables_.find(MakeKey(processor));
+ if (i != recordables_.end())
+ {
+ return i->second;
+ }
+ static std::unique_ptr<Recordable> empty(nullptr);
+ return empty;
+ }
+
+ std::unique_ptr<Recordable> ReleaseRecordable(const SpanProcessor &processor) noexcept
+ {
+ auto i = recordables_.find(MakeKey(processor));
+ if (i != recordables_.end())
+ {
+ std::unique_ptr<Recordable> result(i->second.release());
+ recordables_.erase(MakeKey(processor));
+ return result;
+ }
+ return std::unique_ptr<Recordable>(nullptr);
+ }
+
+ void SetIdentity(const opentelemetry::trace::SpanContext &span_context,
+ opentelemetry::trace::SpanId parent_span_id) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetIdentity(span_context, parent_span_id);
+ }
+ }
+
+ void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetAttribute(key, value);
+ }
+ }
+
+ void AddEvent(nostd::string_view name,
+ opentelemetry::common::SystemTimestamp timestamp,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept override
+ {
+
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->AddEvent(name, timestamp, attributes);
+ }
+ }
+
+ void AddLink(const opentelemetry::trace::SpanContext &span_context,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->AddLink(span_context, attributes);
+ }
+ }
+
+ void SetStatus(opentelemetry::trace::StatusCode code,
+ nostd::string_view description) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetStatus(code, description);
+ }
+ }
+
+ void SetName(nostd::string_view name) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetName(name);
+ }
+ }
+
+ void SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetSpanKind(span_kind);
+ }
+ }
+
+ void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetResource(resource);
+ }
+ }
+
+ void SetStartTime(opentelemetry::common::SystemTimestamp start_time) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetStartTime(start_time);
+ }
+ }
+
+ void SetDuration(std::chrono::nanoseconds duration) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetDuration(duration);
+ }
+ }
+
+ void SetInstrumentationLibrary(
+ const InstrumentationLibrary &instrumentation_library) noexcept override
+ {
+ for (auto &recordable : recordables_)
+ {
+ recordable.second->SetInstrumentationLibrary(instrumentation_library);
+ }
+ }
+
+private:
+ std::map<std::size_t, std::unique_ptr<Recordable>> recordables_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h
new file mode 100644
index 000000000..8463ad520
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h
@@ -0,0 +1,187 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <mutex>
+#include <vector>
+
+#include "opentelemetry/sdk/trace/multi_recordable.h"
+#include "opentelemetry/sdk/trace/processor.h"
+
+#include <iostream>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+
+/** Instantiation options. */
+struct MultiSpanProcessorOptions
+{};
+
+/**
+ * Span processor allow hooks for span start and end method invocations.
+ *
+ * Built-in span processors are responsible for batching and conversion of
+ * spans to exportable representation and passing batches to exporters.
+ */
+class MultiSpanProcessor : public SpanProcessor
+{
+public:
+ MultiSpanProcessor(std::vector<std::unique_ptr<SpanProcessor>> &&processors)
+ : head_(nullptr), tail_(nullptr), count_(0)
+ {
+ for (auto &processor : processors)
+ {
+ AddProcessor(std::move(processor));
+ }
+ }
+
+ void AddProcessor(std::unique_ptr<SpanProcessor> &&processor)
+ {
+ // Add preocessor to end of the list.
+ if (processor)
+ {
+ ProcessorNode *pNode = new ProcessorNode(std::move(processor), tail_);
+ if (count_ > 0)
+ {
+ tail_->next_ = pNode;
+ tail_ = pNode;
+ }
+ else
+ {
+ head_ = tail_ = pNode;
+ }
+ count_++;
+ }
+ }
+
+ std::unique_ptr<Recordable> MakeRecordable() noexcept override
+ {
+ auto recordable = std::unique_ptr<Recordable>(new MultiRecordable);
+ auto multi_recordable = static_cast<MultiRecordable *>(recordable.get());
+ ProcessorNode *node = head_;
+ while (node != nullptr)
+ {
+ auto processor = node->value_.get();
+ multi_recordable->AddRecordable(*processor, processor->MakeRecordable());
+ node = node->next_;
+ }
+ return recordable;
+ }
+
+ virtual void OnStart(Recordable &span,
+ const opentelemetry::trace::SpanContext &parent_context) noexcept override
+ {
+ auto multi_recordable = static_cast<MultiRecordable *>(&span);
+ ProcessorNode *node = head_;
+ while (node != nullptr)
+ {
+ auto processor = node->value_.get();
+ auto &recordable = multi_recordable->GetRecordable(*processor);
+ if (recordable != nullptr)
+ {
+ processor->OnStart(*recordable, parent_context);
+ }
+ node = node->next_;
+ }
+ }
+
+ virtual void OnEnd(std::unique_ptr<Recordable> &&span) noexcept override
+ {
+ auto multi_recordable = static_cast<MultiRecordable *>(span.release());
+ ProcessorNode *node = head_;
+ while (node != nullptr)
+ {
+ auto processor = node->value_.get();
+ auto recordable = multi_recordable->ReleaseRecordable(*processor);
+ if (recordable != nullptr)
+ {
+ processor->OnEnd(std::move(recordable));
+ }
+ node = node->next_;
+ }
+ delete multi_recordable;
+ }
+
+ bool ForceFlush(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override
+ {
+ bool result = true;
+ ProcessorNode *node = head_;
+ while (node != nullptr)
+ {
+ auto processor = node->value_.get();
+ result |= processor->ForceFlush(timeout);
+ node = node->next_;
+ }
+ return result;
+ }
+
+ bool Shutdown(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override
+ {
+ bool result = true;
+ ProcessorNode *node = head_;
+ while (node != nullptr)
+ {
+ auto processor = node->value_.get();
+ result |= processor->Shutdown(timeout);
+ node = node->next_;
+ }
+ return result;
+ }
+
+ ~MultiSpanProcessor()
+ {
+ Shutdown();
+ Cleanup();
+ }
+
+private:
+ struct ProcessorNode
+ {
+ std::unique_ptr<SpanProcessor> value_;
+ ProcessorNode *next_, *prev_;
+ ProcessorNode(std::unique_ptr<SpanProcessor> &&value,
+ ProcessorNode *prev = nullptr,
+ ProcessorNode *next = nullptr)
+ : value_(std::move(value)), next_(next), prev_(prev)
+ {}
+ };
+
+ void Cleanup()
+ {
+ if (count_)
+ {
+ ProcessorNode *node = tail_;
+ while (node != nullptr)
+ {
+ if (node->next_ != nullptr)
+ {
+ delete node->next_;
+ node->next_ = nullptr;
+ }
+ if (node->prev_ != nullptr)
+ {
+ node = node->prev_;
+ }
+ else
+ {
+ delete node;
+ node = nullptr;
+ }
+ }
+ head_ = tail_ = nullptr;
+ count_ = 0;
+ }
+ }
+
+ ProcessorNode *head_, *tail_;
+ size_t count_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/processor.h
new file mode 100644
index 000000000..17ac0e59a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/processor.h
@@ -0,0 +1,70 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <chrono>
+#include <memory>
+#include "opentelemetry/sdk/trace/recordable.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * Span processor allow hooks for span start and end method invocations.
+ *
+ * Built-in span processors are responsible for batching and conversion of
+ * spans to exportable representation and passing batches to exporters.
+ */
+class SpanProcessor
+{
+public:
+ virtual ~SpanProcessor() = default;
+
+ /**
+ * Create a span recordable. This requests a new span recordable from the
+ * associated exporter.
+ * @return a newly initialized recordable
+ *
+ * Note: This method must be callable from multiple threads.
+ */
+ virtual std::unique_ptr<Recordable> MakeRecordable() noexcept = 0;
+
+ /**
+ * OnStart is called when a span is started.
+ * @param span a recordable for a span that was just started
+ * @param parent_context The parent context of the span that just started
+ */
+ virtual void OnStart(Recordable &span,
+ const opentelemetry::trace::SpanContext &parent_context) noexcept = 0;
+
+ /**
+ * OnEnd is called when a span is ended.
+ * @param span a recordable for a span that was ended
+ */
+ virtual void OnEnd(std::unique_ptr<Recordable> &&span) noexcept = 0;
+
+ /**
+ * Export all ended spans that have not yet been exported.
+ * @param timeout an optional timeout, the default timeout of 0 means that no
+ * timeout is applied.
+ */
+ virtual bool ForceFlush(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0;
+
+ /**
+ * Shut down the processor and do any cleanup required. Ended spans are
+ * exported before shutdown. After the call to Shutdown, subsequent calls to
+ * OnStart, OnEnd, ForceFlush or Shutdown will return immediately without
+ * doing anything.
+ * @param timeout an optional timeout, the default timeout of 0 means that no
+ * timeout is applied.
+ */
+ virtual bool Shutdown(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/random_id_generator.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/random_id_generator.h
new file mode 100644
index 000000000..908f1b850
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/random_id_generator.h
@@ -0,0 +1,24 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include "opentelemetry/sdk/trace/id_generator.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+
+class RandomIdGenerator : public IdGenerator
+{
+public:
+ opentelemetry::trace::SpanId GenerateSpanId() noexcept override;
+
+ opentelemetry::trace::TraceId GenerateTraceId() noexcept override;
+};
+
+} // namespace trace
+
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/recordable.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/recordable.h
new file mode 100644
index 000000000..b92a3ff06
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/recordable.h
@@ -0,0 +1,152 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/common/attribute_value.h"
+#include "opentelemetry/common/key_value_iterable.h"
+#include "opentelemetry/common/timestamp.h"
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/sdk/common/empty_attributes.h"
+#include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+#include "opentelemetry/sdk/resource/resource.h"
+#include "opentelemetry/trace/canonical_code.h"
+#include "opentelemetry/trace/span.h"
+#include "opentelemetry/trace/span_context.h"
+#include "opentelemetry/trace/span_id.h"
+#include "opentelemetry/trace/trace_id.h"
+#include "opentelemetry/version.h"
+
+#include <map>
+
+// TODO: Create generic short pattern for opentelemetry::common and opentelemetry::trace
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+
+using namespace opentelemetry::sdk::instrumentationlibrary;
+
+/**
+ * Maintains a representation of a span in a format that can be processed by a recorder.
+ *
+ * This class is thread-compatible.
+ */
+class Recordable
+{
+public:
+ virtual ~Recordable() = default;
+
+ /**
+ * Set the span context and parent span id
+ * @param span_context the span context to set
+ * @param parent_span_id the parent span id to set
+ */
+ virtual void SetIdentity(const opentelemetry::trace::SpanContext &span_context,
+ opentelemetry::trace::SpanId parent_span_id) noexcept = 0;
+
+ /**
+ * Set an attribute of a span.
+ * @param name the name of the attribute
+ * @param value the attribute value
+ */
+ virtual void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept = 0;
+
+ /**
+ * Add an event to a span.
+ * @param name the name of the event
+ * @param timestamp the timestamp of the event
+ * @param attributes the attributes associated with the event
+ */
+ virtual void AddEvent(nostd::string_view name,
+ opentelemetry::common::SystemTimestamp timestamp,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0;
+
+ /**
+ * Add an event to a span with default timestamp and attributes.
+ * @param name the name of the event
+ */
+ void AddEvent(nostd::string_view name)
+ {
+ AddEvent(name, opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()),
+ opentelemetry::sdk::GetEmptyAttributes());
+ }
+
+ /**
+ * Add an event to a span with default (empty) attributes.
+ * @param name the name of the event
+ * @param timestamp the timestamp of the event
+ */
+ void AddEvent(nostd::string_view name, opentelemetry::common::SystemTimestamp timestamp)
+ {
+ AddEvent(name, timestamp, opentelemetry::sdk::GetEmptyAttributes());
+ }
+
+ /**
+ * Add a link to a span.
+ * @param span_context the span context of the linked span
+ * @param attributes the attributes associated with the link
+ */
+ virtual void AddLink(const opentelemetry::trace::SpanContext &span_context,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0;
+
+ /**
+ * Add a link to a span with default (empty) attributes.
+ * @param span_context the span context of the linked span
+ */
+ void AddLink(opentelemetry::trace::SpanContext span_context)
+ {
+ AddLink(span_context, opentelemetry::sdk::GetEmptyAttributes());
+ }
+
+ /**
+ * Set the status of the span.
+ * @param code the status code
+ * @param description a description of the status
+ */
+ virtual void SetStatus(opentelemetry::trace::StatusCode code,
+ nostd::string_view description) noexcept = 0;
+
+ /**
+ * Set the name of the span.
+ * @param name the name to set
+ */
+ virtual void SetName(nostd::string_view name) noexcept = 0;
+
+ /**
+ * Set the spankind of the span.
+ * @param span_kind the spankind to set
+ */
+ virtual void SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept = 0;
+
+ /**
+ * Set Resource of the span
+ * @param Resource the resource to set
+ */
+ virtual void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept = 0;
+
+ /**
+ * Set the start time of the span.
+ * @param start_time the start time to set
+ */
+ virtual void SetStartTime(opentelemetry::common::SystemTimestamp start_time) noexcept = 0;
+
+ /**
+ * Set the duration of the span.
+ * @param duration the duration to set
+ */
+ virtual void SetDuration(std::chrono::nanoseconds duration) noexcept = 0;
+
+ /**
+ * Set the instrumentation library of the span.
+ * @param instrumentation_library the instrumentation library to set
+ */
+ virtual void SetInstrumentationLibrary(
+ const InstrumentationLibrary &instrumentation_library) noexcept = 0;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/sampler.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/sampler.h
new file mode 100644
index 000000000..452ba924b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/sampler.h
@@ -0,0 +1,91 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/common/attribute_value.h"
+#include "opentelemetry/trace/span.h"
+#include "opentelemetry/trace/span_context.h"
+#include "opentelemetry/trace/span_context_kv_iterable.h"
+#include "opentelemetry/trace/trace_id.h"
+#include "opentelemetry/trace/trace_state.h"
+#include "opentelemetry/version.h"
+
+#include <map>
+#include <memory>
+#include <string>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * A sampling Decision for a Span to be created.
+ */
+enum class Decision
+{
+ // IsRecording() == false, span will not be recorded and all events and attributes will be
+ // dropped.
+ DROP,
+ // IsRecording() == true, but Sampled flag MUST NOT be set.
+ RECORD_ONLY,
+ // IsRecording() == true AND Sampled flag` MUST be set.
+ RECORD_AND_SAMPLE
+};
+
+/**
+ * The output of ShouldSample.
+ * It contains a sampling Decision and a set of Span Attributes.
+ */
+struct SamplingResult
+{
+ Decision decision;
+ // A set of span Attributes that will also be added to the Span. Can be nullptr.
+ std::unique_ptr<const std::map<std::string, opentelemetry::common::AttributeValue>> attributes;
+ // The tracestate used by the span.
+ nostd::shared_ptr<opentelemetry::trace::TraceState> trace_state;
+};
+
+/**
+ * The Sampler interface allows users to create custom samplers which will return a
+ * SamplingResult based on information that is typically available just before the Span was created.
+ */
+class Sampler
+{
+public:
+ virtual ~Sampler() = default;
+ /**
+ * Called during Span creation to make a sampling decision.
+ *
+ * @param parent_context a const reference to the SpanContext of a parent Span.
+ * An invalid SpanContext if this is a root span.
+ * @param trace_id the TraceId for the new Span. This will be identical to that in
+ * the parentContext, unless this is a root span.
+ * @param name the name of the new Span.
+ * @param spanKind the opentelemetry::trace::SpanKind of the Span.
+ * @param attributes list of AttributeValue with their keys.
+ * @param links Collection of links that will be associated with the Span to be created.
+ * @return sampling result whether span should be sampled or not.
+ * @since 0.1.0
+ */
+
+ virtual SamplingResult ShouldSample(
+ const opentelemetry::trace::SpanContext &parent_context,
+ opentelemetry::trace::TraceId trace_id,
+ nostd::string_view name,
+ opentelemetry::trace::SpanKind span_kind,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::trace::SpanContextKeyValueIterable &links) noexcept = 0;
+
+ /**
+ * Returns the sampler name or short description with the configuration.
+ * This may be displayed on debug pages or in the logs.
+ *
+ * @return the description of this Sampler.
+ */
+ virtual nostd::string_view GetDescription() const noexcept = 0;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_off.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_off.h
new file mode 100644
index 000000000..2392b9b2f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_off.h
@@ -0,0 +1,48 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/trace/sampler.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * The always off sampler always returns DROP, effectively disabling
+ * tracing functionality.
+ */
+class AlwaysOffSampler : public Sampler
+{
+public:
+ /**
+ * @return Returns DROP always
+ */
+ SamplingResult ShouldSample(
+ const opentelemetry::trace::SpanContext &parent_context,
+ opentelemetry::trace::TraceId /*trace_id*/,
+ nostd::string_view /*name*/,
+ opentelemetry::trace::SpanKind /*span_kind*/,
+ const opentelemetry::common::KeyValueIterable & /*attributes*/,
+ const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/) noexcept override
+ {
+ if (!parent_context.IsValid())
+ {
+ return {Decision::DROP, nullptr, opentelemetry::trace::TraceState::GetDefault()};
+ }
+ else
+ {
+ return {Decision::DROP, nullptr, parent_context.trace_state()};
+ }
+ }
+
+ /**
+ * @return Description MUST be AlwaysOffSampler
+ */
+ nostd::string_view GetDescription() const noexcept override { return "AlwaysOffSampler"; }
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_on.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_on.h
new file mode 100644
index 000000000..6c8583599
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/always_on.h
@@ -0,0 +1,47 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/trace/sampler.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * The always on sampler is a default sampler which always return Decision::RECORD_AND_SAMPLE
+ */
+class AlwaysOnSampler : public Sampler
+{
+public:
+ /**
+ * @return Always return Decision RECORD_AND_SAMPLE
+ */
+ inline SamplingResult ShouldSample(
+ const opentelemetry::trace::SpanContext &parent_context,
+ opentelemetry::trace::TraceId /*trace_id*/,
+ nostd::string_view /*name*/,
+ opentelemetry::trace::SpanKind /*span_kind*/,
+ const opentelemetry::common::KeyValueIterable & /*attributes*/,
+ const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/) noexcept override
+ {
+ if (!parent_context.IsValid())
+ {
+ return {Decision::RECORD_AND_SAMPLE, nullptr, opentelemetry::trace::TraceState::GetDefault()};
+ }
+ else
+ {
+ return {Decision::RECORD_AND_SAMPLE, nullptr, parent_context.trace_state()};
+ }
+ }
+
+ /**
+ * @return Description MUST be AlwaysOnSampler
+ */
+ inline nostd::string_view GetDescription() const noexcept override { return "AlwaysOnSampler"; }
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/parent.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/parent.h
new file mode 100644
index 000000000..c76a6c2a5
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/parent.h
@@ -0,0 +1,45 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/common/atomic_shared_ptr.h"
+#include "opentelemetry/sdk/trace/sampler.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * The ParentBased sampler is a composite sampler. ParentBased(delegateSampler) either respects
+ * the parent span's sampling decision or delegates to delegateSampler for root spans.
+ */
+class ParentBasedSampler : public Sampler
+{
+public:
+ explicit ParentBasedSampler(std::shared_ptr<Sampler> delegate_sampler) noexcept;
+ /** The decision either respects the parent span's sampling decision or delegates to
+ * delegateSampler for root spans
+ * @return Returns DROP always
+ */
+ SamplingResult ShouldSample(
+ const opentelemetry::trace::SpanContext &parent_context,
+ opentelemetry::trace::TraceId trace_id,
+ nostd::string_view name,
+ opentelemetry::trace::SpanKind span_kind,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const opentelemetry::trace::SpanContextKeyValueIterable &links) noexcept override;
+
+ /**
+ * @return Description MUST be ParentBased{delegate_sampler_.getDescription()}
+ */
+ nostd::string_view GetDescription() const noexcept override;
+
+private:
+ const std::shared_ptr<Sampler> delegate_sampler_;
+ const std::string description_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/trace_id_ratio.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/trace_id_ratio.h
new file mode 100644
index 000000000..407b480d6
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/samplers/trace_id_ratio.h
@@ -0,0 +1,53 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/trace/sampler.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * The TraceIdRatioBased sampler computes and returns a decision based on the
+ * provided trace_id and the configured ratio.
+ */
+class TraceIdRatioBasedSampler : public Sampler
+{
+public:
+ /**
+ * @param ratio a required value, 1.0 >= ratio >= 0.0. If the given trace_id
+ * falls into a given ratio of all possible trace_id values, ShouldSample will
+ * return RECORD_AND_SAMPLE.
+ * @throws invalid_argument if ratio is out of bounds [0.0, 1.0]
+ */
+ explicit TraceIdRatioBasedSampler(double ratio);
+
+ /**
+ * @return Returns either RECORD_AND_SAMPLE or DROP based on current
+ * sampler configuration and provided trace_id and ratio. trace_id
+ * is used as a pseudorandom value in conjunction with the predefined
+ * ratio to determine whether this trace should be sampled
+ */
+ SamplingResult ShouldSample(
+ const opentelemetry::trace::SpanContext & /*parent_context*/,
+ opentelemetry::trace::TraceId trace_id,
+ nostd::string_view /*name*/,
+ opentelemetry::trace::SpanKind /*span_kind*/,
+ const opentelemetry::common::KeyValueIterable & /*attributes*/,
+ const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/) noexcept override;
+
+ /**
+ * @return Description MUST be TraceIdRatioBasedSampler{0.000100}
+ */
+ nostd::string_view GetDescription() const noexcept override;
+
+private:
+ std::string description_;
+ const uint64_t threshold_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/simple_processor.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/simple_processor.h
new file mode 100644
index 000000000..accc68596
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/simple_processor.h
@@ -0,0 +1,84 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <atomic>
+#include <mutex>
+
+#include "opentelemetry/common/spin_lock_mutex.h"
+#include "opentelemetry/sdk/trace/exporter.h"
+#include "opentelemetry/sdk/trace/processor.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * The simple span processor passes finished recordables to the configured
+ * SpanExporter, as soon as they are finished.
+ *
+ * OnEnd and ForceFlush are no-ops.
+ *
+ * All calls to the configured SpanExporter are synchronized using a
+ * spin-lock on an atomic_flag.
+ */
+class SimpleSpanProcessor : public SpanProcessor
+{
+public:
+ /**
+ * Initialize a simple span processor.
+ * @param exporter the exporter used by the span processor
+ */
+ explicit SimpleSpanProcessor(std::unique_ptr<SpanExporter> &&exporter) noexcept
+ : exporter_(std::move(exporter))
+ {}
+
+ std::unique_ptr<Recordable> MakeRecordable() noexcept override
+ {
+ return exporter_->MakeRecordable();
+ }
+
+ void OnStart(Recordable &span,
+ const opentelemetry::trace::SpanContext &parent_context) noexcept override
+ {}
+
+ void OnEnd(std::unique_ptr<Recordable> &&span) noexcept override
+ {
+ nostd::span<std::unique_ptr<Recordable>> batch(&span, 1);
+ const std::lock_guard<opentelemetry::common::SpinLockMutex> locked(lock_);
+ if (exporter_->Export(batch) == sdk::common::ExportResult::kFailure)
+ {
+ /* Once it is defined how the SDK does logging, an error should be
+ * logged in this case. */
+ }
+ }
+
+ bool ForceFlush(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override
+ {
+ return true;
+ }
+
+ bool Shutdown(
+ std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override
+ {
+ // We only call shutdown ONCE.
+ if (exporter_ != nullptr && !shutdown_latch_.test_and_set(std::memory_order_acquire))
+ {
+ return exporter_->Shutdown(timeout);
+ }
+ return true;
+ }
+
+ ~SimpleSpanProcessor() { Shutdown(); }
+
+private:
+ std::unique_ptr<SpanExporter> exporter_;
+ opentelemetry::common::SpinLockMutex lock_;
+ std::atomic_flag shutdown_latch_ = ATOMIC_FLAG_INIT;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/span_data.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/span_data.h
new file mode 100644
index 000000000..0fb09f328
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/span_data.h
@@ -0,0 +1,304 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <chrono>
+#include <unordered_map>
+#include <vector>
+#include "opentelemetry/common/attribute_value.h"
+#include "opentelemetry/common/timestamp.h"
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/sdk/common/attribute_utils.h"
+#include "opentelemetry/sdk/trace/recordable.h"
+#include "opentelemetry/trace/canonical_code.h"
+#include "opentelemetry/trace/span.h"
+#include "opentelemetry/trace/span_id.h"
+#include "opentelemetry/trace/trace_id.h"
+
+#include <string>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+/**
+ * Class for storing events in SpanData.
+ */
+class SpanDataEvent
+{
+public:
+ SpanDataEvent(std::string name,
+ opentelemetry::common::SystemTimestamp timestamp,
+ const opentelemetry::common::KeyValueIterable &attributes)
+ : name_(name), timestamp_(timestamp), attribute_map_(attributes)
+ {}
+
+ /**
+ * Get the name for this event
+ * @return the name for this event
+ */
+ std::string GetName() const noexcept { return name_; }
+
+ /**
+ * Get the timestamp for this event
+ * @return the timestamp for this event
+ */
+ opentelemetry::common::SystemTimestamp GetTimestamp() const noexcept { return timestamp_; }
+
+ /**
+ * Get the attributes for this event
+ * @return the attributes for this event
+ */
+ const std::unordered_map<std::string, common::OwnedAttributeValue> &GetAttributes() const noexcept
+ {
+ return attribute_map_.GetAttributes();
+ }
+
+private:
+ std::string name_;
+ opentelemetry::common::SystemTimestamp timestamp_;
+ common::AttributeMap attribute_map_;
+};
+
+/**
+ * Class for storing links in SpanData.
+ */
+class SpanDataLink
+{
+public:
+ SpanDataLink(opentelemetry::trace::SpanContext span_context,
+ const opentelemetry::common::KeyValueIterable &attributes)
+ : span_context_(span_context), attribute_map_(attributes)
+ {}
+
+ /**
+ * Get the attributes for this link
+ * @return the attributes for this link
+ */
+ const std::unordered_map<std::string, common::OwnedAttributeValue> &GetAttributes() const noexcept
+ {
+ return attribute_map_.GetAttributes();
+ }
+
+ /**
+ * Get the span context for this link
+ * @return the span context for this link
+ */
+ const opentelemetry::trace::SpanContext &GetSpanContext() const noexcept { return span_context_; }
+
+private:
+ opentelemetry::trace::SpanContext span_context_;
+ common::AttributeMap attribute_map_;
+};
+
+/**
+ * SpanData is a representation of all data collected by a span.
+ */
+class SpanData final : public Recordable
+{
+public:
+ SpanData() : resource_{nullptr}, instrumentation_library_{nullptr} {}
+ /**
+ * Get the trace id for this span
+ * @return the trace id for this span
+ */
+ opentelemetry::trace::TraceId GetTraceId() const noexcept { return span_context_.trace_id(); }
+
+ /**
+ * Get the span id for this span
+ * @return the span id for this span
+ */
+ opentelemetry::trace::SpanId GetSpanId() const noexcept { return span_context_.span_id(); }
+
+ /**
+ * Get the span context for this span
+ * @return the span context for this span
+ */
+ const opentelemetry::trace::SpanContext &GetSpanContext() const noexcept { return span_context_; }
+
+ /**
+ * Get the parent span id for this span
+ * @return the span id for this span's parent
+ */
+ opentelemetry::trace::SpanId GetParentSpanId() const noexcept { return parent_span_id_; }
+
+ /**
+ * Get the name for this span
+ * @return the name for this span
+ */
+ opentelemetry::nostd::string_view GetName() const noexcept { return name_; }
+
+ /**
+ * Get the kind of this span
+ * @return the kind of this span
+ */
+ opentelemetry::trace::SpanKind GetSpanKind() const noexcept { return span_kind_; }
+
+ /**
+ * Get the status for this span
+ * @return the status for this span
+ */
+ opentelemetry::trace::StatusCode GetStatus() const noexcept { return status_code_; }
+
+ /**
+ * Get the status description for this span
+ * @return the description of the the status of this span
+ */
+ opentelemetry::nostd::string_view GetDescription() const noexcept { return status_desc_; }
+
+ /**
+ * Get the attributes associated with the resource
+ * @returns the attributes associated with the resource configured for TracerProvider
+ */
+
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept
+ {
+ if (resource_ == nullptr)
+ {
+ // this shouldn't happen as TraceProvider provides default resources
+ static opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::GetEmpty();
+ return resource;
+ }
+ return *resource_;
+ }
+
+ /**
+ * Get the attributes associated with the resource
+ * @returns the attributes associated with the resource configured for TracerProvider
+ */
+
+ const opentelemetry::sdk::trace::InstrumentationLibrary &GetInstrumentationLibrary()
+ const noexcept
+ {
+ if (instrumentation_library_ == nullptr)
+ {
+ // this shouldn't happen as Tracer ensures there is valid default instrumentation library.
+ static std::unique_ptr<opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary>
+ instrumentation_library =
+ opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create(
+ "unknown_service");
+ return *instrumentation_library;
+ }
+ return *instrumentation_library_;
+ }
+
+ /**
+ * Get the start time for this span
+ * @return the start time for this span
+ */
+ opentelemetry::common::SystemTimestamp GetStartTime() const noexcept { return start_time_; }
+
+ /**
+ * Get the duration for this span
+ * @return the duration for this span
+ */
+ std::chrono::nanoseconds GetDuration() const noexcept { return duration_; }
+
+ /**
+ * Get the attributes for this span
+ * @return the attributes for this span
+ */
+ const std::unordered_map<std::string, common::OwnedAttributeValue> &GetAttributes() const noexcept
+ {
+ return attribute_map_.GetAttributes();
+ }
+
+ /**
+ * Get the events associated with this span
+ * @return the events associated with this span
+ */
+ const std::vector<SpanDataEvent> &GetEvents() const noexcept { return events_; }
+
+ /**
+ * Get the links associated with this span
+ * @return the links associated with this span
+ */
+ const std::vector<SpanDataLink> &GetLinks() const noexcept { return links_; }
+
+ void SetIdentity(const opentelemetry::trace::SpanContext &span_context,
+ opentelemetry::trace::SpanId parent_span_id) noexcept override
+ {
+ span_context_ = span_context;
+ parent_span_id_ = parent_span_id;
+ }
+
+ void SetAttribute(nostd::string_view key,
+ const opentelemetry::common::AttributeValue &value) noexcept override
+ {
+ attribute_map_.SetAttribute(key, value);
+ }
+
+ void AddEvent(nostd::string_view name,
+ opentelemetry::common::SystemTimestamp timestamp =
+ opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()),
+ const opentelemetry::common::KeyValueIterable &attributes =
+ opentelemetry::common::KeyValueIterableView<std::map<std::string, int>>(
+ {})) noexcept override
+ {
+ SpanDataEvent event(std::string(name), timestamp, attributes);
+ events_.push_back(event);
+ }
+
+ void AddLink(const opentelemetry::trace::SpanContext &span_context,
+ const opentelemetry::common::KeyValueIterable &attributes) noexcept override
+ {
+ SpanDataLink link(span_context, attributes);
+ links_.push_back(link);
+ }
+
+ void SetStatus(opentelemetry::trace::StatusCode code,
+ nostd::string_view description) noexcept override
+ {
+ status_code_ = code;
+ status_desc_ = std::string(description);
+ }
+
+ void SetName(nostd::string_view name) noexcept override
+ {
+ name_ = std::string(name.data(), name.length());
+ }
+
+ void SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept override
+ {
+ span_kind_ = span_kind;
+ }
+
+ void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept override
+ {
+ resource_ = &resource;
+ }
+
+ void SetStartTime(opentelemetry::common::SystemTimestamp start_time) noexcept override
+ {
+ start_time_ = start_time;
+ }
+
+ void SetDuration(std::chrono::nanoseconds duration) noexcept override { duration_ = duration; }
+
+ void SetInstrumentationLibrary(
+ const InstrumentationLibrary &instrumentation_library) noexcept override
+ {
+ instrumentation_library_ = &instrumentation_library;
+ }
+
+private:
+ opentelemetry::trace::SpanContext span_context_{false, false};
+ opentelemetry::trace::SpanId parent_span_id_;
+ opentelemetry::common::SystemTimestamp start_time_;
+ std::chrono::nanoseconds duration_{0};
+ std::string name_;
+ opentelemetry::trace::StatusCode status_code_{opentelemetry::trace::StatusCode::kUnset};
+ std::string status_desc_;
+ common::AttributeMap attribute_map_;
+ std::vector<SpanDataEvent> events_;
+ std::vector<SpanDataLink> links_;
+ opentelemetry::trace::SpanKind span_kind_{opentelemetry::trace::SpanKind::kInternal};
+ const opentelemetry::sdk::resource::Resource *resource_;
+ const InstrumentationLibrary *instrumentation_library_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer.h
new file mode 100644
index 000000000..fd9f2c8e8
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer.h
@@ -0,0 +1,70 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/common/atomic_shared_ptr.h"
+#include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h"
+#include "opentelemetry/sdk/resource/resource.h"
+#include "opentelemetry/sdk/trace/processor.h"
+#include "opentelemetry/sdk/trace/samplers/always_on.h"
+#include "opentelemetry/sdk/trace/tracer_context.h"
+#include "opentelemetry/trace/noop.h"
+#include "opentelemetry/trace/tracer.h"
+#include "opentelemetry/version.h"
+
+#include <memory>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+
+using namespace opentelemetry::sdk::instrumentationlibrary;
+
+class Tracer final : public trace_api::Tracer, public std::enable_shared_from_this<Tracer>
+{
+public:
+ /** Construct a new Tracer with the given context pipeline. */
+ explicit Tracer(std::shared_ptr<sdk::trace::TracerContext> context,
+ std::unique_ptr<InstrumentationLibrary> instrumentation_library =
+ InstrumentationLibrary::Create("")) noexcept;
+
+ nostd::shared_ptr<trace_api::Span> StartSpan(
+ nostd::string_view name,
+ const opentelemetry::common::KeyValueIterable &attributes,
+ const trace_api::SpanContextKeyValueIterable &links,
+ const trace_api::StartSpanOptions &options = {}) noexcept override;
+
+ void ForceFlushWithMicroseconds(uint64_t timeout) noexcept override;
+
+ void CloseWithMicroseconds(uint64_t timeout) noexcept override;
+
+ /** Returns the configured span processor. */
+ SpanProcessor &GetProcessor() noexcept { return context_->GetProcessor(); }
+
+ /** Returns the configured Id generator */
+ IdGenerator &GetIdGenerator() const noexcept { return context_->GetIdGenerator(); }
+
+ /** Returns the associated instruementation library */
+ const InstrumentationLibrary &GetInstrumentationLibrary() const noexcept
+ {
+ return *instrumentation_library_;
+ }
+
+ /** Returns the currently configured resource **/
+ const opentelemetry::sdk::resource::Resource &GetResource() { return context_->GetResource(); }
+
+ // Note: Test only
+ Sampler &GetSampler() { return context_->GetSampler(); }
+
+private:
+ // order of declaration is important here - instrumentation library should destroy after
+ // tracer-context.
+ std::shared_ptr<InstrumentationLibrary> instrumentation_library_;
+ std::shared_ptr<sdk::trace::TracerContext> context_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_context.h
new file mode 100644
index 000000000..572f60caf
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_context.h
@@ -0,0 +1,100 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/sdk/common/atomic_unique_ptr.h"
+#include "opentelemetry/sdk/resource/resource.h"
+#include "opentelemetry/sdk/trace/processor.h"
+#include "opentelemetry/sdk/trace/random_id_generator.h"
+#include "opentelemetry/sdk/trace/samplers/always_on.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+
+/**
+ * A class which stores the TracerProvider context.
+ *
+ * This class meets the following design criteria:
+ * - A shared reference between TracerProvider and Tracers instantiated.
+ * - A thread-safe class that allows updating/altering processor/exporter pipelines
+ * and sampling config.
+ * - The owner/destroyer of Processors/Exporters. These will remain active until
+ * this class is destroyed. I.e. Sampling, Exporting, flushing, Custom Iterator etc. are all ok
+ * if this object is alive, and they will work together. If this object is destroyed, then no shared
+ * references to Processor, Exporter, Recordable, Custom Iterator etc. should exist, and all
+ * associated pipelines will have been flushed.
+ */
+class TracerContext
+{
+public:
+ explicit TracerContext(
+ std::vector<std::unique_ptr<SpanProcessor>> &&processor,
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({}),
+ std::unique_ptr<Sampler> sampler = std::unique_ptr<AlwaysOnSampler>(new AlwaysOnSampler),
+ std::unique_ptr<IdGenerator> id_generator =
+ std::unique_ptr<IdGenerator>(new RandomIdGenerator())) noexcept;
+
+ /**
+ * Attaches a span processor to list of configured processors to this tracer context.
+ * Processor once attached can't be removed.
+ * @param processor The new span processor for this tracer. This must not be
+ * a nullptr. Ownership is given to the `TracerContext`.
+ *
+ * Note: This method is not thread safe.
+ */
+ void AddProcessor(std::unique_ptr<SpanProcessor> processor) noexcept;
+
+ /**
+ * Obtain the sampler associated with this tracer.
+ * @return The sampler for this tracer.
+ */
+ Sampler &GetSampler() const noexcept;
+
+ /**
+ * Obtain the configured (composite) processor.
+ *
+ * Note: When more than one processor is active, this will
+ * return an "aggregate" processor
+ */
+ SpanProcessor &GetProcessor() const noexcept;
+
+ /**
+ * Obtain the resource associated with this tracer context.
+ * @return The resource for this tracer context.
+ */
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept;
+
+ /**
+ * Obtain the Id Generator associated with this tracer context.
+ * @return The ID Generator for this tracer context.
+ */
+ opentelemetry::sdk::trace::IdGenerator &GetIdGenerator() const noexcept;
+
+ /**
+ * Force all active SpanProcessors to flush any buffered spans
+ * within the given timeout.
+ */
+ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;
+
+ /**
+ * Shutdown the span processor associated with this tracer provider.
+ */
+ bool Shutdown() noexcept;
+
+private:
+ // order of declaration is important here - resource object should be destroyed after processor.
+ opentelemetry::sdk::resource::Resource resource_;
+ std::unique_ptr<Sampler> sampler_;
+ std::unique_ptr<IdGenerator> id_generator_;
+ std::unique_ptr<SpanProcessor> processor_;
+};
+
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_provider.h
new file mode 100644
index 000000000..aa0f69a2b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/tracer_provider.h
@@ -0,0 +1,103 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+#include "opentelemetry/nostd/shared_ptr.h"
+#include "opentelemetry/sdk/resource/resource.h"
+#include "opentelemetry/sdk/trace/processor.h"
+#include "opentelemetry/sdk/trace/samplers/always_on.h"
+#include "opentelemetry/sdk/trace/tracer.h"
+#include "opentelemetry/sdk/trace/tracer_context.h"
+#include "opentelemetry/trace/tracer_provider.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace trace
+{
+class TracerProvider final : public opentelemetry::trace::TracerProvider
+{
+public:
+ /**
+ * Initialize a new tracer provider with a specified sampler
+ * @param processor The span processor for this tracer provider. This must
+ * not be a nullptr.
+ * @param resource The resources for this tracer provider.
+ * @param sampler The sampler for this tracer provider. This must
+ * not be a nullptr.
+ * @param id_generator The custom id generator for this tracer provider. This must
+ * not be a nullptr
+ */
+ explicit TracerProvider(
+ std::unique_ptr<SpanProcessor> processor,
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({}),
+ std::unique_ptr<Sampler> sampler = std::unique_ptr<AlwaysOnSampler>(new AlwaysOnSampler),
+ std::unique_ptr<opentelemetry::sdk::trace::IdGenerator> id_generator =
+ std::unique_ptr<opentelemetry::sdk::trace::IdGenerator>(
+ new RandomIdGenerator())) noexcept;
+
+ explicit TracerProvider(
+ std::vector<std::unique_ptr<SpanProcessor>> &&processors,
+ opentelemetry::sdk::resource::Resource resource =
+ opentelemetry::sdk::resource::Resource::Create({}),
+ std::unique_ptr<Sampler> sampler = std::unique_ptr<AlwaysOnSampler>(new AlwaysOnSampler),
+ std::unique_ptr<opentelemetry::sdk::trace::IdGenerator> id_generator =
+ std::unique_ptr<opentelemetry::sdk::trace::IdGenerator>(
+ new RandomIdGenerator())) noexcept;
+
+ /**
+ * Initialize a new tracer provider with a specified context
+ * @param context The shared tracer configuration/pipeline for this provider.
+ */
+ explicit TracerProvider(std::shared_ptr<sdk::trace::TracerContext> context) noexcept;
+
+ ~TracerProvider();
+
+ opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> GetTracer(
+ nostd::string_view library_name,
+ nostd::string_view library_version = "",
+ nostd::string_view schema_url = "") noexcept override;
+
+ /**
+ * Attaches a span processor to list of configured processors for this tracer provider.
+ * @param processor The new span processor for this tracer provider. This
+ * must not be a nullptr.
+ *
+ * Note: This process may not receive any in-flight spans, but will get newly created spans.
+ * Note: This method is not thread safe, and should ideally be called from main thread.
+ */
+ void AddProcessor(std::unique_ptr<SpanProcessor> processor) noexcept;
+
+ /**
+ * Obtain the resource associated with this tracer provider.
+ * @return The resource for this tracer provider.
+ */
+ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept;
+
+ /**
+ * Shutdown the span processor associated with this tracer provider.
+ */
+ bool Shutdown() noexcept;
+
+ /**
+ * Force flush the span processor associated with this tracer provider.
+ */
+ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;
+
+private:
+ // order of declaration is important here - tracers should destroy only after context.
+ std::vector<std::shared_ptr<opentelemetry::sdk::trace::Tracer>> tracers_;
+ std::shared_ptr<sdk::trace::TracerContext> context_;
+ std::mutex lock_;
+};
+} // namespace trace
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/version/version.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/version/version.h
new file mode 100644
index 000000000..65c3c826c
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/version/version.h
@@ -0,0 +1,30 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/detail/preprocessor.h"
+
+#define OPENTELEMETRY_SDK_VERSION "1.4.0"
+
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace sdk
+{
+namespace version
+{
+extern const int MAJOR_VERSION;
+extern const int MINOR_VERSION;
+extern const int PATCH_VERSION;
+extern const char *PRE_RELEASE;
+extern const char *BUILD_METADATA;
+extern const int COUNT_NEW_COMMITS;
+extern const char *BRANCH;
+extern const char *COMMIT_HASH;
+extern const char *FULL_VERSION;
+extern const char *FULL_VERSION_WITH_BRANCH_COMMITHASH;
+extern const char *BUILD_DATE;
+} // namespace version
+} // namespace sdk
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk_config.h b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk_config.h
new file mode 100644
index 000000000..8ac72a10d
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk_config.h
@@ -0,0 +1,7 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/config.h"
+#include "opentelemetry/sdk/common/global_log_handler.h" \ No newline at end of file