diff options
Diffstat (limited to '')
-rw-r--r-- | example/CMakeLists.txt | 2 | ||||
-rw-r--r-- | example/dynamic_load/CMakeLists.txt | 4 | ||||
-rw-r--r-- | example/dynamic_load/dynamic_load-example.cpp | 69 | ||||
-rw-r--r-- | example/tutorial/CMakeLists.txt | 6 | ||||
-rw-r--r-- | example/tutorial/text_map_carrier.h | 37 | ||||
-rw-r--r-- | example/tutorial/tutorial-example.cpp | 99 |
6 files changed, 217 insertions, 0 deletions
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 0000000..39565cc --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(tutorial) +add_subdirectory(dynamic_load) diff --git a/example/dynamic_load/CMakeLists.txt b/example/dynamic_load/CMakeLists.txt new file mode 100644 index 0000000..1413a4b --- /dev/null +++ b/example/dynamic_load/CMakeLists.txt @@ -0,0 +1,4 @@ +if (BUILD_DYNAMIC_LOADING AND BUILD_SHARED_LIBS) + add_executable(dynamic_load-example dynamic_load-example.cpp) + target_link_libraries(dynamic_load-example opentracing) +endif() diff --git a/example/dynamic_load/dynamic_load-example.cpp b/example/dynamic_load/dynamic_load-example.cpp new file mode 100644 index 0000000..f49996f --- /dev/null +++ b/example/dynamic_load/dynamic_load-example.cpp @@ -0,0 +1,69 @@ +// Demonstrates how to load a tracer library in at runtime and how to use it +// to construct spans. To run it using the mocktracer, invoke with +// +// TRACER_CONFIG=`mktemp` +// echo '{ "output_file": "/dev/stdout" }' > $TRACER_CONFIG +// dynamic_load-example /path/to/libopentracing_mocktracer.so $TRACER_CONFIG + +#include <opentracing/dynamic_load.h> +#include <cassert> +#include <cerrno> +#include <fstream> +#include <iostream> +#include <iterator> +#include <string> + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4996) +#endif + +int main(int argc, char* argv[]) { + if (argc != 3) { + std::cerr << "Usage: <tracer_library> <tracer_config_file>\n"; + return -1; + } + + // Load the tracer library. + std::string error_message; + auto handle_maybe = + opentracing::DynamicallyLoadTracingLibrary(argv[1], error_message); + if (!handle_maybe) { + std::cerr << "Failed to load tracer library " << error_message << "\n"; + return -1; + } + + // Read in the tracer's configuration. + std::ifstream istream{argv[2]}; + if (!istream.good()) { + std::cerr << "Failed to open tracer config file " << argv[2] << ": " + << std::strerror(errno) << "\n"; + return -1; + } + std::string tracer_config{std::istreambuf_iterator<char>{istream}, + std::istreambuf_iterator<char>{}}; + + // Construct a tracer. + auto& tracer_factory = handle_maybe->tracer_factory(); + auto tracer_maybe = + tracer_factory.MakeTracer(tracer_config.c_str(), error_message); + if (!tracer_maybe) { + std::cerr << "Failed to create tracer " << error_message << "\n"; + return -1; + } + auto& tracer = *tracer_maybe; + + // Use the tracer to create some spans. + { + auto span_a = tracer->StartSpan("A"); + assert(span_a != nullptr); + span_a->SetTag("abc", 123); + auto span_b = + tracer->StartSpan("B", {opentracing::ChildOf(&span_a->context())}); + assert(span_b != nullptr); + span_b->SetTag("xyz", 987); + } + + tracer->Close(); + return 0; +} diff --git a/example/tutorial/CMakeLists.txt b/example/tutorial/CMakeLists.txt new file mode 100644 index 0000000..11daf16 --- /dev/null +++ b/example/tutorial/CMakeLists.txt @@ -0,0 +1,6 @@ +if (BUILD_MOCKTRACER AND BUILD_SHARED_LIBS) + include_directories(../../mocktracer/include) + add_executable(tutorial-example tutorial-example.cpp) + target_link_libraries(tutorial-example opentracing_mocktracer) + add_test(NAME tutorial-example COMMAND tutorial-example) +endif() diff --git a/example/tutorial/text_map_carrier.h b/example/tutorial/text_map_carrier.h new file mode 100644 index 0000000..2538324 --- /dev/null +++ b/example/tutorial/text_map_carrier.h @@ -0,0 +1,37 @@ +#ifndef LIGHTSTEP_TEXT_MAP_CARRIER +#define LIGHTSTEP_TEXT_MAP_CARRIER + +#include <opentracing/propagation.h> +#include <string> +#include <unordered_map> + +using opentracing::expected; +using opentracing::string_view; +using opentracing::TextMapReader; +using opentracing::TextMapWriter; + +class TextMapCarrier : public TextMapReader, public TextMapWriter { + public: + TextMapCarrier(std::unordered_map<std::string, std::string>& text_map) + : text_map_(text_map) {} + + expected<void> Set(string_view key, string_view value) const override { + text_map_[key] = value; + return {}; + } + + expected<void> ForeachKey( + std::function<expected<void>(string_view key, string_view value)> f) + const override { + for (const auto& key_value : text_map_) { + auto result = f(key_value.first, key_value.second); + if (!result) return result; + } + return {}; + } + + private: + std::unordered_map<std::string, std::string>& text_map_; +}; + +#endif // LIGHTSTEP_TEXT_MAP_CARRIER diff --git a/example/tutorial/tutorial-example.cpp b/example/tutorial/tutorial-example.cpp new file mode 100644 index 0000000..e842765 --- /dev/null +++ b/example/tutorial/tutorial-example.cpp @@ -0,0 +1,99 @@ +// Demonstrates basic usage of the OpenTracing API. Uses OpenTracing's +// mocktracer to capture all the recorded spans as JSON. + +#include <opentracing/mocktracer/json_recorder.h> +#include <opentracing/mocktracer/tracer.h> +#include <cassert> +#include <iostream> +#include <sstream> +#include <unordered_map> +#include "text_map_carrier.h" +using namespace opentracing; +using namespace opentracing::mocktracer; + +int main() { + MockTracerOptions options; + std::unique_ptr<std::ostringstream> output{new std::ostringstream{}}; + std::ostringstream& oss = *output; + options.recorder = std::unique_ptr<mocktracer::Recorder>{ + new JsonRecorder{std::move(output)}}; + + std::shared_ptr<opentracing::Tracer> tracer{ + new MockTracer{std::move(options)}}; + + auto parent_span = tracer->StartSpan("parent"); + assert(parent_span); + + // Create a child span. + { + auto child_span = + tracer->StartSpan("childA", {ChildOf(&parent_span->context())}); + assert(child_span); + + // Set a simple tag. + child_span->SetTag("simple tag", 123); + + // Set a complex tag. + child_span->SetTag("complex tag", + Values{123, Dictionary{{"abc", 123}, {"xyz", 4.0}}}); + + // Log simple values. + child_span->Log({{"event", "simple log"}, {"abc", 123}}); + + // Log complex values. + child_span->Log({{"event", "complex log"}, + {"data", Dictionary{{"a", 1}, {"b", Values{1, 2}}}}}); + + child_span->Finish(); + } + + // Create a follows from span. + { + auto child_span = + tracer->StartSpan("childB", {FollowsFrom(&parent_span->context())}); + + // child_span's destructor will finish the span if not done so explicitly. + } + + // Use custom timestamps. + { + auto t1 = SystemClock::now(); + auto t2 = SteadyClock::now(); + auto span = tracer->StartSpan( + "useCustomTimestamps", + {ChildOf(&parent_span->context()), StartTimestamp(t1)}); + assert(span); + span->Finish({FinishTimestamp(t2)}); + } + + // Extract and Inject a span context. + { + std::unordered_map<std::string, std::string> text_map; + TextMapCarrier carrier(text_map); + auto err = tracer->Inject(parent_span->context(), carrier); + assert(err); + auto span_context_maybe = tracer->Extract(carrier); + assert(span_context_maybe); + auto span = tracer->StartSpan("propagationSpan", + {ChildOf(span_context_maybe->get())}); + } + + // You get an error when trying to extract a corrupt span. + { + std::unordered_map<std::string, std::string> text_map = { + {"x-ot-span-context", "123"}}; + TextMapCarrier carrier(text_map); + auto err = tracer->Extract(carrier); + assert(!err); + assert(err.error() == span_context_corrupted_error); + // How to get a readable message from the error. + std::cout << "Example error message: \"" << err.error().message() << "\"\n"; + } + + parent_span->Finish(); + tracer->Close(); + + std::cout << "\nRecorded spans as JSON:\n\n"; + std::cout << oss.str() << "\n"; + return 0; +} |