diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7d5453f66d..dcb04ccf4e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(plugin) +add_subdirectory(simple) diff --git a/examples/simple/BUILD b/examples/simple/BUILD new file mode 100644 index 0000000000..34583e2eac --- /dev/null +++ b/examples/simple/BUILD @@ -0,0 +1,25 @@ +cc_library( + name = "foo_library", + srcs = [ + "foo_library/foo_library.cc", + ], + hdrs = [ + "foo_library/foo_library.h", + ], + deps = [ + "//api", + ], +) + +cc_binary( + name = "example_simple", + srcs = [ + "main.cc", + "stdout_exporter.h", + ], + deps = [ + ":foo_library", + "//api", + "//sdk/src/trace", + ], +) diff --git a/examples/simple/CMakeLists.txt b/examples/simple/CMakeLists.txt new file mode 100644 index 0000000000..4b0ab35f74 --- /dev/null +++ b/examples/simple/CMakeLists.txt @@ -0,0 +1,6 @@ +add_library(foo_library foo_library/foo_library.cc) +target_link_libraries(foo_library ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + +add_executable(example_simple main.cc) +target_link_libraries(example_simple ${CMAKE_THREAD_LIBS_INIT} foo_library + opentelemetry_trace) diff --git a/examples/simple/README.md b/examples/simple/README.md new file mode 100644 index 0000000000..18d8d9bb34 --- /dev/null +++ b/examples/simple/README.md @@ -0,0 +1,25 @@ + +## Building and Running the Simple Trace Example + +This example sets up a tracer in the main application then uses a library that is instrumented with Open Telemetry. All telemetry output is directed to stdout. + +Install Bazel version 1.2.0 by following the steps listed at https://docs.bazel.build/versions/master/install.html + +Clone or fork the Open Telemetry C++ repository: + +```sh +git clone https://github.com/open-telemetry/opentelemetry-cpp.git +``` + +Build the example from the root of the opentelemetry-cpp directory using Bazel: + +```sh +cd opentelemetry-cpp/ +bazel build //examples/simple:example_simple +``` + +Run the resulting executable to see telemetry from the application as it calls the instrumented library. + +```sh +bazel-bin/examples/simple/example_simple +``` \ No newline at end of file diff --git a/examples/simple/foo_library/foo_library.cc b/examples/simple/foo_library/foo_library.cc new file mode 100644 index 0000000000..b92de2397a --- /dev/null +++ b/examples/simple/foo_library/foo_library.cc @@ -0,0 +1,36 @@ +#include "opentelemetry/trace/provider.h" + +namespace trace = opentelemetry::trace; +namespace nostd = opentelemetry::nostd; + +namespace +{ +nostd::shared_ptr get_tracer() +{ + // Retrieve the global TraceProvider specific in main + auto provider = trace::Provider::GetTracerProvider(); + // Return a Tracer object + return provider->GetTracer("foo_library"); +} + +void f1() +{ + // Create a span using the Tracer returned by the get_tracer() function + auto span = get_tracer()->StartSpan("f1"); +} + +void f2() +{ + auto span = get_tracer()->StartSpan("f2"); + + f1(); + f1(); +} +} // namespace + +void foo_library() +{ + auto span = get_tracer()->StartSpan("library"); + + f2(); +} diff --git a/examples/simple/foo_library/foo_library.h b/examples/simple/foo_library/foo_library.h new file mode 100644 index 0000000000..7ac75c0e50 --- /dev/null +++ b/examples/simple/foo_library/foo_library.h @@ -0,0 +1,3 @@ +#pragma once + +void foo_library(); diff --git a/examples/simple/main.cc b/examples/simple/main.cc new file mode 100644 index 0000000000..bea7a51819 --- /dev/null +++ b/examples/simple/main.cc @@ -0,0 +1,36 @@ +#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. +#include "stdout_exporter.h" + +#include "foo_library/foo_library.h" + +namespace +{ +void initTracer() +{ + // Specify the exporter: StdoutExporter in this case simply passes all output from the span + // processor to stdout + auto exporter = std::unique_ptr(new StdoutExporter); + // Specify the Span Processor: SimpleSpanProcessor forwards all completed spans directly to the + // exporter + auto processor = std::shared_ptr(new sdktrace::SimpleSpanProcessor( + std::move(exporter))); // Creating a Span Processor given the StdoutExporter defined earlier + // Initialize a trace provider with the Span Processor instance defined above + auto provider = nostd::shared_ptr(new sdktrace::TracerProvider(processor)); + // Set global trace provider + trace::Provider::SetTracerProvider(provider); +} +} // namespace + +int main() +{ + // Removing this line will leave OT initialized with the default noop + // tracer, thus being effectively deactivated. + initTracer(); + + // Call the instrumented library + foo_library(); +} diff --git a/examples/simple/stdout_exporter.h b/examples/simple/stdout_exporter.h new file mode 100644 index 0000000000..6a58c5b8d6 --- /dev/null +++ b/examples/simple/stdout_exporter.h @@ -0,0 +1,52 @@ +#pragma once + +#include "opentelemetry/sdk/trace/exporter.h" +#include "opentelemetry/sdk/trace/span_data.h" + +#include + +namespace trace = opentelemetry::trace; +namespace nostd = opentelemetry::nostd; +namespace sdktrace = opentelemetry::sdk::trace; + +class StdoutExporter final : public sdktrace::SpanExporter +{ + std::unique_ptr MakeRecordable() noexcept + { + return std::unique_ptr(new sdktrace::SpanData); + } + + sdktrace::ExportResult Export( + const nostd::span> &spans) noexcept + { + for (auto &recordable : spans) + { + auto span = std::unique_ptr( + static_cast(recordable.release())); + + if (span != nullptr) + { + char trace_id[32] = {0}; + char span_id[16] = {0}; + char parent_span_id[16] = {0}; + + span->GetTraceId().ToLowerBase16(trace_id); + span->GetSpanId().ToLowerBase16(span_id); + span->GetParentSpanId().ToLowerBase16(parent_span_id); + + std::cout << "{" + << "\n name : " << span->GetName() + << "\n trace_id : " << std::string(trace_id, 32) + << "\n span_id : " << std::string(span_id, 16) + << "\n parent_span_id: " << std::string(parent_span_id, 16) + << "\n start : " << span->GetStartTime().time_since_epoch().count() + << "\n duration : " << span->GetDuration().count() << "\n}" + << "\n"; + } + } + + return sdktrace::ExportResult::kSuccess; + } + + void Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept {} +}; diff --git a/sdk/include/opentelemetry/sdk/trace/exporter.h b/sdk/include/opentelemetry/sdk/trace/exporter.h index d517c572b2..ec5473edb8 100644 --- a/sdk/include/opentelemetry/sdk/trace/exporter.h +++ b/sdk/include/opentelemetry/sdk/trace/exporter.h @@ -48,7 +48,8 @@ class SpanExporter * @param spans a span of unique pointers to span recordables */ virtual ExportResult Export( - nostd::span> &spans) noexcept = 0; + const nostd::span> + &spans) noexcept = 0; /** * Shut down the exporter. diff --git a/sdk/src/trace/simple_processor.h b/sdk/include/opentelemetry/sdk/trace/simple_processor.h similarity index 100% rename from sdk/src/trace/simple_processor.h rename to sdk/include/opentelemetry/sdk/trace/simple_processor.h diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 322d2fcb59..d78fed02fc 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -43,7 +43,7 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider private: opentelemetry::sdk::AtomicSharedPtr processor_; - opentelemetry::nostd::shared_ptr tracer_; + std::shared_ptr tracer_; }; } // namespace trace } // namespace sdk diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 18e3dc99f9..3268207510 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -13,7 +13,7 @@ opentelemetry::nostd::shared_ptr TracerProvider::G nostd::string_view library_name, nostd::string_view library_version) noexcept { - return tracer_; + return opentelemetry::nostd::shared_ptr(tracer_); } void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept diff --git a/sdk/test/trace/simple_processor_test.cc b/sdk/test/trace/simple_processor_test.cc index ddeba25fe6..b4819aa0ae 100644 --- a/sdk/test/trace/simple_processor_test.cc +++ b/sdk/test/trace/simple_processor_test.cc @@ -1,4 +1,4 @@ -#include "src/trace/simple_processor.h" +#include "opentelemetry/sdk/trace/simple_processor.h" #include "opentelemetry/nostd/span.h" #include "opentelemetry/sdk/trace/span_data.h" @@ -23,7 +23,7 @@ class MockSpanExporter final : public SpanExporter } ExportResult Export( - opentelemetry::nostd::span> &spans) noexcept override + const opentelemetry::nostd::span> &spans) noexcept override { for (auto &span : spans) { diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index 8168aeb6ba..90dbe7c747 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -1,6 +1,6 @@ #include "opentelemetry/sdk/trace/tracer_provider.h" +#include "opentelemetry/sdk/trace/simple_processor.h" #include "opentelemetry/sdk/trace/tracer.h" -#include "src/trace/simple_processor.h" #include diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index 99a18ba99d..f1195b3feb 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -1,6 +1,6 @@ #include "opentelemetry/sdk/trace/tracer.h" +#include "opentelemetry/sdk/trace/simple_processor.h" #include "opentelemetry/sdk/trace/span_data.h" -#include "src/trace/simple_processor.h" #include @@ -22,7 +22,7 @@ class MockSpanExporter final : public SpanExporter } ExportResult Export( - opentelemetry::nostd::span> &recordables) noexcept override + const opentelemetry::nostd::span> &recordables) noexcept override { for (auto &recordable : recordables) {