summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/opentelemetry-cpp/examples
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/jaegertracing/opentelemetry-cpp/examples
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/examples')
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/CMakeLists.txt27
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/batch/BUILD13
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/batch/CMakeLists.txt6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/batch/main.cc90
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/CMakeLists.txt5
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/BUILD16
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/CMakeLists.txt3
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.cc37
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.h6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/BUILD16
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/CMakeLists.txt3
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.cc39
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.h6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/BUILD17
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/CMakeLists.txt2
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.cc87
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.h15
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/etw_threads/CMakeLists.txt6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/etw_threads/README.md32
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/etw_threads/main.cc154
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/BUILD63
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/CMakeLists.txt45
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/README.md107
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/client.cc117
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/protos/messages.proto15
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/server.cc125
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/grpc/tracer_common.h98
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/BUILD42
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/CMakeLists.txt20
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/README.md112
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/client.cc95
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/server.cc94
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/server.h53
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/http/tracer_common.h87
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/jaeger/BUILD13
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/jaeger/CMakeLists.txt6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/jaeger/README.md18
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/jaeger/main.cc46
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD28
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt13
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md86
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc118
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc119
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multi_processor/BUILD17
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multi_processor/CMakeLists.txt7
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multi_processor/README.md15
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multi_processor/main.cc89
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multithreaded/BUILD12
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multithreaded/CMakeLists.txt5
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/multithreaded/main.cc68
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/BUILD73
-rwxr-xr-xsrc/jaegertracing/opentelemetry-cpp/examples/otlp/CMakeLists.txt40
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/README.md69
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_log_main.cc77
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_main.cc54
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/http_log_main.cc92
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/http_main.cc62
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/otlp/opentelemetry-collector-config/config.dev.yaml24
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/CMakeLists.txt2
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/load/BUILD12
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/load/CMakeLists.txt2
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/load/main.cc42
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/BUILD12
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/CMakeLists.txt2
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/factory_impl.cc49
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.cc75
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.h26
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/prometheus/BUILD14
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/prometheus/CMakeLists.txt5
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/prometheus/README.md208
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/prometheus/main.cc118
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/prometheus/prometheus.yml16
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/prometheus/run.sh1
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/simple/BUILD15
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/simple/CMakeLists.txt6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/simple/README.md12
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/simple/main.cc41
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/zipkin/CMakeLists.txt6
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/zipkin/README.md32
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/zipkin/main.cc49
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/zpages/BUILD32
-rw-r--r--src/jaegertracing/opentelemetry-cpp/examples/zpages/zpages_example.cc60
82 files changed, 3641 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/CMakeLists.txt
new file mode 100644
index 000000000..2367918c7
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/CMakeLists.txt
@@ -0,0 +1,27 @@
+add_subdirectory(common)
+include_directories(common)
+if(WITH_OTLP_GRPC OR WITH_OTLP_HTTP)
+ add_subdirectory(otlp)
+endif()
+if(WITH_OTLP_GRPC)
+ add_subdirectory(grpc)
+endif()
+if(WITH_ETW)
+ add_subdirectory(etw_threads)
+endif()
+if(WITH_JAEGER)
+ add_subdirectory(jaeger)
+endif()
+if(WITH_ZIPKIN)
+ add_subdirectory(zipkin)
+endif()
+if(WITH_PROMETHEUS AND NOT WITH_METRICS_PREVIEW)
+ add_subdirectory(prometheus)
+endif()
+add_subdirectory(plugin)
+add_subdirectory(simple)
+add_subdirectory(batch)
+add_subdirectory(metrics_simple)
+add_subdirectory(multithreaded)
+add_subdirectory(multi_processor)
+add_subdirectory(http)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/batch/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/batch/BUILD
new file mode 100644
index 000000000..2dedf6b29
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/batch/BUILD
@@ -0,0 +1,13 @@
+cc_binary(
+ name = "example_simple",
+ srcs = [
+ "main.cc",
+ ],
+ linkopts = ["-lpthread"],
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//exporters/ostream:ostream_span_exporter",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/batch/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/batch/CMakeLists.txt
new file mode 100644
index 000000000..d1146d59b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/batch/CMakeLists.txt
@@ -0,0 +1,6 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include)
+
+add_executable(batch_span_processor_example main.cc)
+
+target_link_libraries(batch_span_processor_example ${CMAKE_THREAD_LIBS_INIT}
+ opentelemetry_exporter_ostream_span opentelemetry_trace)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/batch/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/batch/main.cc
new file mode 100644
index 000000000..9a4606ef5
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/batch/main.cc
@@ -0,0 +1,90 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+// Using an exporter that simply dumps span data to stdout.
+#include "opentelemetry/exporters/ostream/span_exporter.h"
+#include "opentelemetry/sdk/trace/batch_span_processor.h"
+
+#include <chrono>
+#include <thread>
+
+constexpr int kNumSpans = 10;
+namespace trace_api = opentelemetry::trace;
+namespace resource = opentelemetry::sdk::resource;
+namespace exporter_trace = opentelemetry::exporter::trace;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace nostd = opentelemetry::nostd;
+
+namespace
+{
+
+void initTracer()
+{
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new exporter_trace::OStreamSpanExporter);
+
+ // CONFIGURE BATCH SPAN PROCESSOR PARAMETERS
+
+ trace_sdk::BatchSpanProcessorOptions options{};
+ // We make the queue size `KNumSpans`*2+5 because when the queue is half full, a preemptive notif
+ // is sent to start an export call, which we want to avoid in this simple example.
+ options.max_queue_size = kNumSpans * 2 + 5;
+ // Time interval (in ms) between two consecutive exports.
+ options.schedule_delay_millis = std::chrono::milliseconds(3000);
+ // We export `kNumSpans` after every `schedule_delay_millis` milliseconds.
+ options.max_export_batch_size = kNumSpans;
+
+ resource::ResourceAttributes attributes = {{"service", "test_service"}, {"version", (uint32_t)1}};
+ auto resource = resource::Resource::Create(attributes);
+
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::BatchSpanProcessor(std::move(exporter), options));
+
+ auto provider = nostd::shared_ptr<trace_api::TracerProvider>(
+ new trace_sdk::TracerProvider(std::move(processor), resource));
+ // Set the global trace provider.
+ trace_api::Provider::SetTracerProvider(provider);
+}
+
+nostd::shared_ptr<trace_api::Tracer> get_tracer()
+{
+ auto provider = trace_api::Provider::GetTracerProvider();
+ return provider->GetTracer("foo_library");
+}
+
+void StartAndEndSpans()
+{
+ for (int i = 1; i <= kNumSpans; ++i)
+ {
+ get_tracer()->StartSpan("Span " + std::to_string(i));
+ }
+}
+
+} // namespace
+
+int main()
+{
+ // Removing this line will leave the default noop TracerProvider in place.
+ initTracer();
+
+ std::cout << "Creating first batch of " << kNumSpans << " spans and waiting 3 seconds ...\n";
+ StartAndEndSpans();
+ std::this_thread::sleep_for(std::chrono::milliseconds(3000 + 50));
+ // The spans should now be exported.
+ std::cout << "....Exported!\n\n\n";
+
+ // Do the same again
+ std::cout << "Creating second batch of " << kNumSpans << " spans and waiting 3 seconds ...\n";
+ StartAndEndSpans();
+ std::this_thread::sleep_for(std::chrono::milliseconds(3000 + 50));
+ std::cout << "....Exported!\n\n\n";
+
+ // Shutdown and drain queue
+ StartAndEndSpans();
+ printf("Shutting down and draining queue.... \n");
+ std::this_thread::sleep_for(std::chrono::milliseconds(2000));
+ // We immediately let the program terminate which invokes the processor destructor
+ // which in turn invokes the processor Shutdown(), which finally drains the queue of ALL
+ // its spans.
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/common/CMakeLists.txt
new file mode 100644
index 000000000..c2fdca259
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_subdirectory(foo_library)
+if(WITH_LOGS_PREVIEW)
+ add_subdirectory(logs_foo_library)
+endif()
+add_subdirectory(metrics_foo_library)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/BUILD
new file mode 100644
index 000000000..beffe5ca1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/BUILD
@@ -0,0 +1,16 @@
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+ name = "common_foo_library",
+ srcs = [
+ "foo_library.cc",
+ ],
+ hdrs = [
+ "foo_library.h",
+ ],
+ defines = ["BAZEL_BUILD"],
+ deps = [
+ "//api",
+ "//sdk:headers",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/CMakeLists.txt
new file mode 100644
index 000000000..a13512ffe
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_library(common_foo_library foo_library.h foo_library.cc)
+target_link_libraries(common_foo_library PUBLIC ${CMAKE_THREAD_LIBS_INIT}
+ opentelemetry_api)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.cc b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.cc
new file mode 100644
index 000000000..a0dec3c76
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.cc
@@ -0,0 +1,37 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/sdk/version/version.h"
+#include "opentelemetry/trace/provider.h"
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+
+namespace
+{
+nostd::shared_ptr<trace::Tracer> get_tracer()
+{
+ auto provider = trace::Provider::GetTracerProvider();
+ return provider->GetTracer("foo_library", OPENTELEMETRY_SDK_VERSION);
+}
+
+void f1()
+{
+ auto scoped_span = trace::Scope(get_tracer()->StartSpan("f1"));
+}
+
+void f2()
+{
+ auto scoped_span = trace::Scope(get_tracer()->StartSpan("f2"));
+
+ f1();
+ f1();
+}
+} // namespace
+
+void foo_library()
+{
+ auto scoped_span = trace::Scope(get_tracer()->StartSpan("library"));
+
+ f2();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.h b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.h
new file mode 100644
index 000000000..daebb2603
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/foo_library/foo_library.h
@@ -0,0 +1,6 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+void foo_library();
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/BUILD
new file mode 100644
index 000000000..956c7a569
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/BUILD
@@ -0,0 +1,16 @@
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+ name = "common_logs_foo_library",
+ srcs = [
+ "foo_library.cc",
+ ],
+ hdrs = [
+ "foo_library.h",
+ ],
+ defines = ["BAZEL_BUILD"],
+ deps = [
+ "//api",
+ "//sdk:headers",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/CMakeLists.txt
new file mode 100644
index 000000000..df14f5c98
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_library(common_logs_foo_library foo_library.h foo_library.cc)
+target_link_libraries(common_logs_foo_library PUBLIC ${CMAKE_THREAD_LIBS_INIT}
+ opentelemetry_api)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.cc b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.cc
new file mode 100644
index 000000000..9e4158406
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.cc
@@ -0,0 +1,39 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+#ifdef ENABLE_LOGS_PREVIEW
+# include <map>
+# include <string>
+# include "opentelemetry/logs/provider.h"
+# include "opentelemetry/sdk/version/version.h"
+# include "opentelemetry/trace/provider.h"
+
+namespace logs = opentelemetry::logs;
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+
+namespace
+{
+nostd::shared_ptr<trace::Tracer> get_tracer()
+{
+ auto provider = trace::Provider::GetTracerProvider();
+ return provider->GetTracer("foo_library", OPENTELEMETRY_SDK_VERSION);
+}
+
+nostd::shared_ptr<logs::Logger> get_logger()
+{
+ auto provider = logs::Provider::GetLoggerProvider();
+ return provider->GetLogger("foo_library_logger", "", "foo_library");
+}
+} // namespace
+
+void foo_library()
+{
+ auto span = get_tracer()->StartSpan("span 1");
+ auto scoped_span = trace::Scope(get_tracer()->StartSpan("foo_library"));
+ auto ctx = span->GetContext();
+ auto logger = get_logger();
+ logger->Log(opentelemetry::logs::Severity::kDebug, "body", {}, ctx.trace_id(), ctx.span_id(),
+ ctx.trace_flags(),
+ opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()));
+}
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.h b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.h
new file mode 100644
index 000000000..daebb2603
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/logs_foo_library/foo_library.h
@@ -0,0 +1,6 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+void foo_library();
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/BUILD
new file mode 100644
index 000000000..bc8494973
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/BUILD
@@ -0,0 +1,17 @@
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+ name = "common_metrics_foo_library",
+ srcs = [
+ "foo_library.cc",
+ ],
+ hdrs = [
+ "foo_library.h",
+ ],
+ defines = ["BAZEL_BUILD"],
+ deps = [
+ "//api",
+ "//sdk:headers",
+ "//sdk/src/metrics",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/CMakeLists.txt
new file mode 100644
index 000000000..4f2bca2a0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(common_metrics_foo_library foo_library.h foo_library.cc)
+target_link_libraries(common_metrics_foo_library PUBLIC opentelemetry_api)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.cc b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.cc
new file mode 100644
index 000000000..2fcbd660e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.cc
@@ -0,0 +1,87 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef ENABLE_METRICS_PREVIEW
+# include "foo_library.h"
+# include <chrono>
+# include <map>
+# include <thread>
+# include <vector>
+# include "opentelemetry/context/context.h"
+# include "opentelemetry/metrics/provider.h"
+
+namespace nostd = opentelemetry::nostd;
+namespace metrics_api = opentelemetry::metrics;
+
+namespace
+{
+
+std::map<std::string, std::string> get_random_attr()
+{
+ static const std::vector<std::pair<std::string, std::string>> labels = {{"key1", "value1"},
+ {"key2", "value2"},
+ {"key3", "value3"},
+ {"key4", "value4"},
+ {"key5", "value5"}};
+ return std::map<std::string, std::string>{labels[rand() % (labels.size() - 1)],
+ labels[rand() % (labels.size() - 1)]};
+}
+
+class MeasurementFetcher
+{
+public:
+ static void Fetcher(opentelemetry::metrics::ObserverResult<double> &observer_result, void *state)
+ {
+ double val = (rand() % 700) + 1.1;
+ std::map<std::string, std::string> labels = get_random_attr();
+ auto labelkv = opentelemetry::common::KeyValueIterableView<decltype(labels)>{labels};
+ observer_result.Observe(val /*, labelkv*/);
+ }
+};
+} // namespace
+
+void foo_library::counter_example(const std::string &name)
+{
+ std::string counter_name = name + "_counter";
+ auto provider = metrics_api::Provider::GetMeterProvider();
+ nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter(name, "1.2.0");
+ auto double_counter = meter->CreateDoubleCounter(counter_name);
+
+ while (true)
+ {
+ double val = (rand() % 700) + 1.1;
+ double_counter->Add(val);
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ }
+}
+
+void foo_library::observable_counter_example(const std::string &name)
+{
+ std::string counter_name = name + "_observable_counter";
+ auto provider = metrics_api::Provider::GetMeterProvider();
+ nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter(name, "1.2.0");
+ meter->CreateDoubleObservableCounter(counter_name, MeasurementFetcher::Fetcher);
+ while (true)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ }
+}
+
+void foo_library::histogram_example(const std::string &name)
+{
+ std::string histogram_name = name + "_histogram";
+ auto provider = metrics_api::Provider::GetMeterProvider();
+ nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter(name, "1.2.0");
+ auto histogram_counter = meter->CreateDoubleHistogram(histogram_name);
+ auto context = opentelemetry::context::Context{};
+ while (true)
+ {
+ double val = (rand() % 700) + 1.1;
+ std::map<std::string, std::string> labels = get_random_attr();
+ auto labelkv = opentelemetry::common::KeyValueIterableView<decltype(labels)>{labels};
+ histogram_counter->Record(val, labelkv, context);
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
+}
+
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.h b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.h
new file mode 100644
index 000000000..2f84bcc34
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/common/metrics_foo_library/foo_library.h
@@ -0,0 +1,15 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#ifndef ENABLE_METRICS_PREVIEW
+# include <string>
+
+class foo_library
+{
+public:
+ static void counter_example(const std::string &name);
+ static void histogram_example(const std::string &name);
+ static void observable_counter_example(const std::string &name);
+};
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/CMakeLists.txt
new file mode 100644
index 000000000..fd6ac7644
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/CMakeLists.txt
@@ -0,0 +1,6 @@
+project(etw_threadpool)
+
+add_executable(etw_threadpool main.cc)
+
+target_link_libraries(etw_threadpool ${CMAKE_THREAD_LIBS_INIT}
+ opentelemetry_api opentelemetry_exporter_etw)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/README.md b/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/README.md
new file mode 100644
index 000000000..a004a9f55
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/README.md
@@ -0,0 +1,32 @@
+# ETW Exporter multithreaded context propagation example
+
+## Preface
+
+This example shows how to pass context from main dispatcher thread to worker threads.
+While this example is convenient to run in Visual Studio with ETW exporter, the same
+logic should apply to any other exporter. Only the initial portion that obtains ETW
+Tracer is unique to ETW, the rest can be reused.
+
+## How to debug events in Visual Studio 2019 or newer
+
+Specify your component instrumentation name, which should match the destination ETW
+Provider Name or GUID. Example uses "OpenTelemetry-ETW-TLD" for the instrument /
+instrumentation name.
+
+In Visual Studio IDE:
+
+- navigate to `View -> Other Windows -> Diagnostic Events...`
+- click `Configure...` gear on top.
+- specify `OpenTelemetry-ETW-TLD` in the list of providers to monitor.
+- run example.
+- `Diagnostic Events` view shows you the event flow in realtime.
+
+## Explanation of the code flow
+
+`main` function acts as a dispatcher to manage thread pool called `pool`. `beep_bop`
+span is started in the `main`. Then in a loop up to `kMaxThreads` get started
+concurrently. Each thread executing `beep` function with a parent scope of `main`.
+`beep` subsequently calls into `bop` function, with a parent scope of `beep` span.
+Entire execution of all threads is grouped under the main span called `beep_bop`.
+At the end of execution, the `main` function joins all pending threads and ends
+the main span.
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/main.cc
new file mode 100644
index 000000000..d25883d1d
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/etw_threads/main.cc
@@ -0,0 +1,154 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Include common Trace Provider API and processor
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#include "opentelemetry/exporters/etw/etw_tracer_exporter.h"
+
+#include <iostream>
+#include <thread>
+
+#include <cstdio>
+#ifndef LOG_DEBUG
+# include <mutex>
+
+/**
+ * @brief Thread-safe logger routine.
+ * @param format
+ * @param args
+ * @return
+ */
+static inline int log_vprintf(const char *format, va_list args)
+{
+ static std::mutex cout_mutex;
+ std::lock_guard<std::mutex> lk(cout_mutex);
+ return vprintf(format, args);
+};
+
+/**
+ * @brief Thread-safe logger routine.
+ * @param format
+ * @param
+ * @return
+ */
+static inline int log_printf(const char *format, ...)
+{
+ int result;
+ va_list ap;
+ va_start(ap, format);
+ result = log_vprintf(format, ap);
+ va_end(ap);
+ return result;
+};
+
+// Debug macros
+# define LOG_DEBUG(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_TRACE(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_INFO(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_WARN(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_ERROR(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+#endif
+
+using namespace OPENTELEMETRY_NAMESPACE;
+
+using namespace opentelemetry::exporter::etw;
+
+// Specify destination ETW Provider Name or GUID.
+//
+// In Visual Studio:
+// - View -> Other Windows -> Diagnostic Events...
+// - Click Configure (gear on top).
+// - Specify "OpenTelemetry-ETW-TLD" in the list of providers.
+//
+// Event view shows event flow in realtime.
+const char *kGlobalProviderName = "OpenTelemetry-ETW-TLD";
+
+std::string providerName = kGlobalProviderName;
+
+// One provider can be used to associate with different destinations.
+exporter::etw::TracerProvider provider;
+
+// Code below is generic and may be reused with any other TracerProvider.
+// In ETW provider case - instrumentation name must match destination
+// ETW provider name.
+nostd::shared_ptr<trace::Tracer> tracer = provider.GetTracer(providerName, "1.0");
+
+// Obtain numeric thread id
+static inline uint64_t gettid()
+{
+ std::stringstream ss;
+ ss << std::this_thread::get_id();
+ uint64_t id = std::stoull(ss.str());
+ return id;
+}
+
+// bop gets called by beep.
+void bop()
+{
+ LOG_TRACE("bop worker tid=%u", gettid());
+ auto span = tracer->StartSpan("bop");
+ span->AddEvent("BopEvent", {{"tid", gettid()}});
+ span->SetAttribute("attrib", 2);
+ span->End();
+}
+
+// beep gets called in its own thread.
+// It is running in a thread pool, invoked via lambda by dispatcher.
+void beep()
+{
+ LOG_TRACE("beep worker tid=%u", gettid());
+ auto span = tracer->StartSpan("beep");
+ span->AddEvent("BeepEvent", {{"tid", gettid()}});
+ span->SetAttribute("attrib", 1);
+ {
+ auto bopScope = tracer->WithActiveSpan(span);
+ bop();
+ }
+ span->End();
+}
+
+// Max number of threads to spawn
+constexpr int kMaxThreads = 10;
+
+int main(int arc, char **argv)
+{
+ std::thread pool[kMaxThreads];
+
+ // Main dispatcher span: parent of all child thread spans.
+ auto mainSpan = tracer->StartSpan("beep_bop");
+ mainSpan->SetAttribute("attrib", 0);
+
+ // Start several threads to perform beep-bop actions.
+ LOG_TRACE("beep-boop dispatcher tid=%u", gettid());
+ for (auto i = 0; i < kMaxThreads; i++)
+ {
+ pool[i] = std::thread([&]() {
+ // This code runs in its own worker thread.
+ auto beepScope = tracer->WithActiveSpan(mainSpan);
+ // call beep -> bop
+ beep();
+ });
+ };
+
+ // Join all worker threads in the pool
+ for (auto &th : pool)
+ {
+ try
+ {
+ if (th.joinable())
+ th.join();
+ }
+ catch (...)
+ {
+ // thread might have been gracefully terminated already
+ }
+ }
+
+ // End span
+ mainSpan->End();
+
+ return 0;
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/grpc/BUILD
new file mode 100644
index 000000000..4b2de49cb
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/BUILD
@@ -0,0 +1,63 @@
+package(default_visibility = ["//visibility:public"])
+
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
+
+proto_library(
+ name = "messages_proto",
+ srcs = ["protos/messages.proto"],
+)
+
+cc_proto_library(
+ name = "messages_cc_proto",
+ deps = [":messages_proto"],
+)
+
+cc_grpc_library(
+ name = "messages_cc_grpc",
+ srcs = [":messages_proto"],
+ grpc_only = True,
+ deps = [":messages_cc_proto"],
+)
+
+cc_library(
+ name = "tracer_common",
+ srcs = ["tracer_common.h"],
+ defines = ["BAZEL_BUILD"],
+ tags = ["ostream"],
+ deps = [
+ "//exporters/ostream:ostream_span_exporter",
+ ],
+)
+
+cc_binary(
+ name = "client_grpc",
+ srcs = [
+ "client.cc",
+ ],
+ defines = ["BAZEL_BUILD"],
+ tags = ["ostream"],
+ deps = [
+ "messages_cc_grpc",
+ ":tracer_common",
+ "//api",
+ "//sdk/src/trace",
+ "@com_github_grpc_grpc//:grpc++",
+ ],
+)
+
+cc_binary(
+ name = "server_grpc",
+ srcs = [
+ "server.cc",
+ ],
+ defines = ["BAZEL_BUILD"],
+ tags = ["ostream"],
+ deps = [
+ "messages_cc_grpc",
+ ":tracer_common",
+ "//api",
+ "//sdk/src/trace",
+ "@com_github_grpc_grpc//:grpc++",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/grpc/CMakeLists.txt
new file mode 100644
index 000000000..4b701999e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/CMakeLists.txt
@@ -0,0 +1,45 @@
+# Proto file
+get_filename_component(proto_file "./protos/messages.proto" ABSOLUTE)
+get_filename_component(proto_file_path "${proto_file}" PATH)
+
+message("PATH:${proto_file_path}:${proto_file}")
+# Generated sources
+set(example_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/messages.pb.cc")
+set(example_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/messages.pb.h")
+set(example_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/messages.grpc.pb.cc")
+set(example_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/messages.grpc.pb.h")
+
+add_custom_command(
+ OUTPUT "${example_proto_srcs}" "${example_proto_hdrs}" "${example_grpc_srcs}"
+ "${example_grpc_hdrs}"
+ COMMAND
+ ${PROTOBUF_PROTOC_EXECUTABLE} ARGS "--grpc_out=${CMAKE_CURRENT_BINARY_DIR}"
+ "--cpp_out=${CMAKE_CURRENT_BINARY_DIR}" "--proto_path=${proto_file_path}"
+ "--plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN_EXECUTABLE}" "${proto_file}")
+
+add_library(example_grpc_proto ${example_grpc_srcs} ${example_grpc_hdrs}
+ ${example_proto_srcs} ${example_proto_hdrs})
+
+include(${PROJECT_SOURCE_DIR}/cmake/proto-options-patch.cmake)
+patch_protobuf_targets(example_grpc_proto)
+
+include_directories(
+ ${CMAKE_SOURCE_DIR}/exporters/ostream/include ${CMAKE_SOURCE_DIR}/ext/include
+ ${CMAKE_SOURCE_DIR}/api/include/ ${CMAKE_SOURCE_DIR/})
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+if(TARGET protobuf::libprotobuf)
+ target_link_libraries(example_grpc_proto gRPC::grpc++ protobuf::libprotobuf)
+else()
+ target_include_directories(example_grpc_proto ${Protobuf_INCLUDE_DIRS})
+ target_link_libraries(example_grpc_proto ${Protobuf_LIBRARIES})
+endif()
+
+foreach(_target client server)
+ add_executable(${_target} "${_target}.cc")
+ target_link_libraries(
+ ${_target} example_grpc_proto protobuf::libprotobuf gRPC::grpc++
+ opentelemetry_trace opentelemetry_exporter_ostream_span)
+ patch_protobuf_targets(${_target})
+endforeach()
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/README.md b/src/jaegertracing/opentelemetry-cpp/examples/grpc/README.md
new file mode 100644
index 000000000..96d1dc279
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/README.md
@@ -0,0 +1,107 @@
+# OpenTelemetry C++ Example
+
+## gRPC
+
+This is a simple example that demonstrates tracing a gRPC request from client to
+server. There is an experimental directory in this example - the code within has
+been commented out to prevent any conflicts. The example shows several aspects
+of tracing such as:
+
+* Using the `TracerProvider`
+* Implementing the TextMapCarrier
+* Context injection/extraction
+* Span Attributes
+* Span Semantic Conventions
+* Using the ostream exporter
+* Nested spans
+* W3c Trace Context Propagation (Very soon!)
+
+### Running the example
+
+1. The example uses gRPC C++ as well as Google's protocol buffers. Make sure you
+ have installed both of these packages on your system, in such a way that
+ CMake would know how to find them with this command:
+
+ ``find_package(gRPC)``
+
+2. Build and Deploy the opentelementry-cpp as described in
+ [INSTALL.md](../../INSTALL.md). Building the project will build all of the
+ examples and create new folders containing their executables within the
+ 'build' directory NOT the 'examples' directory.
+
+3. Start the server from your `build/examples/grpc` directory. Both the server
+ and client are configured to use 8800 as the default port, but if you would
+ like to use another port, you can specify that as an argument.
+
+ ```console
+ $ ./server [port_num]
+ Server listening on port: 0.0.0.0:8800
+ ```
+
+4. In a separate terminal window, run the client to make a single request:
+
+ ```console
+ $ ./client [port_num]
+ ...
+ ```
+
+5. You should see console exporter output for both the client and server
+ sessions.
+ * Client console
+
+ ```console
+ {
+ name : GreeterClient/Greet
+ trace_id : f5d16f8399be0d2c6b39d992634ffdbb
+ span_id : 9c79a2dd744d7d2d
+ tracestate :
+ parent_span_id: 0000000000000000
+ start : 1622603339918985700
+ duration : 4960500
+ description :
+ span kind : Client
+ status : Ok
+ attributes :
+ rpc.grpc.status_code: 0
+ net.peer.port: 8080
+ net.peer.ip: 0.0.0.0
+ rpc.method: Greet
+ rpc.service: grpc-example.GreetService
+ rpc.system: grpc
+ events :
+ }
+ ```
+
+ * Server console
+
+ ```console
+ {
+ name : GreeterService/Greet
+ trace_id : f5d16f8399be0d2c6b39d992634ffdbb
+ span_id : 1e8a7d2d46e08573
+ tracestate :
+ parent_span_id: 9c79a2dd744d7d2d
+ start : 1622603339923163800
+ duration : 76400
+ description :
+ span kind : Server
+ status : Ok
+ attributes :
+ rpc.grpc.status_code: 0
+ rpc.method: Greet
+ rpc.service: GreeterService
+ rpc.system: grpc
+ events :
+ {
+ name : Processing client attributes
+ timestamp : 1622603339923180800
+ attributes :
+ }
+ {
+ name : Response sent to client
+ timestamp : 1622603339923233700
+ attributes :
+ }
+ links :
+ }
+ ```
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/client.cc b/src/jaegertracing/opentelemetry-cpp/examples/grpc/client.cc
new file mode 100644
index 000000000..5a182f19a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/client.cc
@@ -0,0 +1,117 @@
+// Make sure to include GRPC headers first because otherwise Abseil may create
+// ambiguity with `nostd::variant` if compiled with Visual Studio 2015. Other
+// modern compilers are unaffected.
+#include <grpcpp/grpcpp.h>
+#ifdef BAZEL_BUILD
+# include "examples/grpc/protos/messages.grpc.pb.h"
+#else
+# include "messages.grpc.pb.h"
+#endif
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include "opentelemetry/trace/experimental_semantic_conventions.h"
+#include "tracer_common.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::ClientReader;
+using grpc::Status;
+
+using grpc_example::Greeter;
+using grpc_example::GreetRequest;
+using grpc_example::GreetResponse;
+
+namespace
+{
+namespace context = opentelemetry::context;
+using namespace opentelemetry::trace;
+class GreeterClient
+{
+public:
+ GreeterClient(std::shared_ptr<Channel> channel) : stub_(Greeter::NewStub(channel)) {}
+
+ std::string Greet(std::string ip, uint16_t port)
+ {
+ // Build gRPC Context objects and protobuf message containers
+ GreetRequest request;
+ GreetResponse response;
+ ClientContext context;
+ request.set_request("Nice to meet you!");
+
+ StartSpanOptions options;
+ options.kind = SpanKind::kClient;
+
+ std::string span_name = "GreeterClient/Greet";
+ auto span = get_tracer("grpc")->StartSpan(
+ span_name,
+ {{OTEL_GET_TRACE_ATTR(AttrRpcSystem), "grpc"},
+ {OTEL_GET_TRACE_ATTR(AttrRpcService), "grpc-example.GreetService"},
+ {OTEL_GET_TRACE_ATTR(AttrRpcMethod), "Greet"},
+ {OTEL_GET_TRACE_ATTR(AttrNetPeerIp), ip},
+ {OTEL_GET_TRACE_ATTR(AttrNetPeerPort), port}},
+ options);
+
+ auto scope = get_tracer("grpc-client")->WithActiveSpan(span);
+
+ // inject current context to grpc metadata
+ auto current_ctx = context::RuntimeContext::GetCurrent();
+ GrpcClientCarrier carrier(&context);
+ auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
+ prop->Inject(carrier, current_ctx);
+
+ // Send request to server
+ Status status = stub_->Greet(&context, request, &response);
+ if (status.ok())
+ {
+ span->SetStatus(StatusCode::kOk);
+ span->SetAttribute(OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), status.error_code());
+ // Make sure to end your spans!
+ span->End();
+ return response.response();
+ }
+ else
+ {
+ std::cout << status.error_code() << ": " << status.error_message() << std::endl;
+ span->SetStatus(StatusCode::kError);
+ span->SetAttribute(OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), status.error_code());
+ // Make sure to end your spans!
+ span->End();
+ return "RPC failed";
+ }
+ }
+
+private:
+ std::unique_ptr<Greeter::Stub> stub_;
+}; // GreeterClient class
+
+void RunClient(uint16_t port)
+{
+ GreeterClient greeter(
+ grpc::CreateChannel("0.0.0.0:" + std::to_string(port), grpc::InsecureChannelCredentials()));
+ std::string response = greeter.Greet("0.0.0.0", port);
+ std::cout << "grpc_server says: " << response << std::endl;
+}
+} // namespace
+
+int main(int argc, char **argv)
+{
+ initTracer();
+ // set global propagator
+ context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
+ opentelemetry::nostd::shared_ptr<context::propagation::TextMapPropagator>(
+ new propagation::HttpTraceContext()));
+ constexpr uint16_t default_port = 8800;
+ uint16_t port;
+ if (argc > 1)
+ {
+ port = atoi(argv[1]);
+ }
+ else
+ {
+ port = default_port;
+ }
+ RunClient(port);
+ return 0;
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/protos/messages.proto b/src/jaegertracing/opentelemetry-cpp/examples/grpc/protos/messages.proto
new file mode 100644
index 000000000..e0d69959b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/protos/messages.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package grpc_example;
+
+service Greeter {
+ rpc Greet(GreetRequest) returns (GreetResponse) {}
+}
+
+message GreetRequest {
+ string request = 1;
+}
+
+message GreetResponse {
+ string response = 1;
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/server.cc b/src/jaegertracing/opentelemetry-cpp/examples/grpc/server.cc
new file mode 100644
index 000000000..2671cc0b6
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/server.cc
@@ -0,0 +1,125 @@
+#ifdef BAZEL_BUILD
+# include "examples/grpc/protos/messages.grpc.pb.h"
+#else
+# include "messages.grpc.pb.h"
+#endif
+
+#include "opentelemetry/trace/context.h"
+#include "opentelemetry/trace/experimental_semantic_conventions.h"
+#include "opentelemetry/trace/span_context_kv_iterable_view.h"
+#include "tracer_common.h"
+
+#include <grpcpp/grpcpp.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+#include <grpcpp/server_context.h>
+
+#include <chrono>
+#include <fstream>
+#include <map>
+#include <sstream>
+#include <string>
+#include <thread>
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ServerWriter;
+using grpc::Status;
+
+using grpc_example::Greeter;
+using grpc_example::GreetRequest;
+using grpc_example::GreetResponse;
+
+using Span = opentelemetry::trace::Span;
+using SpanContext = opentelemetry::trace::SpanContext;
+using namespace opentelemetry::trace;
+
+namespace context = opentelemetry::context;
+
+namespace
+{
+class GreeterServer final : public Greeter::Service
+{
+public:
+ Status Greet(ServerContext *context,
+ const GreetRequest *request,
+ GreetResponse *response) override
+ {
+ for (auto elem : context->client_metadata())
+ {
+ std::cout << "ELEM: " << elem.first << " " << elem.second << "\n";
+ }
+
+ // Create a SpanOptions object and set the kind to Server to inform OpenTel.
+ StartSpanOptions options;
+ options.kind = SpanKind::kServer;
+
+ // extract context from grpc metadata
+ GrpcServerCarrier carrier(context);
+
+ auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
+ auto current_ctx = context::RuntimeContext::GetCurrent();
+ auto new_context = prop->Extract(carrier, current_ctx);
+ options.parent = GetSpan(new_context)->GetContext();
+
+ std::string span_name = "GreeterService/Greet";
+ auto span =
+ get_tracer("grpc")->StartSpan(span_name,
+ {{OTEL_GET_TRACE_ATTR(AttrRpcSystem), "grpc"},
+ {OTEL_GET_TRACE_ATTR(AttrRpcService), "GreeterService"},
+ {OTEL_GET_TRACE_ATTR(AttrRpcMethod), "Greet"},
+ {OTEL_GET_TRACE_ATTR(AttrRpcGrpcStatusCode), 0}},
+ options);
+ auto scope = get_tracer("grpc")->WithActiveSpan(span);
+
+ // Fetch and parse whatever HTTP headers we can from the gRPC request.
+ span->AddEvent("Processing client attributes");
+
+ std::string req = request->request();
+ std::cout << std::endl << "grpc_client says: " << req << std::endl;
+ std::string message = "The pleasure is mine.";
+ // Send response to client
+ response->set_response(message);
+ span->AddEvent("Response sent to client");
+
+ span->SetStatus(StatusCode::kOk);
+ // Make sure to end your spans!
+ span->End();
+ return Status::OK;
+ }
+}; // GreeterServer class
+
+void RunServer(uint16_t port)
+{
+ std::string address("0.0.0.0:" + std::to_string(port));
+ GreeterServer service;
+ ServerBuilder builder;
+
+ builder.RegisterService(&service);
+ builder.AddListeningPort(address, grpc::InsecureServerCredentials());
+
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ std::cout << "Server listening on port: " << address << std::endl;
+ server->Wait();
+ server->Shutdown();
+}
+} // namespace
+
+int main(int argc, char **argv)
+{
+ initTracer();
+ constexpr uint16_t default_port = 8800;
+ uint16_t port;
+ if (argc > 1)
+ {
+ port = atoi(argv[1]);
+ }
+ else
+ {
+ port = default_port;
+ }
+
+ RunServer(port);
+ return 0;
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/grpc/tracer_common.h b/src/jaegertracing/opentelemetry-cpp/examples/grpc/tracer_common.h
new file mode 100644
index 000000000..13474a732
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/grpc/tracer_common.h
@@ -0,0 +1,98 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include "opentelemetry/exporters/ostream/span_exporter.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#include "opentelemetry/context/propagation/global_propagator.h"
+#include "opentelemetry/context/propagation/text_map_propagator.h"
+#include "opentelemetry/nostd/shared_ptr.h"
+#include "opentelemetry/trace/propagation/http_trace_context.h"
+
+#include <grpcpp/grpcpp.h>
+#include <cstring>
+#include <iostream>
+#include <vector>
+
+using grpc::ClientContext;
+using grpc::ServerContext;
+
+namespace
+{
+class GrpcClientCarrier : public opentelemetry::context::propagation::TextMapCarrier
+{
+public:
+ GrpcClientCarrier(ClientContext *context) : context_(context) {}
+ GrpcClientCarrier() = default;
+ virtual opentelemetry::nostd::string_view Get(
+ opentelemetry::nostd::string_view key) const noexcept override
+ {
+ return "";
+ }
+
+ virtual void Set(opentelemetry::nostd::string_view key,
+ opentelemetry::nostd::string_view value) noexcept override
+ {
+ std::cout << " Client ::: Adding " << key << " " << value << "\n";
+ context_->AddMetadata(key.data(), value.data());
+ }
+
+ ClientContext *context_;
+};
+
+class GrpcServerCarrier : public opentelemetry::context::propagation::TextMapCarrier
+{
+public:
+ GrpcServerCarrier(ServerContext *context) : context_(context) {}
+ GrpcServerCarrier() = default;
+ virtual opentelemetry::nostd::string_view Get(
+ opentelemetry::nostd::string_view key) const noexcept override
+ {
+ auto it = context_->client_metadata().find(key.data());
+ if (it != context_->client_metadata().end())
+ {
+ return it->second.data();
+ }
+ return "";
+ }
+
+ virtual void Set(opentelemetry::nostd::string_view key,
+ opentelemetry::nostd::string_view value) noexcept override
+ {
+ // Not required for server
+ }
+
+ ServerContext *context_;
+};
+
+void initTracer()
+{
+ auto exporter = std::unique_ptr<opentelemetry::sdk::trace::SpanExporter>(
+ new opentelemetry::exporter::trace::OStreamSpanExporter);
+ auto processor = std::unique_ptr<opentelemetry::sdk::trace::SpanProcessor>(
+ new opentelemetry::sdk::trace::SimpleSpanProcessor(std::move(exporter)));
+ std::vector<std::unique_ptr<opentelemetry::sdk::trace::SpanProcessor>> processors;
+ processors.push_back(std::move(processor));
+ // Default is an always-on sampler.
+ auto context = std::make_shared<opentelemetry::sdk::trace::TracerContext>(std::move(processors));
+ auto provider = opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
+ new opentelemetry::sdk::trace::TracerProvider(context));
+ // Set the global trace provider
+ opentelemetry::trace::Provider::SetTracerProvider(provider);
+
+ // set global propagator
+ opentelemetry::context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
+ opentelemetry::nostd::shared_ptr<opentelemetry::context::propagation::TextMapPropagator>(
+ new opentelemetry::trace::propagation::HttpTraceContext()));
+}
+
+opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> get_tracer(std::string tracer_name)
+{
+ auto provider = opentelemetry::trace::Provider::GetTracerProvider();
+ return provider->GetTracer(tracer_name);
+}
+
+} // namespace
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/http/BUILD
new file mode 100644
index 000000000..ac36bc0ce
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/BUILD
@@ -0,0 +1,42 @@
+cc_binary(
+ name = "example_http_client",
+ srcs = [
+ "client.cc",
+ "tracer_common.h",
+ ],
+ copts = [
+ "-DWITH_CURL",
+ ],
+ linkopts = select({
+ "//bazel:windows": [
+ "-DEFAULTLIB:advapi32.lib",
+ "-DEFAULTLIB:crypt32.lib",
+ "-DEFAULTLIB:Normaliz.lib",
+ ],
+ "//conditions:default": [],
+ }),
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//exporters/ostream:ostream_span_exporter",
+ "//ext:headers",
+ "//ext/src/http/client/curl:http_client_curl",
+ "//sdk/src/trace",
+ ],
+)
+
+cc_binary(
+ name = "example_http_server",
+ srcs = [
+ "server.cc",
+ "server.h",
+ "tracer_common.h",
+ ],
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//exporters/ostream:ostream_span_exporter",
+ "//ext:headers",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/http/CMakeLists.txt
new file mode 100644
index 000000000..a1181c93a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/CMakeLists.txt
@@ -0,0 +1,20 @@
+find_package(CURL)
+
+if(NOT CURL_FOUND)
+ message(WARNING "Skipping http client/server example build: CURL not found")
+else()
+ include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include
+ ${CMAKE_SOURCE_DIR}/ext/include ${CMAKE_SOURCE_DIR/})
+
+ add_executable(http_client client.cc)
+ add_executable(http_server server.cc)
+
+ target_link_libraries(
+ http_client ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace
+ opentelemetry_http_client_curl opentelemetry_exporter_ostream_span
+ ${CURL_LIBRARIES})
+
+ target_link_libraries(
+ http_server ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace
+ opentelemetry_http_client_curl opentelemetry_exporter_ostream_span)
+endif()
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/README.md b/src/jaegertracing/opentelemetry-cpp/examples/http/README.md
new file mode 100644
index 000000000..70285170f
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/README.md
@@ -0,0 +1,112 @@
+# OpenTelemetry C++ Example
+
+## HTTP
+
+This is a simple example that demonstrates tracing an HTTP request from client
+to server. The example shows several aspects of tracing such as:
+
+* Using the `TracerProvider`
+* Using the `GlobalPropagator`
+* Span Attributes
+* Span Events
+* Using the ostream exporter
+* Nested spans (TBD)
+* W3C Trace Context Propagation
+
+### Running the example
+
+1. The example uses HTTP server and client provided as part of this repo:
+ * [HTTP
+ Client](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/ext/include/opentelemetry/ext/http/client)
+ * [HTTP
+ Server](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/ext/include/opentelemetry/ext/http/server)
+
+2. Build and Deploy the opentelementry-cpp as described in
+ [INSTALL.md](../../INSTALL.md)
+
+3. Start the server from the `examples/http` directory
+
+ ```console
+ $ http_server 8800
+ Server is running..Press ctrl-c to exit...
+ ```
+
+4. In a separate terminal window, run the client to make a single request:
+
+ ```console
+ $ ./http_client 8800
+ ...
+ ...
+ ```
+
+5. You should see console exporter output for both the client and server
+ sessions.
+ * Client console
+
+ ```console
+
+ {
+ name : /helloworld
+ trace_id : baa922bc0da6f79d46373371f4416463
+ span_id : 83bed4da7a01267d
+ tracestate :
+ parent_span_id: 0000000000000000
+ start : 1620287026111457000
+ duration : 5164400
+ description :
+ span kind : Client
+ status : Unset
+ attributes :
+ http.header.Date: Thu, 06 May 2021 07:43:46 GMT
+ http.header.Content-Length: 0
+ http.status_code: 200
+ http.method: GET
+ http.header.Host: localhost
+ http.header.Content-Type: text/plain
+ http.header.Connection: keep-alive
+ http.scheme: http
+ http.url: h**p://localhost:8800/helloworld
+ events :
+ links :
+
+ }
+ ```
+
+ * Server console
+
+ ```console
+
+ {
+ name : /helloworld
+ trace_id : baa922bc0da6f79d46373371f4416463
+ span_id : c3e7e23042eb670e
+ tracestate :
+ parent_span_id: 83bed4da7a01267d
+ start : 1620287026115443300
+ duration : 50700
+ description :
+ span kind : Server
+ status : Unset
+ attributes :
+ http.header.Traceparent: 00-baa922bc0da6f79d46373371f4416463-83bed4da7a01267d-01
+ http.header.Accept: */*
+ http.request_content_length: 0
+ http.header.Host: localhost:8800
+ http.scheme: http
+ http.client_ip: 127.0.0.1:50792
+ http.method: GET
+ net.host.port: 8800
+ http.server_name: localhost
+ events :
+ {
+ name : Processing request
+ timestamp : 1620287026115464000
+ attributes :
+ }
+ links :
+
+ }
+ ```
+
+ As seen from example above, `trace_id` and `parent_span_id` is propagated
+ from client to server.
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/client.cc b/src/jaegertracing/opentelemetry-cpp/examples/http/client.cc
new file mode 100644
index 000000000..91161e221
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/client.cc
@@ -0,0 +1,95 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/ext/http/client/http_client_factory.h"
+#include "opentelemetry/ext/http/common/url_parser.h"
+#include "opentelemetry/trace/experimental_semantic_conventions.h"
+#include "tracer_common.h"
+
+namespace
+{
+
+using namespace opentelemetry::trace;
+namespace http_client = opentelemetry::ext::http::client;
+namespace context = opentelemetry::context;
+namespace nostd = opentelemetry::nostd;
+
+void sendRequest(const std::string &url)
+{
+ auto http_client = http_client::HttpClientFactory::CreateSync();
+
+ // start active span
+ StartSpanOptions options;
+ options.kind = SpanKind::kClient; // client
+ opentelemetry::ext::http::common::UrlParser url_parser(url);
+
+ std::string span_name = url_parser.path_;
+ auto span = get_tracer("http-client")
+ ->StartSpan(span_name,
+ {{OTEL_GET_TRACE_ATTR(AttrHttpUrl), url_parser.url_},
+ {OTEL_GET_TRACE_ATTR(AttrHttpScheme), url_parser.scheme_},
+ {OTEL_GET_TRACE_ATTR(AttrHttpMethod), "GET"}},
+ options);
+ auto scope = get_tracer("http-client")->WithActiveSpan(span);
+
+ // inject current context into http header
+ auto current_ctx = context::RuntimeContext::GetCurrent();
+ HttpTextMapCarrier<http_client::Headers> carrier;
+ auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
+ prop->Inject(carrier, current_ctx);
+
+ // send http request
+ http_client::Result result = http_client->Get(url, carrier.headers_);
+ if (result)
+ {
+ // set span attributes
+ auto status_code = result.GetResponse().GetStatusCode();
+ span->SetAttribute(OTEL_GET_TRACE_ATTR(AttrHttpStatusCode), status_code);
+ result.GetResponse().ForEachHeader(
+ [&span](nostd::string_view header_name, nostd::string_view header_value) {
+ span->SetAttribute("http.header." + std::string(header_name.data()), header_value);
+ return true;
+ });
+
+ if (status_code >= 400)
+ {
+ span->SetStatus(StatusCode::kError);
+ }
+ }
+ else
+ {
+ span->SetStatus(
+ StatusCode::kError,
+ "Response Status :" +
+ std::to_string(
+ static_cast<typename std::underlying_type<http_client::SessionState>::type>(
+ result.GetSessionState())));
+ }
+ // end span and export data
+ span->End();
+}
+
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ initTracer();
+ constexpr char default_host[] = "localhost";
+ constexpr char default_path[] = "/helloworld";
+ constexpr uint16_t default_port = 8800;
+ uint16_t port;
+
+ // The port the validation service listens to can be specified via the command line.
+ if (argc > 1)
+ {
+ port = atoi(argv[1]);
+ }
+ else
+ {
+ port = default_port;
+ }
+
+ std::string url = "http://" + std::string(default_host) + ":" + std::to_string(port) +
+ std::string(default_path);
+ sendRequest(url);
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/server.cc b/src/jaegertracing/opentelemetry-cpp/examples/http/server.cc
new file mode 100644
index 000000000..46772dc05
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/server.cc
@@ -0,0 +1,94 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "server.h"
+#include "opentelemetry/trace/context.h"
+#include "opentelemetry/trace/experimental_semantic_conventions.h"
+#include "tracer_common.h"
+
+#include <iostream>
+#include <thread>
+
+namespace
+{
+
+using namespace opentelemetry::trace;
+namespace context = opentelemetry::context;
+
+uint16_t server_port = 8800;
+constexpr const char *server_name = "localhost";
+
+class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback
+{
+public:
+ virtual int onHttpRequest(HTTP_SERVER_NS::HttpRequest const &request,
+ HTTP_SERVER_NS::HttpResponse &response) override
+ {
+ StartSpanOptions options;
+ options.kind = SpanKind::kServer; // server
+ std::string span_name = request.uri;
+
+ // extract context from http header
+ const HttpTextMapCarrier<std::map<std::string, std::string>> carrier(
+ (std::map<std::string, std::string> &)request.headers);
+ auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator();
+ auto current_ctx = context::RuntimeContext::GetCurrent();
+ auto new_context = prop->Extract(carrier, current_ctx);
+ options.parent = GetSpan(new_context)->GetContext();
+
+ // start span with parent context extracted from http header
+ auto span = get_tracer("http-server")
+ ->StartSpan(span_name,
+ {{OTEL_GET_TRACE_ATTR(AttrHttpServerName), server_name},
+ {OTEL_GET_TRACE_ATTR(AttrNetHostPort), server_port},
+ {OTEL_GET_TRACE_ATTR(AttrHttpMethod), request.method},
+ {OTEL_GET_TRACE_ATTR(AttrHttpScheme), "http"},
+ {OTEL_GET_TRACE_ATTR(AttrHttpRequestContentLength),
+ static_cast<uint64_t>(request.content.length())},
+ {OTEL_GET_TRACE_ATTR(AttrHttpClientIp), request.client}},
+ options);
+
+ auto scope = get_tracer("http_server")->WithActiveSpan(span);
+
+ for (auto &kv : request.headers)
+ {
+ span->SetAttribute("http.header." + std::string(kv.first.data()), kv.second);
+ }
+ if (request.uri == "/helloworld")
+ {
+ span->AddEvent("Processing request");
+ response.headers[HTTP_SERVER_NS::CONTENT_TYPE] = HTTP_SERVER_NS::CONTENT_TYPE_TEXT;
+ span->End();
+ return 200;
+ }
+ span->End();
+ return 404;
+ }
+};
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ initTracer();
+
+ // The port the validation service listens to can be specified via the command line.
+ if (argc > 1)
+ {
+ server_port = atoi(argv[1]);
+ }
+
+ HttpServer http_server(server_name, server_port);
+ RequestHandler req_handler;
+ http_server.AddHandler("/helloworld", &req_handler);
+ auto root_span = get_tracer("http_server")->StartSpan(__func__);
+ Scope scope(root_span);
+ http_server.Start();
+ std::cout << "Server is running..Press ctrl-c to exit...\n";
+ while (1)
+ {
+ std::this_thread::sleep_for(std::chrono::seconds(100));
+ }
+ http_server.Stop();
+ root_span->End();
+ return 0;
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/server.h b/src/jaegertracing/opentelemetry-cpp/examples/http/server.h
new file mode 100644
index 000000000..2b94bf3a6
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/server.h
@@ -0,0 +1,53 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include <atomic>
+#include <string>
+#include "opentelemetry/ext/http/server/http_server.h"
+
+namespace
+{
+
+class HttpServer : public HTTP_SERVER_NS::HttpRequestCallback
+{
+
+protected:
+ HTTP_SERVER_NS::HttpServer server_;
+ std::string server_url_;
+ uint16_t port_;
+ std::atomic<bool> is_running_{false};
+
+public:
+ HttpServer(std::string server_name = "test_server", uint16_t port = 8800) : port_(port)
+ {
+ server_.setServerName(server_name);
+ server_.setKeepalive(false);
+ }
+
+ void AddHandler(std::string path, HTTP_SERVER_NS::HttpRequestCallback *request_handler)
+ {
+ server_.addHandler(path, *request_handler);
+ }
+
+ void Start()
+ {
+ if (!is_running_.exchange(true))
+ {
+ server_.addListeningPort(port_);
+ server_.start();
+ }
+ }
+
+ void Stop()
+ {
+ if (is_running_.exchange(false))
+ {
+ server_.stop();
+ }
+ }
+
+ ~HttpServer() { Stop(); }
+};
+
+} // namespace \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/http/tracer_common.h b/src/jaegertracing/opentelemetry-cpp/examples/http/tracer_common.h
new file mode 100644
index 000000000..619aed622
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/http/tracer_common.h
@@ -0,0 +1,87 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+#include "opentelemetry/exporters/ostream/span_exporter.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#include "opentelemetry/context/propagation/global_propagator.h"
+#include "opentelemetry/context/propagation/text_map_propagator.h"
+#include "opentelemetry/trace/propagation/http_trace_context.h"
+
+#include <cstring>
+#include <iostream>
+#include <vector>
+#include "opentelemetry/ext/http/client/http_client.h"
+#include "opentelemetry/nostd/shared_ptr.h"
+
+namespace
+{
+
+template <typename T>
+class HttpTextMapCarrier : public opentelemetry::context::propagation::TextMapCarrier
+{
+public:
+ HttpTextMapCarrier<T>(T &headers) : headers_(headers) {}
+ HttpTextMapCarrier() = default;
+ virtual opentelemetry::nostd::string_view Get(
+ opentelemetry::nostd::string_view key) const noexcept override
+ {
+ std::string key_to_compare = key.data();
+ // Header's first letter seems to be automatically capitaliazed by our test http-server, so
+ // compare accordingly.
+ if (key == opentelemetry::trace::propagation::kTraceParent)
+ {
+ key_to_compare = "Traceparent";
+ }
+ else if (key == opentelemetry::trace::propagation::kTraceState)
+ {
+ key_to_compare = "Tracestate";
+ }
+ auto it = headers_.find(key_to_compare);
+ if (it != headers_.end())
+ {
+ return it->second;
+ }
+ return "";
+ }
+
+ virtual void Set(opentelemetry::nostd::string_view key,
+ opentelemetry::nostd::string_view value) noexcept override
+ {
+ headers_.insert(std::pair<std::string, std::string>(std::string(key), std::string(value)));
+ }
+
+ T headers_;
+};
+
+void initTracer()
+{
+ auto exporter = std::unique_ptr<opentelemetry::sdk::trace::SpanExporter>(
+ new opentelemetry::exporter::trace::OStreamSpanExporter);
+ auto processor = std::unique_ptr<opentelemetry::sdk::trace::SpanProcessor>(
+ new opentelemetry::sdk::trace::SimpleSpanProcessor(std::move(exporter)));
+ std::vector<std::unique_ptr<opentelemetry::sdk::trace::SpanProcessor>> processors;
+ processors.push_back(std::move(processor));
+ // Default is an always-on sampler.
+ auto context = std::make_shared<opentelemetry::sdk::trace::TracerContext>(std::move(processors));
+ auto provider = opentelemetry::nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
+ new opentelemetry::sdk::trace::TracerProvider(context));
+ // Set the global trace provider
+ opentelemetry::trace::Provider::SetTracerProvider(provider);
+
+ // set global propagator
+ opentelemetry::context::propagation::GlobalTextMapPropagator::SetGlobalPropagator(
+ opentelemetry::nostd::shared_ptr<opentelemetry::context::propagation::TextMapPropagator>(
+ new opentelemetry::trace::propagation::HttpTraceContext()));
+}
+
+opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> get_tracer(std::string tracer_name)
+{
+ auto provider = opentelemetry::trace::Provider::GetTracerProvider();
+ return provider->GetTracer(tracer_name);
+}
+
+} // namespace
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/jaeger/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/BUILD
new file mode 100644
index 000000000..23f42f93b
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/BUILD
@@ -0,0 +1,13 @@
+cc_binary(
+ name = "example_jaeger",
+ srcs = [
+ "main.cc",
+ ],
+ tags = ["jaeger"],
+ deps = [
+ "//api",
+ "//examples/common/foo_library:common_foo_library",
+ "//exporters/jaeger:opentelemetry_exporter_jaeger_trace",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/jaeger/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/CMakeLists.txt
new file mode 100644
index 000000000..713521c3a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/CMakeLists.txt
@@ -0,0 +1,6 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/jaeger/include)
+
+add_executable(example_jaeger main.cc)
+target_link_libraries(
+ example_jaeger ${CMAKE_THREAD_LIBS_INIT} common_foo_library
+ opentelemetry_trace opentelemetry_exporter_jaeger_trace)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/jaeger/README.md b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/README.md
new file mode 100644
index 000000000..42ac4e125
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/README.md
@@ -0,0 +1,18 @@
+# Jaeger Exporter Example
+
+This is an example of how to use the Jaeger exporter.
+
+The application in `main.cc` initializes an `JaegerExporter` instance and uses it
+to register a tracer provider from the [OpenTelemetry
+SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then
+calls a `foo_library` which has been instrumented using the [OpenTelemetry
+API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api).
+
+Resulting spans are exported to the Jaeger agent using the Jaeger exporter.
+
+Note that the Jaeger exporter connects to the agent at `localhost:6831` by
+default.
+
+Once you have the Collector running, see
+[CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
+running the example.
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/jaeger/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/main.cc
new file mode 100644
index 000000000..d0f507fd4
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/jaeger/main.cc
@@ -0,0 +1,46 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/exporters/jaeger/jaeger_exporter.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#ifdef BAZEL_BUILD
+# include "examples/common/foo_library/foo_library.h"
+#else
+# include "foo_library/foo_library.h"
+#endif
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace jaeger = opentelemetry::exporter::jaeger;
+
+namespace
+{
+opentelemetry::exporter::jaeger::JaegerExporterOptions opts;
+void InitTracer()
+{
+ // Create Jaeger exporter instance
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new jaeger::JaegerExporter(opts));
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider =
+ nostd::shared_ptr<trace::TracerProvider>(new trace_sdk::TracerProvider(std::move(processor)));
+ // Set the global trace provider
+ trace::Provider::SetTracerProvider(provider);
+}
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ if (argc == 2)
+ {
+ opts.endpoint = argv[1];
+ }
+ // Removing this line will leave the default noop TracerProvider in place.
+ InitTracer();
+
+ foo_library();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD
new file mode 100644
index 000000000..95d6490ba
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/BUILD
@@ -0,0 +1,28 @@
+cc_binary(
+ name = "metrics_simple_example",
+ srcs = [
+ "main.cc",
+ ],
+ linkopts = ["-pthread"],
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//exporters/ostream:ostream_metrics_exporter_deprecated",
+ "//sdk/src/_metrics:metrics_deprecated",
+ ],
+)
+
+cc_binary(
+ name = "metrics_ostream_example",
+ srcs = [
+ "metrics_ostream.cc",
+ ],
+ linkopts = ["-pthread"],
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//examples/common/metrics_foo_library:common_metrics_foo_library",
+ "//exporters/ostream:ostream_metric_exporter",
+ "//sdk/src/metrics",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt
new file mode 100644
index 000000000..a2088fd51
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/CMakeLists.txt
@@ -0,0 +1,13 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include)
+if(WITH_METRICS_PREVIEW)
+ add_executable(simple_metrics main.cc)
+ target_link_libraries(
+ simple_metrics ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics_deprecated
+ opentelemetry_exporter_ostream_metrics_deprecated)
+else()
+ add_executable(metrics_ostream_example metrics_ostream.cc)
+ target_link_libraries(
+ metrics_ostream_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics
+ opentelemetry_exporter_ostream_metrics opentelemetry_resources
+ common_metrics_foo_library)
+endif()
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md
new file mode 100644
index 000000000..b2c5dc0a7
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/README.md
@@ -0,0 +1,86 @@
+# Simple Metrics Example
+
+This example initializes the metrics pipeline with 2 different instrument types.
+Here are more detailed explanations of each part.
+
+1: Initialize an exporter and a reader. In this case, we initialize an OStream
+Exporter which will print to stdout by default.
+The reader periodically collects metrics from the collector and exports them.
+
+```cpp
+std::unique_ptr<metric_sdk::MetricExporter> exporter{new exportermetrics::OStreamMetricExporter};
+std::unique_ptr<metric_sdk::MetricReader> reader{
+ new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)};
+```
+
+2: Initialize a MeterProvider and add the reader.
+We will use this to obtain Meter objects in the future.
+
+```cpp
+auto provider = std::shared_ptr<metrics_api::MeterProvider>(new opentelemetry::metrics::MeterProvider());
+auto p = std::static_pointer_cast<metric_sdk::MeterProvider>(provider);
+p->AddMetricReader(std::move(reader));
+```
+
+3: Create and add a view to the provider.
+
+```cpp
+std::unique_ptr<metric_sdk::InstrumentSelector> instrument_selector{
+ new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, "name_counter")};
+std::unique_ptr<metric_sdk::MeterSelector> meter_selector{
+ new metric_sdk::MeterSelector(name, version, schema)};
+std::unique_ptr<metric_sdk::View> sum_view{
+ new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}};
+p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view));
+```
+
+4: Then create a
+[Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter)
+instrument from it. Every Meter pointer returned by the
+MeterProvider points to the same Meter. This means that the Meter will be able
+to combine metrics captured from different functions without having to
+constantly pass the Meter around the library.
+
+```cpp
+nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter(name, "1.2.0");
+auto double_counter = meter->CreateDoubleCounter(counter_name);
+// Create a label set which annotates metric values
+std::map<std::string, std::string> labels = {{"key", "value"}};
+auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+double_counter->Add(val, labelkv);
+```
+
+5: To use histogram instrument, a view with proper `InstrumentType` and `AggregationType`
+has to be added to the provider.
+
+```cpp
+std::unique_ptr<metric_sdk::InstrumentSelector> histogram_instrument_selector{
+ new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, "histogram_name")};
+std::unique_ptr<metric_sdk::MeterSelector> histogram_meter_selector{
+ new metric_sdk::MeterSelector(name, version, schema)};
+std::unique_ptr<metric_sdk::View> histogram_view{
+ new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}};
+p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector),
+ std::move(histogram_view));
+
+auto histogram_counter = meter->CreateDoubleHistogram("histogram_name");
+auto context = opentelemetry::context::Context{};
+histogram_counter->Record(val, labelkv, context);
+```
+
+See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
+running the example.
+
+## Additional Documentation
+
+[API
+Design](https://github.com/open-o11y/docs/blob/master/cpp-metrics/api-design.md)
+
+[SDK
+Design](https://github.com/open-o11y/docs/blob/master/cpp-metrics/sdk-design.md)
+
+[OStreamExporters
+Design](https://github.com/open-o11y/docs/blob/master/cpp-ostream/ostream-exporter-design.md)
+
+[OpenTelemetry C++ Metrics
+Overview](https://github.com/open-o11y/docs/blob/master/cpp-metrics/README.md)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc
new file mode 100644
index 000000000..3a18a52f3
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/main.cc
@@ -0,0 +1,118 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifdef ENABLE_METRICS_PREVIEW
+# include "opentelemetry/_metrics/provider.h"
+# include "opentelemetry/exporters/ostream/metrics_exporter.h"
+# include "opentelemetry/sdk/_metrics/controller.h"
+# include "opentelemetry/sdk/_metrics/meter.h"
+# include "opentelemetry/sdk/_metrics/meter_provider.h"
+# include "opentelemetry/sdk/_metrics/ungrouped_processor.h"
+
+namespace metric_sdk = opentelemetry::sdk::metrics;
+namespace nostd = opentelemetry::nostd;
+namespace common = opentelemetry::common;
+namespace exportermetrics = opentelemetry::exporter::metrics;
+namespace metrics_api = opentelemetry::metrics;
+
+int main()
+{
+ // Initialize and set the global MeterProvider
+ auto provider = nostd::shared_ptr<metrics_api::MeterProvider>(new metric_sdk::MeterProvider);
+ metrics_api::Provider::SetMeterProvider(provider);
+
+ // Get the Meter from the MeterProvider
+ nostd::shared_ptr<metrics_api::Meter> meter = provider->GetMeter("Test", "0.1.0");
+
+ // Create the controller with Stateless Metrics Processor
+ metric_sdk::PushController ControllerStateless(
+ meter,
+ std::unique_ptr<metric_sdk::MetricsExporter>(new exportermetrics::OStreamMetricsExporter),
+ std::shared_ptr<metric_sdk::MetricsProcessor>(
+ new metric_sdk::UngroupedMetricsProcessor(false)),
+ .05);
+
+ // Create and instrument
+ auto intupdowncounter = meter->NewIntUpDownCounter("UpDownCounter", "None", "none", true);
+ auto intcounter = meter->NewIntCounter("Counter", "none", "none", true);
+
+ // Create a labelset
+ std::map<std::string, std::string> labels = {{"key", "value"}};
+ auto labelkv = common::KeyValueIterableView<decltype(labels)>{labels};
+
+ // Create arrays of instrument and values to add to them
+ metrics_api::SynchronousInstrument<int> *iinstr_arr[] = {intupdowncounter.get(),
+ intcounter.get()};
+ int ivalues_arr[] = {10, 5};
+
+ // Change the arrays to be nostd::spans
+ nostd::span<metrics_api::SynchronousInstrument<int> *> instrument_span{iinstr_arr};
+ nostd::span<const int, 2> instrument_values{ivalues_arr};
+
+ /**
+ * First way of updating an instrument, RecordBatch. We can update multiple instruments at once by
+ * using a span of instruments and a span of values. This RecordBatch will update the ith
+ * instrument with the ith value.
+ **/
+ std::cout << "Example 1" << std::endl;
+ ControllerStateless.start();
+
+ // Updating multiple instruments with the same labelset
+ meter->RecordIntBatch(labelkv, instrument_span, instrument_values);
+
+ ControllerStateless.stop();
+ /**
+ * Second way of updating an instrument, bind then add. In this method the user binds an
+ *instrument to a labelset Then add to the bounded instrument, then unbind.
+ **/
+ std::cout << "Example 2" << std::endl;
+ ControllerStateless.start();
+
+ auto boundintupdowncounter = intupdowncounter->bindUpDownCounter(labelkv);
+ boundintupdowncounter->add(50);
+ boundintupdowncounter->unbind();
+
+ ControllerStateless.stop();
+ /**
+ * The Third and final way is to add a value with a labelset at the same time. This also shows
+ * The difference between using a Stateless and Stateful Processor
+ */
+
+ // Start exporting from the Controller with Stateless Processor
+ std::cout << "-----"
+ << " Stateless Processor "
+ << "-----" << std::endl;
+ ControllerStateless.start();
+ for (int i = 0; i < 20; i++)
+ {
+ intupdowncounter->add(i, labelkv);
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+ ControllerStateless.stop();
+
+ // Do the same thing for stateful to see the difference
+ metric_sdk::PushController ControllerStateful(
+ meter,
+ std::unique_ptr<metric_sdk::MetricsExporter>(new exportermetrics::OStreamMetricsExporter),
+ std::shared_ptr<metric_sdk::MetricsProcessor>(
+ new metric_sdk::UngroupedMetricsProcessor(true)),
+ .05);
+
+ // Start exporting from the Controller with Stateful Processor
+ std::cout << "-----"
+ << " Stateful Processor "
+ << "-----" << std::endl;
+ ControllerStateful.start();
+ for (int i = 0; i < 20; i++)
+ {
+ intupdowncounter->add(i, labelkv);
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ }
+ ControllerStateful.stop();
+}
+#else
+int main()
+{
+ // empty
+}
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc
new file mode 100644
index 000000000..585856f91
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/metrics_simple/metrics_ostream.cc
@@ -0,0 +1,119 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef ENABLE_METRICS_PREVIEW
+# include <memory>
+# include <thread>
+# include "opentelemetry/exporters/ostream/metric_exporter.h"
+# include "opentelemetry/metrics/provider.h"
+# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
+# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h"
+# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h"
+# include "opentelemetry/sdk/metrics/meter.h"
+# include "opentelemetry/sdk/metrics/meter_provider.h"
+
+# ifdef BAZEL_BUILD
+# include "examples/common/metrics_foo_library/foo_library.h"
+# else
+# include "metrics_foo_library/foo_library.h"
+# endif
+
+namespace metric_sdk = opentelemetry::sdk::metrics;
+namespace nostd = opentelemetry::nostd;
+namespace common = opentelemetry::common;
+namespace exportermetrics = opentelemetry::exporter::metrics;
+namespace metrics_api = opentelemetry::metrics;
+
+namespace
+{
+
+void initMetrics(const std::string &name)
+{
+ std::unique_ptr<metric_sdk::MetricExporter> exporter{new exportermetrics::OStreamMetricExporter};
+
+ std::string version{"1.2.0"};
+ std::string schema{"https://opentelemetry.io/schemas/1.2.0"};
+
+ // Initialize and set the global MeterProvider
+ metric_sdk::PeriodicExportingMetricReaderOptions options;
+ options.export_interval_millis = std::chrono::milliseconds(1000);
+ options.export_timeout_millis = std::chrono::milliseconds(500);
+ std::unique_ptr<metric_sdk::MetricReader> reader{
+ new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)};
+ auto provider = std::shared_ptr<metrics_api::MeterProvider>(new metric_sdk::MeterProvider());
+ auto p = std::static_pointer_cast<metric_sdk::MeterProvider>(provider);
+ p->AddMetricReader(std::move(reader));
+
+ // counter view
+ std::string counter_name = name + "_counter";
+ std::unique_ptr<metric_sdk::InstrumentSelector> instrument_selector{
+ new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, counter_name)};
+ std::unique_ptr<metric_sdk::MeterSelector> meter_selector{
+ new metric_sdk::MeterSelector(name, version, schema)};
+ std::unique_ptr<metric_sdk::View> sum_view{
+ new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}};
+ p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view));
+
+ // observable counter view
+ std::string observable_counter_name = name + "_observable_counter";
+ std::unique_ptr<metric_sdk::InstrumentSelector> observable_instrument_selector{
+ new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kObservableCounter,
+ observable_counter_name)};
+ std::unique_ptr<metric_sdk::MeterSelector> observable_meter_selector{
+ new metric_sdk::MeterSelector(name, version, schema)};
+ std::unique_ptr<metric_sdk::View> observable_sum_view{
+ new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}};
+ p->AddView(std::move(observable_instrument_selector), std::move(observable_meter_selector),
+ std::move(observable_sum_view));
+
+ // histogram view
+ std::string histogram_name = name + "_histogram";
+ std::unique_ptr<metric_sdk::InstrumentSelector> histogram_instrument_selector{
+ new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, histogram_name)};
+ std::unique_ptr<metric_sdk::MeterSelector> histogram_meter_selector{
+ new metric_sdk::MeterSelector(name, version, schema)};
+ std::unique_ptr<metric_sdk::View> histogram_view{
+ new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}};
+ p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector),
+ std::move(histogram_view));
+ metrics_api::Provider::SetMeterProvider(provider);
+}
+} // namespace
+
+int main(int argc, char **argv)
+{
+ std::string example_type;
+ if (argc >= 2)
+ {
+ example_type = argv[1];
+ }
+
+ std::string name{"ostream_metric_example"};
+ initMetrics(name);
+
+ if (example_type == "counter")
+ {
+ foo_library::counter_example(name);
+ }
+ else if (example_type == "observable_counter")
+ {
+ foo_library::observable_counter_example(name);
+ }
+ else if (example_type == "histogram")
+ {
+ foo_library::histogram_example(name);
+ }
+ else
+ {
+ std::thread counter_example{&foo_library::counter_example, name};
+ std::thread observable_counter_example{&foo_library::observable_counter_example, name};
+ std::thread histogram_example{&foo_library::histogram_example, name};
+
+ counter_example.join();
+ observable_counter_example.join();
+ histogram_example.join();
+ }
+}
+#else
+int main() {}
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/BUILD
new file mode 100644
index 000000000..3388d3942
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/BUILD
@@ -0,0 +1,17 @@
+cc_binary(
+ name = "example_multi_processor",
+ srcs = [
+ "main.cc",
+ ],
+ tags = [
+ "memory",
+ "ostream",
+ ],
+ deps = [
+ "//api",
+ "//examples/common/foo_library:common_foo_library",
+ "//exporters/memory:in_memory_span_exporter",
+ "//exporters/ostream:ostream_span_exporter",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/CMakeLists.txt
new file mode 100644
index 000000000..a1e4ac9ea
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/CMakeLists.txt
@@ -0,0 +1,7 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include
+ ${CMAKE_SOURCE_DIR}/exporters/memory/include)
+
+add_executable(example_multi_processor main.cc)
+target_link_libraries(
+ example_multi_processor ${CMAKE_THREAD_LIBS_INIT} common_foo_library
+ opentelemetry_trace opentelemetry_exporter_ostream_span)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/README.md b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/README.md
new file mode 100644
index 000000000..c53939762
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/README.md
@@ -0,0 +1,15 @@
+# Multi Processor Trace Example
+
+In this example, the application in `main.cc` initializes and registers a tracer
+provider from the [OpenTelemetry
+SDK](https://github.com/open-telemetry/opentelemetry-cpp). The `TracerProvider`
+is connected to two `processor-exporter` pipelines - for exporting
+simultaneously to `StdoutSpanExporter` and `InMemorySpanExporter`. The
+application then calls a `foo_library` which has been instrumented using the
+[OpenTelemetry
+API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api).
+Resulting telemetry is directed to stdout through the StdoutSpanExporter, and
+saved as a variable (vector of spans) through `InMemorySpanExporter`.
+
+See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
+running the example.
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/main.cc
new file mode 100644
index 000000000..2b722b668
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multi_processor/main.cc
@@ -0,0 +1,89 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_context.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+// Using an exporter that simply dumps span data to stdout.
+#ifdef BAZEL_BUILD
+# include "examples/common/foo_library/foo_library.h"
+#else
+# include "foo_library/foo_library.h"
+#endif
+#include "opentelemetry/exporters/memory/in_memory_span_exporter.h"
+#include "opentelemetry/exporters/ostream/span_exporter.h"
+
+using opentelemetry::exporter::memory::InMemorySpanExporter;
+namespace trace_api = opentelemetry::trace;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace nostd = opentelemetry::nostd;
+
+namespace
+{
+InMemorySpanExporter *initTracer()
+{
+ auto exporter1 = std::unique_ptr<trace_sdk::SpanExporter>(
+ new opentelemetry::exporter::trace::OStreamSpanExporter);
+ auto processor1 = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter1)));
+
+ InMemorySpanExporter *memory_span_exporter = new InMemorySpanExporter();
+ auto exporter2 = std::unique_ptr<trace_sdk::SpanExporter>(memory_span_exporter);
+
+ // fetch the exporter for dumping data later
+
+ auto processor2 = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter2)));
+
+ auto provider = nostd::shared_ptr<trace_sdk::TracerProvider>(
+ new trace_sdk::TracerProvider(std::move(processor1)));
+ provider->AddProcessor(std::move(processor2));
+ // Set the global trace provider
+ trace_api::Provider::SetTracerProvider(std::move(provider));
+
+ return memory_span_exporter;
+}
+
+void dumpSpans(std::vector<std::unique_ptr<trace_sdk::SpanData>> &spans)
+{
+ char span_buf[trace_api::SpanId::kSize * 2];
+ char trace_buf[trace_api::TraceId::kSize * 2];
+ char parent_span_buf[trace_api::SpanId::kSize * 2];
+ std::cout << "\nSpans from memory :" << std::endl;
+
+ for (auto &span : spans)
+ {
+ std::cout << "\n\tSpan: " << std::endl;
+ std::cout << "\t\tName: " << span->GetName() << std::endl;
+ span->GetSpanId().ToLowerBase16(span_buf);
+ span->GetTraceId().ToLowerBase16(trace_buf);
+ span->GetParentSpanId().ToLowerBase16(parent_span_buf);
+ std::cout << "\t\tTraceId: " << std::string(trace_buf, sizeof(trace_buf)) << std::endl;
+ std::cout << "\t\tSpanId: " << std::string(span_buf, sizeof(span_buf)) << std::endl;
+ std::cout << "\t\tParentSpanId: " << std::string(parent_span_buf, sizeof(parent_span_buf))
+ << std::endl;
+
+ std::cout << "\t\tDescription: " << span->GetDescription() << std::endl;
+ std::cout << "\t\tSpan kind:"
+ << static_cast<typename std::underlying_type<trace_api::SpanKind>::type>(
+ span->GetSpanKind())
+ << std::endl;
+ std::cout << "\t\tSpan Status: "
+ << static_cast<typename std::underlying_type<trace_api::StatusCode>::type>(
+ span->GetStatus())
+ << std::endl;
+ }
+}
+} // namespace
+
+int main()
+{
+ // Removing this line will leave the default noop TracerProvider in place.
+ InMemorySpanExporter *memory_span_exporter = initTracer();
+
+ foo_library();
+ auto memory_spans = memory_span_exporter->GetData()->GetSpans();
+ dumpSpans(memory_spans);
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/BUILD
new file mode 100644
index 000000000..5cac7b6d3
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/BUILD
@@ -0,0 +1,12 @@
+cc_binary(
+ name = "example_multithreaded",
+ srcs = [
+ "main.cc",
+ ],
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//exporters/ostream:ostream_span_exporter",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/CMakeLists.txt
new file mode 100644
index 000000000..0721f2e21
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include)
+
+add_executable(example_multithreaded main.cc)
+target_link_libraries(example_multithreaded ${CMAKE_THREAD_LIBS_INIT}
+ opentelemetry_trace opentelemetry_exporter_ostream_span)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/main.cc
new file mode 100644
index 000000000..17efbb8bf
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/multithreaded/main.cc
@@ -0,0 +1,68 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/sdk/resource/resource.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+#include "opentelemetry/trace/scope.h"
+
+// Using an exporter that simply dumps span data to stdout.
+#include "opentelemetry/exporters/ostream/span_exporter.h"
+
+#include <algorithm>
+#include <thread>
+
+namespace trace_api = opentelemetry::trace;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace nostd = opentelemetry::nostd;
+
+namespace
+{
+void initTracer()
+{
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(
+ new opentelemetry::exporter::trace::OStreamSpanExporter);
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider = nostd::shared_ptr<trace_api::TracerProvider>(new trace_sdk::TracerProvider(
+ std::move(processor), opentelemetry::sdk::resource::Resource::Create({})));
+ // Set the global trace provider
+ trace_api::Provider::SetTracerProvider(provider);
+}
+
+nostd::shared_ptr<trace_api::Tracer> get_tracer()
+{
+ auto provider = trace_api::Provider::GetTracerProvider();
+ return provider->GetTracer("foo_library");
+}
+} // namespace
+
+void run_threads()
+{
+ auto thread_span = get_tracer()->StartSpan(__func__);
+
+ std::vector<std::thread> threads;
+ for (int thread_num = 0; thread_num < 5; ++thread_num)
+ {
+ // This shows how one can effectively use Scope objects to correctly
+ // parent spans across threads.
+ threads.push_back(std::thread([=] {
+ trace_api::Scope scope(thread_span);
+ auto thread_span =
+ get_tracer()->StartSpan(std::string("thread ") + std::to_string(thread_num));
+ }));
+ }
+
+ std::for_each(threads.begin(), threads.end(), [](std::thread &th) { th.join(); });
+}
+
+int main()
+{
+ initTracer();
+
+ auto root_span = get_tracer()->StartSpan(__func__);
+ trace_api::Scope scope(root_span);
+
+ run_threads();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/otlp/BUILD
new file mode 100644
index 000000000..795493faa
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/BUILD
@@ -0,0 +1,73 @@
+cc_binary(
+ name = "example_otlp_grpc",
+ srcs = [
+ "grpc_main.cc",
+ ],
+ tags = [
+ "examples",
+ "otlp",
+ "otlp_grpc",
+ ],
+ deps = [
+ "//api",
+ "//examples/common/foo_library:common_foo_library",
+ "//exporters/otlp:otlp_grpc_exporter",
+ "//sdk/src/trace",
+ ],
+)
+
+cc_binary(
+ name = "example_otlp_http",
+ srcs = [
+ "http_main.cc",
+ ],
+ tags = [
+ "examples",
+ "otlp",
+ "otlp_http",
+ ],
+ deps = [
+ "//api",
+ "//examples/common/foo_library:common_foo_library",
+ "//exporters/otlp:otlp_http_exporter",
+ "//sdk/src/trace",
+ ],
+)
+
+cc_binary(
+ name = "example_otlp_http_log",
+ srcs = [
+ "http_log_main.cc",
+ ],
+ tags = [
+ "examples",
+ "otlp",
+ "otlp_http_log",
+ ],
+ deps = [
+ "//api",
+ "//examples/common/logs_foo_library:common_logs_foo_library",
+ "//exporters/otlp:otlp_http_exporter",
+ "//exporters/otlp:otlp_http_log_exporter",
+ "//sdk/src/trace",
+ ],
+)
+
+cc_binary(
+ name = "example_otlp_grpc_log",
+ srcs = [
+ "grpc_log_main.cc",
+ ],
+ tags = [
+ "examples",
+ "otlp",
+ "otlp_grpc_log",
+ ],
+ deps = [
+ "//api",
+ "//examples/common/logs_foo_library:common_logs_foo_library",
+ "//exporters/otlp:otlp_grpc_exporter",
+ "//exporters/otlp:otlp_grpc_log_exporter",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/otlp/CMakeLists.txt
new file mode 100755
index 000000000..52d9846a0
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/CMakeLists.txt
@@ -0,0 +1,40 @@
+include_directories(
+ ${CMAKE_BINARY_DIR}/generated/third_party/opentelemetry-proto
+ ${CMAKE_SOURCE_DIR}/exporters/otlp/include)
+
+if(WITH_OTLP_GRPC)
+ add_executable(example_otlp_grpc grpc_main.cc)
+ target_link_libraries(
+ example_otlp_grpc ${CMAKE_THREAD_LIBS_INIT} common_foo_library
+ opentelemetry_trace opentelemetry_exporter_otlp_grpc gRPC::grpc++)
+ if(WITH_LOGS_PREVIEW)
+ add_executable(example_otlp_grpc_log grpc_log_main.cc)
+ target_link_libraries(
+ example_otlp_grpc_log
+ ${CMAKE_THREAD_LIBS_INIT}
+ common_logs_foo_library
+ opentelemetry_trace
+ opentelemetry_logs
+ opentelemetry_exporter_otlp_grpc
+ opentelemetry_exporter_otlp_grpc_log
+ gRPC::grpc++)
+ endif()
+endif()
+
+if(WITH_OTLP_HTTP)
+ add_executable(example_otlp_http http_main.cc)
+ target_link_libraries(
+ example_otlp_http ${CMAKE_THREAD_LIBS_INIT} common_foo_library
+ opentelemetry_trace opentelemetry_exporter_otlp_http)
+ if(WITH_LOGS_PREVIEW)
+ add_executable(example_otlp_http_log http_log_main.cc)
+ target_link_libraries(
+ example_otlp_http_log
+ ${CMAKE_THREAD_LIBS_INIT}
+ common_logs_foo_library
+ opentelemetry_trace
+ opentelemetry_logs
+ opentelemetry_exporter_otlp_http
+ opentelemetry_exporter_otlp_http_log)
+ endif()
+endif()
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/README.md b/src/jaegertracing/opentelemetry-cpp/examples/otlp/README.md
new file mode 100644
index 000000000..91f86f8f5
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/README.md
@@ -0,0 +1,69 @@
+# OTLP Exporter Example
+
+This is an example of how to use the [OpenTelemetry
+Protocol](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/README.md)
+(OTLP) exporter.
+
+The application in `grpc_main.cc` initializes an `OtlpGrpcExporter` instance,
+the application in `http_main.cc` initializes an `OtlpHttpExporter` instance.
+The application in `http_log_main.cc` initializes an `OtlpHttpLogExporter` instance,
+the application in `grpc_log_main.cc` initializes an `OtlpGrpcLogExporter` instance.
+And they register a tracer provider from the [OpenTelemetry
+SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then
+calls a `foo_library` which has been instrumented using the [OpenTelemetry
+API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api).
+
+To enable TLS authentication for OTLP grpc exporter, SslCredentials can be used
+by specifying the path to client certificate pem file, or the string containing
+this certificate via OtlpGrpcExporterOptions. The path to such a .pem file can be
+provided as a command-line argument alongwith the collector endpoint to the main
+binary invocation above.
+
+Resulting spans are exported to the **OpenTelemetry Collector** using the OTLP
+exporter. The OpenTelemetry Collector can be configured to export to other
+backends (see list of [supported
+backends](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/README.md)).
+
+Follow below command to run the **OpenTelemetry Collector** with OTLP receiver
+in docker which dumps the received data into console. See [Getting
+Started](https://opentelemetry.io/docs/collector/about/) for more information.
+
+Open a terminal window at the root directory of this repo and launch the
+OpenTelemetry Collector with an OTLP receiver by running:
+
+- On Unix based systems use:
+
+```console
+docker run --rm -it -p 4317:4317 -p 4318:4318 -v $(pwd)/examples/otlp:/cfg otel/opentelemetry-collector:0.38.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml
+```
+
+- On Windows use:
+
+```console
+docker run --rm -it -p 4317:4317 -p 4318:4318 -v "%cd%/examples/otlp":/cfg otel/opentelemetry-collector:0.38.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml
+```
+
+Note that the OTLP gRPC and HTTP exporters connects to the Collector at `localhost:4317` and `localhost:4318/v1/traces` respectively. This can be changed with first argument from command-line, for example:
+`./example_otlp_grpc gateway.docker.internal:4317` and
+`./example_otlp_http gateway.docker.internal:4318/v1/traces`.
+
+Once you have the Collector running, see
+[CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
+running the example.
+
+## Additional notes regarding Abseil library
+
+gRPC internally uses a different version of Abseil than OpenTelemetry C++ SDK.
+
+One option to optimize your code is to build the SDK with system-provided
+Abseil library. If you are using CMake, then `-DWITH_ABSEIL=ON` may be passed
+during the build of SDK to reuse the same Abseil library as gRPC. If you are
+using Bazel, then `--@io_opentelemetry_cpp/api:with_abseil=true` may be passed
+to reuse your Abseil library in your project.
+
+If you do not want to pursue the above option, and in case if you run into
+conflict between Abseil library and OpenTelemetry C++ `absl::variant`
+implementation, please include either `grpcpp/grpcpp.h` or
+`opentelemetry/exporters/otlp/otlp_grpc_exporter.h` BEFORE any other API
+headers. This approach efficiently avoids the conflict between the two different
+versions of Abseil.
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_log_main.cc b/src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_log_main.cc
new file mode 100644
index 000000000..9a578c7fb
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_log_main.cc
@@ -0,0 +1,77 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifdef ENABLE_LOGS_PREVIEW
+# include "opentelemetry/exporters/otlp/otlp_grpc_exporter.h"
+# include "opentelemetry/exporters/otlp/otlp_grpc_log_exporter.h"
+# include "opentelemetry/logs/provider.h"
+# include "opentelemetry/sdk/logs/logger_provider.h"
+# include "opentelemetry/sdk/logs/simple_log_processor.h"
+# include "opentelemetry/sdk/trace/simple_processor.h"
+# include "opentelemetry/sdk/trace/tracer_provider.h"
+# include "opentelemetry/trace/provider.h"
+
+# include <string>
+
+# ifdef BAZEL_BUILD
+# include "examples/common/logs_foo_library/foo_library.h"
+# else
+# include "logs_foo_library/foo_library.h"
+# endif
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+namespace otlp = opentelemetry::exporter::otlp;
+namespace logs_sdk = opentelemetry::sdk::logs;
+namespace logs = opentelemetry::logs;
+namespace trace_sdk = opentelemetry::sdk::trace;
+
+namespace
+{
+opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
+void InitTracer()
+{
+ // Create OTLP exporter instance
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new otlp::OtlpGrpcExporter(opts));
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider =
+ nostd::shared_ptr<trace::TracerProvider>(new trace_sdk::TracerProvider(std::move(processor)));
+ // Set the global trace provider
+ trace::Provider::SetTracerProvider(provider);
+}
+
+void InitLogger()
+{
+ // Create OTLP exporter instance
+ auto exporter = std::unique_ptr<logs_sdk::LogExporter>(new otlp::OtlpGrpcLogExporter(opts));
+ auto sdkProvider = std::shared_ptr<logs_sdk::LoggerProvider>(
+ new logs_sdk::LoggerProvider(std::unique_ptr<logs_sdk::LogProcessor>(
+ new logs_sdk::SimpleLogProcessor(std::move(exporter)))));
+ auto apiProvider = nostd::shared_ptr<logs::LoggerProvider>(sdkProvider);
+ auto provider = nostd::shared_ptr<logs::LoggerProvider>(apiProvider);
+ opentelemetry::logs::Provider::SetLoggerProvider(provider);
+}
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ opts.endpoint = argv[1];
+ if (argc > 2)
+ {
+ opts.use_ssl_credentials = true;
+ opts.ssl_credentials_cacert_path = argv[2];
+ }
+ }
+ InitLogger();
+ InitTracer();
+ foo_library();
+}
+#else
+int main()
+{
+ return 0;
+}
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_main.cc b/src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_main.cc
new file mode 100644
index 000000000..2e5eff486
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/grpc_main.cc
@@ -0,0 +1,54 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Make sure to include GRPC exporter first because otherwise Abseil may create
+// ambiguity with `nostd::variant`. See issue:
+// https://github.com/open-telemetry/opentelemetry-cpp/issues/880
+#include "opentelemetry/exporters/otlp/otlp_grpc_exporter.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#ifdef BAZEL_BUILD
+# include "examples/common/foo_library/foo_library.h"
+#else
+# include "foo_library/foo_library.h"
+#endif
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace otlp = opentelemetry::exporter::otlp;
+
+namespace
+{
+opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
+void InitTracer()
+{
+ // Create OTLP exporter instance
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new otlp::OtlpGrpcExporter(opts));
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider =
+ nostd::shared_ptr<trace::TracerProvider>(new trace_sdk::TracerProvider(std::move(processor)));
+ // Set the global trace provider
+ trace::Provider::SetTracerProvider(provider);
+}
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ opts.endpoint = argv[1];
+ if (argc > 2)
+ {
+ opts.use_ssl_credentials = true;
+ opts.ssl_credentials_cacert_path = argv[2];
+ }
+ }
+ // Removing this line will leave the default noop TracerProvider in place.
+ InitTracer();
+
+ foo_library();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/http_log_main.cc b/src/jaegertracing/opentelemetry-cpp/examples/otlp/http_log_main.cc
new file mode 100644
index 000000000..b56dcf5aa
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/http_log_main.cc
@@ -0,0 +1,92 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifdef ENABLE_LOGS_PREVIEW
+# include "opentelemetry/exporters/otlp/otlp_http_exporter.h"
+# include "opentelemetry/exporters/otlp/otlp_http_log_exporter.h"
+# include "opentelemetry/logs/provider.h"
+# include "opentelemetry/sdk/logs/logger_provider.h"
+# include "opentelemetry/sdk/logs/simple_log_processor.h"
+# include "opentelemetry/sdk/trace/simple_processor.h"
+# include "opentelemetry/sdk/trace/tracer_provider.h"
+# include "opentelemetry/trace/provider.h"
+
+# include <string>
+
+# ifdef BAZEL_BUILD
+# include "examples/common/logs_foo_library/foo_library.h"
+# else
+# include "logs_foo_library/foo_library.h"
+# endif
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+namespace otlp = opentelemetry::exporter::otlp;
+namespace logs_sdk = opentelemetry::sdk::logs;
+namespace logs = opentelemetry::logs;
+namespace trace_sdk = opentelemetry::sdk::trace;
+
+namespace
+{
+
+opentelemetry::exporter::otlp::OtlpHttpExporterOptions opts;
+void InitTracer()
+{
+ // Create OTLP exporter instance
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new otlp::OtlpHttpExporter(opts));
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider =
+ nostd::shared_ptr<trace::TracerProvider>(new trace_sdk::TracerProvider(std::move(processor)));
+ // Set the global trace provider
+ trace::Provider::SetTracerProvider(provider);
+}
+
+opentelemetry::exporter::otlp::OtlpHttpLogExporterOptions logger_opts;
+void InitLogger()
+{
+ logger_opts.console_debug = true;
+ // Create OTLP exporter instance
+ auto exporter =
+ std::unique_ptr<logs_sdk::LogExporter>(new otlp::OtlpHttpLogExporter(logger_opts));
+ auto sdkProvider = std::shared_ptr<logs_sdk::LoggerProvider>(
+ new logs_sdk::LoggerProvider(std::unique_ptr<logs_sdk::LogProcessor>(
+ new logs_sdk::SimpleLogProcessor(std::move(exporter)))));
+ auto apiProvider = nostd::shared_ptr<logs::LoggerProvider>(sdkProvider);
+ auto provider = nostd::shared_ptr<logs::LoggerProvider>(apiProvider);
+ opentelemetry::logs::Provider::SetLoggerProvider(provider);
+}
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ opts.url = argv[1];
+ logger_opts.url = argv[1];
+ if (argc > 2)
+ {
+ std::string debug = argv[2];
+ opts.console_debug = debug != "" && debug != "0" && debug != "no";
+ }
+
+ if (argc > 3)
+ {
+ std::string binary_mode = argv[3];
+ if (binary_mode.size() >= 3 && binary_mode.substr(0, 3) == "bin")
+ {
+ opts.content_type = opentelemetry::exporter::otlp::HttpRequestContentType::kBinary;
+ logger_opts.content_type = opentelemetry::exporter::otlp::HttpRequestContentType::kBinary;
+ }
+ }
+ }
+ InitLogger();
+ InitTracer();
+ foo_library();
+}
+#else
+int main()
+{
+ return 0;
+}
+#endif \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/http_main.cc b/src/jaegertracing/opentelemetry-cpp/examples/otlp/http_main.cc
new file mode 100644
index 000000000..8a0b07a14
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/http_main.cc
@@ -0,0 +1,62 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/exporters/otlp/otlp_http_exporter.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#include <string>
+
+#ifdef BAZEL_BUILD
+# include "examples/common/foo_library/foo_library.h"
+#else
+# include "foo_library/foo_library.h"
+#endif
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace otlp = opentelemetry::exporter::otlp;
+
+namespace
+{
+opentelemetry::exporter::otlp::OtlpHttpExporterOptions opts;
+void InitTracer()
+{
+ // Create OTLP exporter instance
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new otlp::OtlpHttpExporter(opts));
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider =
+ nostd::shared_ptr<trace::TracerProvider>(new trace_sdk::TracerProvider(std::move(processor)));
+ // Set the global trace provider
+ trace::Provider::SetTracerProvider(provider);
+}
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ opts.url = argv[1];
+ if (argc > 2)
+ {
+ std::string debug = argv[2];
+ opts.console_debug = debug != "" && debug != "0" && debug != "no";
+ }
+
+ if (argc > 3)
+ {
+ std::string binary_mode = argv[3];
+ if (binary_mode.size() >= 3 && binary_mode.substr(0, 3) == "bin")
+ {
+ opts.content_type = otlp::HttpRequestContentType::kBinary;
+ }
+ }
+ }
+ // Removing this line will leave the default noop TracerProvider in place.
+ InitTracer();
+
+ foo_library();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/otlp/opentelemetry-collector-config/config.dev.yaml b/src/jaegertracing/opentelemetry-cpp/examples/otlp/opentelemetry-collector-config/config.dev.yaml
new file mode 100644
index 000000000..f10252b95
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/otlp/opentelemetry-collector-config/config.dev.yaml
@@ -0,0 +1,24 @@
+exporters:
+ logging:
+ loglevel: DEBUG
+receivers:
+ otlp:
+ protocols:
+ grpc:
+ endpoint: 0.0.0.0:4317
+ http:
+ endpoint: 0.0.0.0:4318
+ cors_allowed_origins:
+ - '*'
+service:
+ pipelines:
+ traces:
+ receivers:
+ - otlp
+ exporters:
+ - logging
+ logs:
+ receivers:
+ - otlp
+ exporters:
+ - logging
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/plugin/CMakeLists.txt
new file mode 100644
index 000000000..081d08b0a
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(load)
+add_subdirectory(plugin)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/BUILD
new file mode 100644
index 000000000..8777c83a9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/BUILD
@@ -0,0 +1,12 @@
+cc_binary(
+ name = "load_plugin",
+ srcs = [
+ "main.cc",
+ ],
+ linkopts = [
+ "-ldl",
+ ],
+ deps = [
+ "//api",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/CMakeLists.txt
new file mode 100644
index 000000000..4677c2494
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_executable(load_plugin_example main.cc)
+target_link_libraries(load_plugin_example opentelemetry_api ${CMAKE_DL_LIBS})
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/main.cc
new file mode 100644
index 000000000..41a04baa4
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/load/main.cc
@@ -0,0 +1,42 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/plugin/dynamic_load.h"
+
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <memory>
+#include <string>
+
+int main(int argc, char *argv[])
+{
+ if (argc != 3)
+ {
+ std::cerr << "Usage: load_plugin <plugin> <config>\n";
+ return -1;
+ }
+ std::string error_message;
+ auto factory = opentelemetry::plugin::LoadFactory(argv[1], error_message);
+ if (factory == nullptr)
+ {
+ std::cerr << "Failed to load opentelemetry plugin: " << error_message << "\n";
+ return -1;
+ }
+ std::ifstream config_in{argv[2]};
+ if (!config_in.good())
+ {
+ std::perror("Failed to open config file");
+ return -1;
+ }
+ std::string config{std::istreambuf_iterator<char>{config_in}, std::istreambuf_iterator<char>{}};
+ auto tracer = factory->MakeTracer(config, error_message);
+ if (tracer == nullptr)
+ {
+ std::cerr << "Failed to make tracer: " << error_message << "\n";
+ return -1;
+ }
+ auto span = tracer->StartSpan("abc");
+ return 0;
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/BUILD
new file mode 100644
index 000000000..a26a0c6e2
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/BUILD
@@ -0,0 +1,12 @@
+cc_binary(
+ name = "example_plugin.so",
+ srcs = [
+ "factory_impl.cc",
+ "tracer.cc",
+ "tracer.h",
+ ],
+ linkshared = 1,
+ deps = [
+ "//api",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/CMakeLists.txt
new file mode 100644
index 000000000..c24a8d1a1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_library(example_plugin SHARED tracer.cc factory_impl.cc)
+target_link_libraries(example_plugin opentelemetry_api)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/factory_impl.cc b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/factory_impl.cc
new file mode 100644
index 000000000..b3bafe705
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/factory_impl.cc
@@ -0,0 +1,49 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/plugin/factory.h"
+#include "opentelemetry/plugin/hook.h"
+#include "tracer.h"
+
+namespace nostd = opentelemetry::nostd;
+namespace plugin = opentelemetry::plugin;
+
+class TracerHandle final : public plugin::TracerHandle
+{
+public:
+ explicit TracerHandle(std::shared_ptr<Tracer> &&tracer) noexcept : tracer_{std::move(tracer)} {}
+
+ // opentelemetry::plugin::TracerHandle
+ Tracer &tracer() const noexcept override { return *tracer_; }
+
+private:
+ std::shared_ptr<Tracer> tracer_;
+};
+
+class FactoryImpl final : public plugin::Factory::FactoryImpl
+{
+public:
+ // opentelemetry::plugin::Factory::FactoryImpl
+ nostd::unique_ptr<plugin::TracerHandle> MakeTracerHandle(
+ nostd::string_view tracer_config,
+ nostd::unique_ptr<char[]> &error_message) const noexcept override
+ {
+ std::shared_ptr<Tracer> tracer{new (std::nothrow) Tracer{""}};
+ if (tracer == nullptr)
+ {
+ return nullptr;
+ }
+ return nostd::unique_ptr<TracerHandle>{new (std::nothrow) TracerHandle{std::move(tracer)}};
+ }
+};
+
+static nostd::unique_ptr<plugin::Factory::FactoryImpl> MakeFactoryImpl(
+ const plugin::LoaderInfo &loader_info,
+ nostd::unique_ptr<char[]> &error_message) noexcept
+{
+ (void)loader_info;
+ (void)error_message;
+ return nostd::unique_ptr<plugin::Factory::FactoryImpl>{new (std::nothrow) FactoryImpl{}};
+}
+
+OPENTELEMETRY_DEFINE_PLUGIN_HOOK(MakeFactoryImpl);
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.cc b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.cc
new file mode 100644
index 000000000..517575c94
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.cc
@@ -0,0 +1,75 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "tracer.h"
+#include "opentelemetry/nostd/unique_ptr.h"
+
+#include <iostream>
+#include <memory>
+
+namespace nostd = opentelemetry::nostd;
+namespace common = opentelemetry::common;
+namespace trace = opentelemetry::trace;
+namespace context = opentelemetry::context;
+
+namespace
+{
+class Span final : public trace::Span
+{
+public:
+ Span(std::shared_ptr<Tracer> &&tracer,
+ nostd::string_view name,
+ const common::KeyValueIterable & /*attributes*/,
+ const trace::SpanContextKeyValueIterable & /*links*/,
+ const trace::StartSpanOptions & /*options*/) noexcept
+ : tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()}
+ {
+ std::cout << "StartSpan: " << name << "\n";
+ }
+
+ ~Span() { std::cout << "~Span\n"; }
+
+ // opentelemetry::trace::Span
+ void SetAttribute(nostd::string_view /*name*/,
+ const common::AttributeValue & /*value*/) noexcept override
+ {}
+
+ void AddEvent(nostd::string_view /*name*/) noexcept override {}
+
+ void AddEvent(nostd::string_view /*name*/,
+ common::SystemTimestamp /*timestamp*/) noexcept override
+ {}
+
+ void AddEvent(nostd::string_view /*name*/,
+ common::SystemTimestamp /*timestamp*/,
+ const common::KeyValueIterable & /*attributes*/) noexcept override
+ {}
+
+ void SetStatus(trace::StatusCode /*code*/, nostd::string_view /*description*/) noexcept override
+ {}
+
+ void UpdateName(nostd::string_view /*name*/) noexcept override {}
+
+ void End(const trace::EndSpanOptions & /*options*/) noexcept override {}
+
+ bool IsRecording() const noexcept override { return true; }
+
+ trace::SpanContext GetContext() const noexcept override { return span_context_; }
+
+private:
+ std::shared_ptr<Tracer> tracer_;
+ std::string name_;
+ trace::SpanContext span_context_;
+};
+} // namespace
+
+Tracer::Tracer(nostd::string_view /*output*/) {}
+
+nostd::shared_ptr<trace::Span> Tracer::StartSpan(nostd::string_view name,
+ const common::KeyValueIterable &attributes,
+ const trace::SpanContextKeyValueIterable &links,
+ const trace::StartSpanOptions &options) noexcept
+{
+ return nostd::shared_ptr<trace::Span>{
+ new (std::nothrow) Span{this->shared_from_this(), name, attributes, links, options}};
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.h b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.h
new file mode 100644
index 000000000..af2a4c5e9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/plugin/plugin/tracer.h
@@ -0,0 +1,26 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#pragma once
+
+#include <memory>
+
+#include "opentelemetry/trace/tracer.h"
+
+class Tracer final : public opentelemetry::trace::Tracer,
+ public std::enable_shared_from_this<Tracer>
+{
+public:
+ explicit Tracer(opentelemetry::nostd::string_view output);
+
+ // opentelemetry::trace::Tracer
+ opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> StartSpan(
+ opentelemetry::nostd::string_view name,
+ const opentelemetry::common::KeyValueIterable & /*attributes*/,
+ const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/,
+ const opentelemetry::trace::StartSpanOptions & /*options */) noexcept override;
+
+ void ForceFlushWithMicroseconds(uint64_t /*timeout*/) noexcept override {}
+
+ void CloseWithMicroseconds(uint64_t /*timeout*/) noexcept override {}
+};
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/prometheus/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/BUILD
new file mode 100644
index 000000000..edbfde61e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/BUILD
@@ -0,0 +1,14 @@
+cc_binary(
+ name = "prometheus_example",
+ srcs = [
+ "main.cc",
+ ],
+ linkopts = ["-pthread"],
+ tags = ["ostream"],
+ deps = [
+ "//api",
+ "//examples/common/metrics_foo_library:common_metrics_foo_library",
+ "//exporters/prometheus:prometheus_exporter",
+ "//sdk/src/metrics",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/prometheus/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/CMakeLists.txt
new file mode 100644
index 000000000..b377920de
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/CMakeLists.txt
@@ -0,0 +1,5 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/prometheus/include)
+add_executable(prometheus_example main.cc)
+target_link_libraries(
+ prometheus_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics
+ prometheus_exporter opentelemetry_resources common_metrics_foo_library)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/prometheus/README.md b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/README.md
new file mode 100644
index 000000000..d7e284a0e
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/README.md
@@ -0,0 +1,208 @@
+# Getting Started with Prometheus and Grafana
+
+- [Export metrics from the application](#export-metrics-from-the-application)
+ - [Check results in the browser](#check-results-in-the-browser)
+- [Collect metrics using Prometheus](#collect-metrics-using-prometheus)
+ - [Configuration](#configuration)
+ - [Start Prometheus](#start-prometheus)
+ - [View results in Prometheus](#view-results-in-prometheus)
+- [Explore metrics using Grafana](#explore-metrics-using-grafana)
+- [Learn more](#learn-more)
+
+## Export metrics from the application
+
+It is highly recommended to go over the [ostream-metrics](../metrics_simple/README.md)
+doc before following along this document.
+
+Run the application with:
+
+```sh
+bazel run //examples/prometheus:prometheus_example
+```
+
+The main difference between the [ostream-metrics](../metrics_simple/README.md)
+example with this one is that the line below is replaced:
+
+```cpp
+std::unique_ptr<metric_sdk::MetricExporter> exporter{
+ new exportermetrics::OStreamMetricExporter};
+
+```
+
+with
+
+```cpp
+std::unique_ptr<metrics_sdk::MetricExporter> exporter{
+ new metrics_exporter::PrometheusExporter(opts)};
+```
+
+OpenTelemetry `PrometheusExporter` will export
+data via the endpoint defined by
+`metrics_exporter::PrometheusExporterOptions::url`,
+which is `http://localhost:9464/` by default.
+
+```mermaid
+graph LR
+
+subgraph SDK
+ MeterProvider
+ MetricReader[PeriodicExportingMetricReader]
+ PrometheusExporter["PrometheusExporter<br/>(http://localhost:9464/)"]
+end
+
+subgraph API
+ Instrument["Meter(#quot;prometheus_metric_example#quot;, #quot;1.0#quot;)<br/>Histogram(#quot;prometheus_metric_example_histogram#quot;)"]
+end
+
+Instrument --> | Measurements | MeterProvider
+
+MeterProvider --> | Metrics | MetricReader --> | Pull | PrometheusExporter
+```
+
+Also, for our learning purpose, we use a while-loop to keep recoring random
+values until the program stops.
+
+```cpp
+while (true)
+{
+ double val = (rand() % 700) + 1.1;
+ std::map<std::string, std::string> labels = get_random_attr();
+ auto labelkv = opentelemetry::common::KeyValueIterableView<decltype(labels)>{labels};
+ histogram_counter->Record(val, labelkv, context);
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+}
+```
+
+### Check results in the browser
+
+Start the application and keep it running. Now we should be able to see the
+metrics at [http://localhost:9464/metrics](http://localhost:9464/metrics) from a
+web browser:
+
+![Browser UI](https://user-images.githubusercontent.com/71217171/168492500-12bd1c99-33ab-4515-a294-17bc349b5d13.png)
+
+Now, we understand how we can configure `PrometheusExporter` to export metrics.
+Next, we are going to learn about how to use Prometheus to collect the metrics.
+
+## Collect metrics using Prometheus
+
+Follow the [first steps](https://prometheus.io/docs/introduction/first_steps/)
+to download the [latest release](https://prometheus.io/download/) of Prometheus.
+It is also possible to use `prom/prometheus` docker image.
+
+### Configuration
+
+After downloading, extract it to a local location that's easy to
+access. We will find the default Prometheus configuration YAML file in the
+folder, named `prometheus.yml`.
+
+```yaml
+global:
+ scrape_interval: 5s
+ scrape_timeout: 2s
+ evaluation_interval: 5s
+alerting:
+ alertmanagers:
+ - follow_redirects: true
+ scheme: http
+ timeout: 5s
+ api_version: v2
+ static_configs:
+ - targets: [localhost:9464]
+scrape_configs:
+ - job_name: otel
+ static_configs:
+ - targets: ['localhost:9464']
+```
+
+### Start Prometheus
+
+Follow the instructions from
+[starting-prometheus](https://prometheus.io/docs/introduction/first_steps/#starting-prometheus)
+to start the Prometheus server and verify it has been started successfully.
+
+Please note that we will need pass in `prometheus.yml` file as the argument
+or mount as volume:
+
+```console
+./prometheus --config.file=prometheus.yml
+# OR:
+docker run -p 9090:9090 -v $(pwd):/etc/prometheus --network="host" prom/prometheus
+```
+
+### View results in Prometheus
+
+To use the graphical interface for viewing our metrics with Prometheus, navigate
+to [http://localhost:9090/graph](http://localhost:9090/graph),
+and type `prometheus_metric_example_bucket` in the expression bar of the UI;
+finally, click the execute button.
+
+We should be able to see the following chart from the browser:
+
+![Prometheus UI](https://user-images.githubusercontent.com/71217171/168492437-f9769db1-6f9e-49c6-8ef0-85f5e1188ba0.png)
+
+From the legend, we can see that the `instance` name and the `job` name are the
+values we have set in `prometheus.yml`.
+
+Congratulations!
+
+Now we know how to configure Prometheus server and deploy OpenTelemetry
+`PrometheusExporter` to export our metrics. Next, we are going to explore a tool
+called Grafana, which has powerful visualizations for the metrics.
+
+## Explore metrics using Grafana
+
+[Install Grafana](https://grafana.com/docs/grafana/latest/installation/).
+
+Start the standalone Grafana server (`grafana-server.exe` or
+`./bin/grafana-server`, depending on the operating system). Then, use the
+browser to navigate to [http://localhost:3000/](http://localhost:3000/).
+It is also possible to run `grafana/grafana` container:
+
+```sh
+docker run -d -p 3000:3000 --network="host" grafana/grafana
+```
+
+Follow the instructions in the Grafana getting started
+[doc](https://grafana.com/docs/grafana/latest/getting-started/getting-started/#step-2-log-in)
+to log in.
+
+After successfully logging in, click on the Configuration icon
+on the panel at the left hand side, and click on Prometheus.
+Type in the default endpoint of Prometheus as suggested by the UI
+as the value for the URI.
+
+```console
+http://localhost:9090
+```
+
+Then, click on the Explore icon on the left panel of
+the website - we should be able to write some queries to explore our metrics
+now!
+
+Feel free to find some handy PromQL
+[here](https://promlabs.com/promql-cheat-sheet/).
+
+![Grafana
+UI](https://user-images.githubusercontent.com/71217171/168492482-047a4429-4854-4b3c-a2dd-4d75362090d5.png)
+
+```mermaid
+graph TD
+
+subgraph Prometheus
+ PrometheusScraper
+ PrometheusDatabase
+end
+
+PrometheusExporter["PrometheusExporter<br/>(listening at #quot;http://localhost:9464/#quot;)"] -->|HTTP GET| PrometheusScraper{{"Prometheus scraper<br/>(polling #quot;http://localhost:9464/metrics#quot; every 5 seconds)"}}
+PrometheusScraper --> PrometheusDatabase[("Prometheus TSDB (time series database)")]
+PrometheusDatabase -->|http://localhost:9090/graph| PrometheusUI["Browser<br/>(Prometheus Dashboard)"]
+PrometheusDatabase -->|http://localhost:9090/api/| Grafana[Grafana Server]
+Grafana -->|http://localhost:3000/dashboard| GrafanaUI["Browser<br/>(Grafana Dashboard)"]
+```
+
+## Learn more
+
+- [What is Prometheus?](https://prometheus.io/docs/introduction/overview/)
+- [Grafana support for
+ Prometheus](https://prometheus.io/docs/visualization/grafana/#creating-a-prometheus-graph)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/prometheus/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/main.cc
new file mode 100644
index 000000000..77a648f55
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/main.cc
@@ -0,0 +1,118 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef ENABLE_METRICS_PREVIEW
+# include <memory>
+# include <thread>
+# include "opentelemetry/exporters/prometheus/exporter.h"
+# include "opentelemetry/metrics/provider.h"
+# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h"
+# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h"
+# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h"
+# include "opentelemetry/sdk/metrics/meter.h"
+# include "opentelemetry/sdk/metrics/meter_provider.h"
+
+# ifdef BAZEL_BUILD
+# include "examples/common/metrics_foo_library/foo_library.h"
+# else
+# include "metrics_foo_library/foo_library.h"
+# endif
+
+namespace metrics_sdk = opentelemetry::sdk::metrics;
+namespace nostd = opentelemetry::nostd;
+namespace common = opentelemetry::common;
+namespace metrics_exporter = opentelemetry::exporter::metrics;
+namespace metrics_api = opentelemetry::metrics;
+
+namespace
+{
+
+void initMetrics(const std::string &name, const std::string &addr)
+{
+ metrics_exporter::PrometheusExporterOptions opts;
+ if (!addr.empty())
+ {
+ opts.url = addr;
+ }
+ std::puts("PrometheusExporter example program running ...");
+
+ std::unique_ptr<metrics_sdk::MetricExporter> exporter{
+ new metrics_exporter::PrometheusExporter(opts)};
+
+ std::string version{"1.2.0"};
+ std::string schema{"https://opentelemetry.io/schemas/1.2.0"};
+
+ // Initialize and set the global MeterProvider
+ metrics_sdk::PeriodicExportingMetricReaderOptions options;
+ options.export_interval_millis = std::chrono::milliseconds(1000);
+ options.export_timeout_millis = std::chrono::milliseconds(500);
+ std::unique_ptr<metrics_sdk::MetricReader> reader{
+ new metrics_sdk::PeriodicExportingMetricReader(std::move(exporter), options)};
+ auto provider = std::shared_ptr<metrics_api::MeterProvider>(new metrics_sdk::MeterProvider());
+ auto p = std::static_pointer_cast<metrics_sdk::MeterProvider>(provider);
+ p->AddMetricReader(std::move(reader));
+
+ // counter view
+ std::string counter_name = name + "_counter";
+ std::unique_ptr<metrics_sdk::InstrumentSelector> instrument_selector{
+ new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kCounter, counter_name)};
+ std::unique_ptr<metrics_sdk::MeterSelector> meter_selector{
+ new metrics_sdk::MeterSelector(name, version, schema)};
+ std::unique_ptr<metrics_sdk::View> sum_view{
+ new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kSum}};
+ p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view));
+
+ // histogram view
+ std::string histogram_name = name + "_histogram";
+ std::unique_ptr<metrics_sdk::InstrumentSelector> histogram_instrument_selector{
+ new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kHistogram, histogram_name)};
+ std::unique_ptr<metrics_sdk::MeterSelector> histogram_meter_selector{
+ new metrics_sdk::MeterSelector(name, version, schema)};
+ std::unique_ptr<metrics_sdk::View> histogram_view{
+ new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kHistogram}};
+ p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector),
+ std::move(histogram_view));
+ metrics_api::Provider::SetMeterProvider(provider);
+}
+} // namespace
+
+int main(int argc, char **argv)
+{
+ std::string example_type;
+ std::string addr{"localhost:8080"};
+ if (argc == 1)
+ {
+ std::puts("usage: $prometheus_example <example type> <url>");
+ }
+
+ if (argc >= 2)
+ {
+ example_type = argv[1];
+ }
+ if (argc > 2)
+ {
+ addr = argv[2];
+ }
+
+ std::string name{"prometheus_metric_example"};
+ initMetrics(name, addr);
+
+ if (example_type == "counter")
+ {
+ foo_library::counter_example(name);
+ }
+ else if (example_type == "histogram")
+ {
+ foo_library::histogram_example(name);
+ }
+ else
+ {
+ std::thread counter_example{&foo_library::counter_example, name};
+ std::thread histogram_example{&foo_library::histogram_example, name};
+ counter_example.join();
+ histogram_example.join();
+ }
+}
+#else
+int main() {}
+#endif
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/prometheus/prometheus.yml b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/prometheus.yml
new file mode 100644
index 000000000..17c42fda3
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/prometheus.yml
@@ -0,0 +1,16 @@
+global:
+ scrape_interval: 5s
+ scrape_timeout: 2s
+ evaluation_interval: 5s
+alerting:
+ alertmanagers:
+ - follow_redirects: true
+ scheme: http
+ timeout: 5s
+ api_version: v2
+ static_configs:
+ - targets: [localhost:9464]
+scrape_configs:
+ - job_name: otel
+ static_configs:
+ - targets: ['localhost:9464'] \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/prometheus/run.sh b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/run.sh
new file mode 100644
index 000000000..412c6ef45
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/prometheus/run.sh
@@ -0,0 +1 @@
+docker run -p 9090:9090 -v $(pwd):/etc/prometheus --network="host" prom/prometheus \ No newline at end of file
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/simple/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/simple/BUILD
new file mode 100644
index 000000000..6a5a76646
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/simple/BUILD
@@ -0,0 +1,15 @@
+cc_binary(
+ name = "example_simple",
+ srcs = [
+ "main.cc",
+ ],
+ tags = [
+ "examples",
+ "ostream",
+ ],
+ deps = [
+ "//api",
+ "//examples/common/foo_library:common_foo_library",
+ "//exporters/ostream:ostream_span_exporter",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/simple/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/simple/CMakeLists.txt
new file mode 100644
index 000000000..4368039c1
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/simple/CMakeLists.txt
@@ -0,0 +1,6 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include)
+
+add_executable(example_simple main.cc)
+target_link_libraries(
+ example_simple ${CMAKE_THREAD_LIBS_INIT} common_foo_library
+ opentelemetry_trace opentelemetry_exporter_ostream_span)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/simple/README.md b/src/jaegertracing/opentelemetry-cpp/examples/simple/README.md
new file mode 100644
index 000000000..b3c449c53
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/simple/README.md
@@ -0,0 +1,12 @@
+
+# Simple Trace Example
+
+In this example, the application in `main.cc` initializes and registers a tracer
+provider from the [OpenTelemetry
+SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then
+calls a `foo_library` which has been instrumented using the [OpenTelemetry
+API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api).
+Resulting telemetry is directed to stdout through the StdoutSpanExporter.
+
+See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
+running the example.
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/simple/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/simple/main.cc
new file mode 100644
index 000000000..d022e5c23
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/simple/main.cc
@@ -0,0 +1,41 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+// Using an exporter that simply dumps span data to stdout.
+#ifdef BAZEL_BUILD
+# include "examples/common/foo_library/foo_library.h"
+#else
+# include "foo_library/foo_library.h"
+#endif
+#include "opentelemetry/exporters/ostream/span_exporter.h"
+
+namespace trace_api = opentelemetry::trace;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace nostd = opentelemetry::nostd;
+namespace
+{
+void initTracer()
+{
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(
+ new opentelemetry::exporter::trace::OStreamSpanExporter);
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider = nostd::shared_ptr<trace_api::TracerProvider>(
+ new trace_sdk::TracerProvider(std::move(processor)));
+
+ // Set the global trace provider
+ trace_api::Provider::SetTracerProvider(provider);
+}
+} // namespace
+
+int main()
+{
+ // Removing this line will leave the default noop TracerProvider in place.
+ initTracer();
+
+ foo_library();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/zipkin/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/examples/zipkin/CMakeLists.txt
new file mode 100644
index 000000000..f55f363d7
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/zipkin/CMakeLists.txt
@@ -0,0 +1,6 @@
+include_directories(${CMAKE_SOURCE_DIR}/exporters/zipkin/include)
+
+add_executable(example_zipkin main.cc)
+target_link_libraries(
+ example_zipkin ${CMAKE_THREAD_LIBS_INIT} common_foo_library
+ opentelemetry_trace opentelemetry_exporter_zipkin_trace)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/zipkin/README.md b/src/jaegertracing/opentelemetry-cpp/examples/zipkin/README.md
new file mode 100644
index 000000000..17d325ecb
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/zipkin/README.md
@@ -0,0 +1,32 @@
+# Zipkin Exporter Example
+
+This is an example of how to use the Zipkin exporter.
+
+The application in `main.cc` initializes an `ZipkinExporter` instance and uses
+it to register a tracer provider from the [OpenTelemetry
+SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then
+calls a `foo_library` which has been instrumented using the [OpenTelemetry
+API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api).
+
+Resulting spans are exported to the Zipkin server using the Zipkin exporter.
+
+Note that the Zipkin exporter connects to the server at `localhost:9411` by
+default.
+
+## Running Zipkin server locally
+
+The quick way to run the Zipkin server is using Docker container :
+
+``console
+
+$ docker run -d -p 9411:9411 openzipkin/zipkin
+
+``
+
+## Running Zipkin example
+
+Build this example using instructions in [INSTALL.md](../../INSTALL.md).
+
+## Viewing the traces
+
+Please visit the Zipkin UI endpoint `http://localhost:9411`
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/zipkin/main.cc b/src/jaegertracing/opentelemetry-cpp/examples/zipkin/main.cc
new file mode 100644
index 000000000..352114749
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/zipkin/main.cc
@@ -0,0 +1,49 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+#include "opentelemetry/exporters/zipkin/zipkin_exporter.h"
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#ifdef BAZEL_BUILD
+# include "examples/common/foo_library/foo_library.h"
+#else
+# include "foo_library/foo_library.h"
+#endif
+
+namespace trace = opentelemetry::trace;
+namespace nostd = opentelemetry::nostd;
+namespace trace_sdk = opentelemetry::sdk::trace;
+namespace zipkin = opentelemetry::exporter::zipkin;
+namespace resource = opentelemetry::sdk::resource;
+
+namespace
+{
+zipkin::ZipkinExporterOptions opts;
+void InitTracer()
+{
+ // Create zipkin exporter instance
+ resource::ResourceAttributes attributes = {{"service.name", "zipkin_demo_service"}};
+ auto resource = resource::Resource::Create(attributes);
+ auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(new zipkin::ZipkinExporter(opts));
+ auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(
+ new trace_sdk::SimpleSpanProcessor(std::move(exporter)));
+ auto provider = nostd::shared_ptr<trace::TracerProvider>(
+ new trace_sdk::TracerProvider(std::move(processor), resource));
+ // Set the global trace provider
+ trace::Provider::SetTracerProvider(provider);
+}
+} // namespace
+
+int main(int argc, char *argv[])
+{
+ if (argc == 2)
+ {
+ opts.endpoint = argv[1];
+ }
+ // Removing this line will leave the default noop TracerProvider in place.
+ InitTracer();
+
+ foo_library();
+}
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/zpages/BUILD b/src/jaegertracing/opentelemetry-cpp/examples/zpages/BUILD
new file mode 100644
index 000000000..4200398c9
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/zpages/BUILD
@@ -0,0 +1,32 @@
+# Copyright 2020, OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package(default_visibility = ["//visibility:public"])
+
+cc_binary(
+ name = "zpages_example",
+ srcs = [
+ "zpages_example.cc",
+ ],
+ linkopts = select({
+ "//bazel:windows": [],
+ "//conditions:default": ["-pthread"],
+ }),
+ tags = ["examples"],
+ deps = [
+ "//ext:headers",
+ "//ext/src/zpages",
+ "//sdk/src/trace",
+ ],
+)
diff --git a/src/jaegertracing/opentelemetry-cpp/examples/zpages/zpages_example.cc b/src/jaegertracing/opentelemetry-cpp/examples/zpages/zpages_example.cc
new file mode 100644
index 000000000..2691a7315
--- /dev/null
+++ b/src/jaegertracing/opentelemetry-cpp/examples/zpages/zpages_example.cc
@@ -0,0 +1,60 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+/**
+ * This is a basic example for zpages that helps users get familiar with how to
+ * use this feature in OpenTelemetery
+ */
+#include <chrono>
+#include <iostream>
+#include <string>
+
+#include "opentelemetry/ext/zpages/zpages.h" // Required file include for zpages
+
+using opentelemetry::common::SteadyTimestamp;
+namespace trace_api = opentelemetry::trace;
+
+int main(int argc, char *argv[])
+{
+
+ /**
+ * The following line initializes zPages and starts a webserver at
+ * http://localhost:30000/tracez/ where spans that are created in the application
+ * can be viewed.
+ * Note that the webserver is destroyed after the application ends execution.
+ */
+ ZPages::Initialize();
+ auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("");
+
+ std::cout << "This example for zPages creates a few types of spans and then "
+ << "creates a span every second for the duration of the application"
+ << "\n";
+
+ // Error span
+ std::map<std::string, opentelemetry::common::AttributeValue> attribute_map;
+ attribute_map["completed_search_for"] = "Unknown user";
+ tracer->StartSpan("find user", attribute_map)
+ ->SetStatus(trace_api::StatusCode::kError, "User not found");
+
+ // Long time duration span
+ std::map<std::string, opentelemetry::common::AttributeValue> attribute_map2;
+ attribute_map2["completed_search_for"] = "John Doe";
+ trace_api::StartSpanOptions start;
+ start.start_steady_time = SteadyTimestamp(nanoseconds(1));
+ trace_api::EndSpanOptions end;
+ end.end_steady_time = SteadyTimestamp(nanoseconds(1000000000000));
+ tracer->StartSpan("find user", attribute_map2, start)->End(end);
+
+ // Running(deadlock) span
+ std::map<std::string, opentelemetry::common::AttributeValue> attribute_map3;
+ attribute_map3["searching_for"] = "Deleted user";
+ auto running_span = tracer->StartSpan("find user", attribute_map3);
+
+ // Create a completed span every second till user stops the loop
+ std::cout << "Presss CTRL+C to stop...\n";
+ while (true)
+ {
+ std::this_thread::sleep_for(seconds(1));
+ tracer->StartSpan("ping user")->End();
+ }
+}