summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h')
-rw-r--r--src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h187
1 files changed, 187 insertions, 0 deletions
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