This repository has been archived by the owner on Jan 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for dynamic loading. (#45)
* Dynamic load changes. * Remove default timestamping. * Add dynamic load functions. * Use factory interface for dynamic loading. * Separate TracerFactory from dynamic loading. * Support specifying an error_code when dynamic load fails. * Allow DynamicTracingLibraryHandle to be default constructible. * Add documentation for make_opentracing_factory. * Comment dynamic_load interface. * Document tracer_factory.h * Fix order in destructors. * Correct typo. * Remove windows stub. * Update naming convention to be more consistent. * Run clang-format. * Correct typo. * Add dynamic loading support to mocktracer. * Add tests for dynamic loading. * Run clang-format. * Test for weak symbols. * Run clang-format. * Fix bazel build for dynamic loading support. * link 3rd party libraries in statically. * Correct include guards. * Rearrange base64 code. * Add missing base64 code. * Include apache license. * Correct typo. * Writing manual serialization code. * Add plugin library. * Add serialization for SpanData. * Suppress false positive from undefined behavior sanitizer. * Represent duration with a string. * Use string to represent trace/span-ids. * Remove 3rd-party json library dependency. * Run clang-format. * Add missing include. * Use strings for IDs in JSON. * Run clang-format. * Add dl library dependency. * Return const pointer from const member function. * Remove constexpr from rvalue-ref member. * Fix bazel build. * Add example usage with mocktracer. * Add example for dynamic loading. * Add missing include.
- Loading branch information
Showing
32 changed files
with
990 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
void __attribute((weak)) f(); | ||
|
||
int main() { return 0; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#pragma once | ||
|
||
#cmakedefine OPENTRACING_BUILD_DYNAMIC_LOADING |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
add_subdirectory(tutorial) | ||
add_subdirectory(dynamic_load) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// 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> | ||
|
||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
if (BUILD_MOCKTRACER AND BUILD_SHARED_LIBS) | ||
include_directories(${CMAKE_SOURCE_DIR}/mocktracer/include) | ||
This comment has been minimized.
Sorry, something went wrong.
andreivirtosu
|
||
add_executable(tutorial-example tutorial-example.cpp) | ||
target_link_libraries(tutorial-example opentracing_mocktracer) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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::TextMapReader; | ||
using opentracing::TextMapWriter; | ||
using opentracing::expected; | ||
using opentracing::string_view; | ||
|
||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
Oops, something went wrong.
@rnburn Using CMAKE_SOURCE_DIR breaks the build when this project is included from within another CMakeLists.txt.
The error I get is: "Cannot find source file: .../weak_symbol.cpp
A quick fix here is to replace it with: {CMAKE_CURRENT_LIST_DIR}