summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin')
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_library_handle.h20
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_unix.h72
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h97
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/loader_info.h24
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/tracer_handle.h23
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/utility.h34
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/dynamic_load.h27
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/factory.h65
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/hook.h48
-rw-r--r--src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/tracer.h103
10 files changed, 513 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_library_handle.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_library_handle.h
new file mode 100644
index 000000000..9ffe076ad
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_library_handle.h
@@ -0,0 +1,20 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+/**
+ * Manage the ownership of a dynamically loaded library.
+ */
+class DynamicLibraryHandle
+{
+public:
+ virtual ~DynamicLibraryHandle() = default;
+};
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_unix.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_unix.h
new file mode 100644
index 000000000..bcc4bd0b8
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_unix.h
@@ -0,0 +1,72 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <algorithm>
+#include <memory>
+
+#include <dlfcn.h>
+
+#include "opentelemetry/plugin/detail/utility.h"
+#include "opentelemetry/plugin/factory.h"
+#include "opentelemetry/plugin/hook.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+class DynamicLibraryHandleUnix final : public DynamicLibraryHandle
+{
+public:
+ explicit DynamicLibraryHandleUnix(void *handle) noexcept : handle_{handle} {}
+
+ ~DynamicLibraryHandleUnix() override { ::dlclose(handle_); }
+
+private:
+ void *handle_;
+};
+
+inline std::unique_ptr<Factory> LoadFactory(const char *plugin, std::string &error_message) noexcept
+{
+ dlerror(); // Clear any existing error.
+
+ auto handle = ::dlopen(plugin, RTLD_NOW | RTLD_LOCAL);
+ if (handle == nullptr)
+ {
+ detail::CopyErrorMessage(dlerror(), error_message);
+ return nullptr;
+ }
+
+ std::shared_ptr<DynamicLibraryHandle> library_handle{new (std::nothrow)
+ DynamicLibraryHandleUnix{handle}};
+ if (library_handle == nullptr)
+ {
+ return nullptr;
+ }
+
+ auto make_factory_impl =
+ reinterpret_cast<OpenTelemetryHook *>(::dlsym(handle, "OpenTelemetryMakeFactoryImpl"));
+ if (make_factory_impl == nullptr)
+ {
+ detail::CopyErrorMessage(dlerror(), error_message);
+ return nullptr;
+ }
+ if (*make_factory_impl == nullptr)
+ {
+ detail::CopyErrorMessage("Invalid plugin hook", error_message);
+ return nullptr;
+ }
+ LoaderInfo loader_info;
+ nostd::unique_ptr<char[]> plugin_error_message;
+ auto factory_impl = (**make_factory_impl)(loader_info, plugin_error_message);
+ if (factory_impl == nullptr)
+ {
+ detail::CopyErrorMessage(plugin_error_message.get(), error_message);
+ return nullptr;
+ }
+ return std::unique_ptr<Factory>{new (std::nothrow)
+ Factory{std::move(library_handle), std::move(factory_impl)}};
+}
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h
new file mode 100644
index 000000000..7a586b6bc
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h
@@ -0,0 +1,97 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <memory>
+
+#include "opentelemetry/plugin/detail/utility.h"
+#include "opentelemetry/plugin/factory.h"
+#include "opentelemetry/plugin/hook.h"
+#include "opentelemetry/version.h"
+
+#ifndef NOMINMAX
+# define NOMINMAX
+#endif
+#include <Windows.h>
+
+#include <WinBase.h>
+#include <errhandlingapi.h>
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+namespace detail
+{
+inline void GetLastErrorMessage(std::string &error_message) noexcept
+{
+ auto error_code = ::GetLastError();
+ // See https://stackoverflow.com/a/455533/4447365
+ LPTSTR error_text = nullptr;
+ auto size = ::FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ reinterpret_cast<LPTSTR>(&error_text), 0, nullptr);
+ if (size == 0)
+ {
+ return;
+ }
+ CopyErrorMessage(error_text, error_message);
+ ::LocalFree(error_text);
+}
+} // namespace detail
+
+class DynamicLibraryHandleWindows final : public DynamicLibraryHandle
+{
+public:
+ explicit DynamicLibraryHandleWindows(HINSTANCE handle) : handle_{handle} {}
+
+ ~DynamicLibraryHandleWindows() override { ::FreeLibrary(handle_); }
+
+private:
+ HINSTANCE handle_;
+};
+
+inline std::unique_ptr<Factory> LoadFactory(const char *plugin, std::string &error_message) noexcept
+{
+ auto handle = ::LoadLibrary(plugin);
+ if (handle == nullptr)
+ {
+ detail::GetLastErrorMessage(error_message);
+ return nullptr;
+ }
+
+ std::shared_ptr<DynamicLibraryHandle> library_handle{new (std::nothrow)
+ DynamicLibraryHandleWindows{handle}};
+ if (library_handle == nullptr)
+ {
+ detail::CopyErrorMessage("Allocation failure", error_message);
+ return nullptr;
+ }
+
+ auto make_factory_impl = reinterpret_cast<OpenTelemetryHook *>(
+ ::GetProcAddress(handle, "OpenTelemetryMakeFactoryImpl"));
+ if (make_factory_impl == nullptr)
+ {
+ detail::GetLastErrorMessage(error_message);
+ return nullptr;
+ }
+ if (*make_factory_impl == nullptr)
+ {
+ detail::CopyErrorMessage("Invalid plugin hook", error_message);
+ return nullptr;
+ }
+
+ LoaderInfo loader_info;
+ nostd::unique_ptr<char[]> plugin_error_message;
+ auto factory_impl = (**make_factory_impl)(loader_info, plugin_error_message);
+ if (factory_impl == nullptr)
+ {
+ detail::CopyErrorMessage(plugin_error_message.get(), error_message);
+ return nullptr;
+ }
+ return std::unique_ptr<Factory>{new (std::nothrow)
+ Factory{std::move(library_handle), std::move(factory_impl)}};
+}
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/loader_info.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/loader_info.h
new file mode 100644
index 000000000..ca8c9f0a1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/loader_info.h
@@ -0,0 +1,24 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+/**
+ * LoaderInfo describes the versioning of the loader.
+ *
+ * Plugins can check against this information and properly error out if they were built against an
+ * incompatible OpenTelemetry API.
+ */
+struct LoaderInfo
+{
+ nostd::string_view opentelemetry_version = OPENTELEMETRY_VERSION;
+ nostd::string_view opentelemetry_abi_version = OPENTELEMETRY_ABI_VERSION;
+};
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/tracer_handle.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/tracer_handle.h
new file mode 100644
index 000000000..559d7ddf4
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/tracer_handle.h
@@ -0,0 +1,23 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/trace/tracer.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+/**
+ * Manage the ownership of a dynamically loaded tracer.
+ */
+class TracerHandle
+{
+public:
+ virtual ~TracerHandle() = default;
+
+ virtual trace::Tracer &tracer() const noexcept = 0;
+};
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/utility.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/utility.h
new file mode 100644
index 000000000..6f8dd5d46
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/detail/utility.h
@@ -0,0 +1,34 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "opentelemetry/nostd/string_view.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+namespace detail
+{
+inline void CopyErrorMessage(const char *source, std::string &destination) noexcept
+#if __EXCEPTIONS
+try
+#endif
+{
+ if (source == nullptr)
+ {
+ return;
+ }
+ destination.assign(source);
+}
+#if __EXCEPTIONS
+catch (const std::bad_alloc &)
+{}
+#endif
+} // namespace detail
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/dynamic_load.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/dynamic_load.h
new file mode 100644
index 000000000..8318d534a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/dynamic_load.h
@@ -0,0 +1,27 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <string>
+
+#ifdef _WIN32
+# include "opentelemetry/plugin/detail/dynamic_load_windows.h"
+#else
+# include "opentelemetry/plugin/detail/dynamic_load_unix.h"
+#endif
+
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+/**
+ * Load an OpenTelemetry implementation as a plugin.
+ * @param plugin the path to the plugin to load
+ * @param error_message on failure this is set to an error message
+ * @return a Factory that can be used to create OpenTelemetry objects or nullptr on failure.
+ */
+std::unique_ptr<Factory> LoadFactory(const char *plugin, std::string &error_message) noexcept;
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/factory.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/factory.h
new file mode 100644
index 000000000..0a285d65b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/factory.h
@@ -0,0 +1,65 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include <memory>
+#include <string>
+
+#include "opentelemetry/plugin/detail/utility.h"
+#include "opentelemetry/plugin/tracer.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+/**
+ * Factory creates OpenTelemetry objects from configuration strings.
+ */
+class Factory final
+{
+public:
+ class FactoryImpl
+ {
+ public:
+ virtual ~FactoryImpl() {}
+
+ virtual nostd::unique_ptr<TracerHandle> MakeTracerHandle(
+ nostd::string_view tracer_config,
+ nostd::unique_ptr<char[]> &error_message) const noexcept = 0;
+ };
+
+ Factory(std::shared_ptr<DynamicLibraryHandle> library_handle,
+ std::unique_ptr<FactoryImpl> &&factory_impl) noexcept
+ : library_handle_{std::move(library_handle)}, factory_impl_{std::move(factory_impl)}
+ {}
+
+ /**
+ * Construct a tracer from a configuration string.
+ * @param tracer_config a representation of the tracer's config as a string.
+ * @param error_message on failure this will contain an error message.
+ * @return a Tracer on success or nullptr on failure.
+ */
+ std::shared_ptr<opentelemetry::trace::Tracer> MakeTracer(
+ nostd::string_view tracer_config,
+ std::string &error_message) const noexcept
+ {
+ nostd::unique_ptr<char[]> plugin_error_message;
+ auto tracer_handle = factory_impl_->MakeTracerHandle(tracer_config, plugin_error_message);
+ if (tracer_handle == nullptr)
+ {
+ detail::CopyErrorMessage(plugin_error_message.get(), error_message);
+ return nullptr;
+ }
+ return std::shared_ptr<opentelemetry::trace::Tracer>{
+ new (std::nothrow) Tracer{library_handle_, std::move(tracer_handle)}};
+ }
+
+private:
+ // Note: The order is important here.
+ //
+ // It's undefined behavior to close the library while a loaded FactoryImpl is still active.
+ std::shared_ptr<DynamicLibraryHandle> library_handle_;
+ std::unique_ptr<FactoryImpl> factory_impl_;
+};
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/hook.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/hook.h
new file mode 100644
index 000000000..c06c0b324
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/hook.h
@@ -0,0 +1,48 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include "opentelemetry/plugin/detail/loader_info.h"
+#include "opentelemetry/plugin/factory.h"
+#include "opentelemetry/version.h"
+
+#ifdef _WIN32
+
+/**
+ * Cross-platform helper macro to declare the symbol used to load an OpenTelemetry implementation
+ * as a plugin.
+ *
+ * Note: The symbols use weak linkage so as to support using an OpenTelemetry both as a regular
+ * library and a dynamically loaded plugin. The weak linkage allows for multiple implementations to
+ * be linked in without getting multiple definition errors.
+ */
+# define OPENTELEMETRY_DEFINE_PLUGIN_HOOK(X) \
+ extern "C" { \
+ extern __declspec(dllexport) \
+ opentelemetry::plugin::OpenTelemetryHook const OpenTelemetryMakeFactoryImpl; \
+ \
+ __declspec(selectany) \
+ opentelemetry::plugin::OpenTelemetryHook const OpenTelemetryMakeFactoryImpl = X; \
+ } // extern "C"
+
+#else
+
+# define OPENTELEMETRY_DEFINE_PLUGIN_HOOK(X) \
+ extern "C" { \
+ __attribute(( \
+ weak)) extern opentelemetry::plugin::OpenTelemetryHook const OpenTelemetryMakeFactoryImpl; \
+ \
+ opentelemetry::plugin::OpenTelemetryHook const OpenTelemetryMakeFactoryImpl = X; \
+ } // extern "C"
+
+#endif
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+using OpenTelemetryHook =
+ nostd::unique_ptr<Factory::FactoryImpl> (*)(const LoaderInfo &loader_info,
+ nostd::unique_ptr<char[]> &error_message);
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE
diff --git a/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/tracer.h b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/tracer.h
new file mode 100644
index 000000000..149f2a93b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/api/include/opentelemetry/plugin/tracer.h
@@ -0,0 +1,103 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <memory>
+
+#include "opentelemetry/common/key_value_iterable.h"
+#include "opentelemetry/plugin/detail/dynamic_library_handle.h"
+#include "opentelemetry/plugin/detail/tracer_handle.h"
+#include "opentelemetry/trace/tracer.h"
+#include "opentelemetry/version.h"
+
+OPENTELEMETRY_BEGIN_NAMESPACE
+namespace plugin
+{
+class Span final : public trace::Span
+{
+public:
+ Span(std::shared_ptr<trace::Tracer> &&tracer, nostd::shared_ptr<trace::Span> span) noexcept
+ : tracer_{std::move(tracer)}, span_{span}
+ {}
+
+ // trace::Span
+ void SetAttribute(nostd::string_view name, const common::AttributeValue &value) noexcept override
+ {
+ span_->SetAttribute(name, value);
+ }
+
+ void AddEvent(nostd::string_view name) noexcept override { span_->AddEvent(name); }
+
+ void AddEvent(nostd::string_view name, common::SystemTimestamp timestamp) noexcept override
+ {
+ span_->AddEvent(name, timestamp);
+ }
+
+ void AddEvent(nostd::string_view name,
+ common::SystemTimestamp timestamp,
+ const common::KeyValueIterable &attributes) noexcept override
+ {
+ span_->AddEvent(name, timestamp, attributes);
+ }
+
+ void SetStatus(trace::StatusCode code, nostd::string_view description) noexcept override
+ {
+ span_->SetStatus(code, description);
+ }
+
+ void UpdateName(nostd::string_view name) noexcept override { span_->UpdateName(name); }
+
+ void End(const trace::EndSpanOptions &options = {}) noexcept override { span_->End(options); }
+
+ bool IsRecording() const noexcept override { return span_->IsRecording(); }
+
+ trace::SpanContext GetContext() const noexcept override { return span_->GetContext(); }
+
+private:
+ std::shared_ptr<trace::Tracer> tracer_;
+ nostd::shared_ptr<trace::Span> span_;
+};
+
+class Tracer final : public trace::Tracer, public std::enable_shared_from_this<Tracer>
+{
+public:
+ Tracer(std::shared_ptr<DynamicLibraryHandle> library_handle,
+ std::unique_ptr<TracerHandle> &&tracer_handle) noexcept
+ : library_handle_{std::move(library_handle)}, tracer_handle_{std::move(tracer_handle)}
+ {}
+
+ // trace::Tracer
+ nostd::shared_ptr<trace::Span> StartSpan(
+ nostd::string_view name,
+ const common::KeyValueIterable &attributes,
+ const trace::SpanContextKeyValueIterable &links,
+ const trace::StartSpanOptions &options = {}) noexcept override
+ {
+ auto span = tracer_handle_->tracer().StartSpan(name, attributes, links, options);
+ if (span == nullptr)
+ {
+ return nostd::shared_ptr<trace::Span>(nullptr);
+ }
+ return nostd::shared_ptr<trace::Span>{new (std::nothrow) Span{this->shared_from_this(), span}};
+ }
+
+ void ForceFlushWithMicroseconds(uint64_t timeout) noexcept override
+ {
+ tracer_handle_->tracer().ForceFlushWithMicroseconds(timeout);
+ }
+
+ void CloseWithMicroseconds(uint64_t timeout) noexcept override
+ {
+ tracer_handle_->tracer().CloseWithMicroseconds(timeout);
+ }
+
+private:
+ // Note: The order is important here.
+ //
+ // It's undefined behavior to close the library while a loaded tracer is still active.
+ std::shared_ptr<DynamicLibraryHandle> library_handle_;
+ std::unique_ptr<TracerHandle> tracer_handle_;
+};
+} // namespace plugin
+OPENTELEMETRY_END_NAMESPACE