Giter Club home page Giter Club logo

opentracing-cpp's Introduction

๐Ÿ›‘ This library is DEPRECATED! opentracing/specification#163

OpenTracing API for C++

C++ implementation of the OpenTracing API http://opentracing.io

Join the chat at https://gitter.im/opentracing/opentracing-cpp

Required Reading

In order to understand the C++ platform API, one must first be familiar with the OpenTracing project and terminology more generally.

Compile and install

Linux/MacOS

mkdir .build
cd .build
cmake ..
make
sudo make install

To test:

make test

Windows

mkdir .build
cd .build
cmake -G "Visual Studio 15 2017 Win64" ..

To build the targets in debug mode

MSBuild.exe opentracing-cpp.sln /p:Configuration=Debug /Target=Build

To build the targets in release mode

MSBuild.exe opentracing-cpp.sln /p:Configuration=Release /Target=Build

To test: Run the below command to run the tests with the debug targets

ctest -C Debug

Run the below command to run the tests with the release targets

ctest -C Release

API overview for those adding instrumentation

Everyday consumers of this opentracing package really only need to worry about a couple of key abstractions: the StartSpan function, the Span interface, and binding a Tracer at main()-time. Here are code snippets demonstrating some important use cases.

Singleton initialization

The simplest starting point is opentracing/tracer.h. As early as possible, call

    #include <opentracing/tracer.h>
    #include <some_tracing_impl.h>
    
    int main() {
      Tracer::InitGlobal(make_some_tracing_impl());
      ...
    }

Non-Singleton initialization

If you prefer direct control to singletons, manage ownership of the opentracing::Tracer implementation explicitly.

Starting an empty trace by creating a "root span"

It's always possible to create a "root" Span with no parent or other causal reference.

    void xyz() {
        ...
        auto tracer = /* Some Tracer */
        auto span = tracer->StartSpan("operation_name");
        if (!span)
          // Error creating span.
          ...
        span->Finish();
        ...
    }

Creating a (child) Span given an existing (parent) Span

    void xyz(const opentracing::Span& parent_span, ...) {
        ...
        auto tracer = /* Some Tracer */
        auto span = tracer->StartSpan(
            "operation_name",
            {opentracing::ChildOf(&parent_span.context())});
        if (!span)
          // Error creating span.
          ...
        span->Finish();
        ...
    }

Inject Span context into a TextMapWriter

    struct CustomCarrierWriter : opentracing::TextMapWriter {
      explicit CustomCarrierWriter(
          std::unordered_map<std::string, std::string>& data_)
          : data{data_} {}
    
      opentracing::expected<void> Set(
          opentracing::string_view key,
          opentracing::string_view value) const override {
        // OpenTracing uses opentracing::expected for error handling. This closely
        // follows the expected proposal for the C++ Standard Library. See
        //    http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0323r3.pdf
        // for more background.
        opentracing::expected<void> result;
    
        auto was_successful = data.emplace(key, value);
        if (was_successful.second) {
          // Use a default constructed opentracing::expected<void> to indicate
          // success.
          return result;
        } else {
          // `key` clashes with existing data, so the span context can't be encoded
          // successfully; set opentracing::expected<void> to an std::error_code.
          return opentracing::make_unexpected(
              std::make_error_code(std::errc::not_supported));
        }
      }
    
      std::unordered_map<std::string, std::string>& data;
    };

    ...
    
    std::unordered_map<std::string, std::string> data;
    CustomCarrierWriter carrier{data};
    auto was_successful = tracer->Inject(span->context(), carrier);
    if (!was_successful) {
      // Injection failed, log an error message.
      std::cerr << was_successful.error().message() << "\n";
    }

Extract Span context from a TextMapReader

    struct CustomCarrierReader : opentracing::TextMapReader {
      explicit CustomCarrierReader(
          const std::unordered_map<std::string, std::string>& data_)
          : data{data_} {}
    
      using F = std::function<opentracing::expected<void>(
          opentracing::string_view, opentracing::string_view)>;
    
      opentracing::expected<void> ForeachKey(F f) const override {
        // Iterate through all key-value pairs, the tracer will use the relevant keys
        // to extract a span context.
        for (auto& key_value : data) {
          auto was_successful = f(key_value.first, key_value.second);
          if (!was_successful) {
            // If the callback returns and unexpected value, bail out of the loop.
            return was_successful;
          }
        }
    
        // Indicate successful iteration.
        return {};
      }
    
      // Optional, define TextMapReader::LookupKey to allow for faster extraction.
      opentracing::expected<opentracing::string_view> LookupKey(
          opentracing::string_view key) const override {
        auto iter = data.find(key);
        if (iter != data.end()) {
          return opentracing::make_unexpected(opentracing::key_not_found_error);
        }
        return opentracing::string_view{iter->second};
      }
    
      const std::unordered_map<std::string, std::string>& data;
    };
    
    ...

    CustomCarrierReader carrier{data};
    auto span_context_maybe = tracer->Extract(carrier);
    if (!span_context_maybe) {
      // Extraction failed, log an error message.
      std::cerr << span_context_maybe.error().message() << "\n";
    }
  
    // If `carrier` contained a span context, `span_context` will point to a
    // representation of it; otherwise, if no span context existed, `span_context`
    // will be nullptr;
    std::unique_ptr<opentracing::SpanContext> span_context =
        std::move(*span_context_maybe);

API compatibility

For the time being, "mild" backwards-incompatible changes may be made without changing the major version number. As OpenTracing and opentracing-cpp mature, backwards compatibility will become more of a priority.

C/C++98

This library requires C++11 or later. But if you're interested in a C or C++98 API contact us on gitter. We're open to supporting additional APIs in a separate repository if there are people willing to maintain it.

License

By contributing to opentracing.cpp, you agree that your contributions will be licensed under its Apache 2.0 License.

opentracing-cpp's People

Contributors

bensigelman avatar david-antiteum avatar eirinikos avatar gabrielkay avatar gitter-badger avatar hennna avatar heyleke avatar ipuustin avatar isaachier avatar jmacd avatar jmillikin-stripe avatar krishvoor avatar lookfwd avatar mdouaihy avatar oberon00 avatar pantoss avatar pikbot avatar rnburn avatar saintdubious avatar shruti9520 avatar ssgelm avatar stgarf avatar sudoshweta avatar vadorovsky avatar yurishkuro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opentracing-cpp's Issues

Use of string_view in StartSpanOption::tags is dangerous

`#include
#include <opentracing/tracer.h>
#include <opentracing/tracer.h>

using namespace std;
using namespace opentracing;

void SetStandardOptions(StartSpanOptions& options)
{
{
string mystring = "user_agent";
opentracing::SetTag o1 = opentracing::SetTag{mystring, "test1"};
o1.Apply(options);
}
{
string mystring = "blah";
opentracing::SetTag o1 = opentracing::SetTag{mystring, "test2"};
o1.Apply(options);
}
}

void PrintOptions(StartSpanOptions& options)
{
string test = "someString1";
string test2 = "someString2";
for (auto a : options.tags)
{
cout << a.first << endl;
}
}

int main()
{
StartSpanOptions options;
SetStandardOptions(options);
PrintOptions(options);
return 0;
}`

Output should be:
user_agent
blah

I get:
&@๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝP๏ฟฝL
&@๏ฟฝ๏ฟฝ

This is due to the tags storing the string_view instead of a copy of the string.

I don't really understand the purpose of using string_view throughout the API. I would love to know the reasoning? I don't see any performance benefit to using over passing a string by reference. You might be able to get some improvement though the use of move semantics but in all likelihood all the strings will be small enough to avoid the free store anyway.

Cannot compile as std++14 in Xcode

When using this in a project which is c++14 code I get the following error:

In file included from /usr/local/include/opentracing/propagation.h:5:
In file included from /usr/local/include/opentracing/util.h:13:
/usr/local/include/opentracing/expected/expected.hpp:829:19: error: no matching member function for call to 'construct_error'
contained.construct_error( error.value() );
~~~~~~~~~~^~~~~~~~~~~~~~~
/usr/local/include/opentracing/expected/expected.hpp:1206:16: note: in instantiation of function template specialization 'opentracing::expected<void, std::__1::error_code>::expectedstd::exception_ptr' requested here
return make_unexpected_from_current_exception();
^
/usr/local/include/opentracing/expected/expected.hpp:157:10: note: candidate function not viable: no known conversion from 'const std::exception_ptr' to 'const error_type' (aka 'const std::__1::error_code') for 1st argument
void construct_error( error_type const & e )
^
/usr/local/include/opentracing/expected/expected.hpp:162:10: note: candidate function not viable: no known conversion from 'const std::exception_ptr' to 'error_type' (aka 'std::__1::error_code') for 1st argument
void construct_error( error_type && e )
^
1 error generated.

Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Always getting span_id as null

Hi Team,

I'm trying to use DynamicallyLoadTracer to load zipkin or jaeger library. But i'm always getting parent span is as NULL after ectracting client message.
When i do gdb i can find span_id is null. Could you please suggest what could be the issue here.

This is my client tracer id: uber-trace-id=16b388d3ff1dd88d:4a2e6836f0c9fa90:16b388d3ff1dd88d:1
after this particular line of code:
auto span_context_maybe = opentracing::Tracer::Global()->Extract(OTCorrInfo);

Code for tracer initialization is as below:
const char * configuration=R"({"service_name":"finlistval"},{"disabled": "false"})";
auto& tracer_factory = handle_maybe->tracer_factory();
auto tracer_maybe =tracer_factory.MakeTracer(configuration, error_message);
if (!tracer_maybe) {
sprintf(errMsg,"Failed to create tracer [%s]",error_message.c_str());
OTLogger(errMsg,0);
return -1;
}
tracer = *tracer_maybe;
if(tracer==NULL)
{
sprintf(errMsg,"Tracer is null");
OTLogger(errMsg,0);
}

Gdb output of span_context_maybe =
$1 = {has_value_ = true, contained = {m_value = std::unique_ptropentracing::v3::SpanContext containing 0x0, m_error = {
_M_value = 0, _M_cat = 0x7fff00000005}}}

Please let me know , what i'm doing wrong.

Method to reset the global tracer?

Hello,
Is it a conscious choice not to have provided a ResetGlobal method or equivalent on the tracer?
I suppose the shared_ptr is cleaned up at global shutdown of an application, but that limits the opportunities for "controlled" init/cleanup of the singleton.

Would this be the preferred way to do it with the current opentracing code?

void closeOpenTracer() 
{ 
    opentracing::Tracer::Global()->Close();
    // How do we delete the global tracer pointer?
    // There is no public method to do so
    //std::shared_ptr<opentracing::Tracer> t;
    // Reinit with an empty shared pointer ?
    //opentracing::Tracer::InitGlobal(t);
}

Thank you,
Regards, Emmanuel.

Default construction of `StartSpanOptions` sets timestamps to epoch time

Calling tracer->StartSpan("operation") intuitively should behave the same as calling tracer->StartSpanWithOptions("operation", StartSpanOptions()), however it doesn't. The former default constructs the StartSpanOptions object and sets the timestamps to Clock::now(), but the latter does not set the timestamps. I think it would make more sense to set the timestamps to Clock::now() in a new default constructor StartSpanOptions().

[CMake BUG] If I don't install, the built target opentracing won't carry correct INTERFACE include directories

CLion won't build install target of CMake. And if I build from source by CLion, the built targets won't carry correct INTERFACE include directories. So when linking with opentracing, the compiler will complain about not find the .h files.

something like this:

In file included from /somepath/TextMapCarrier.cpp:12:0:
/somepath/TextMapCarrier.h:14:10: fatal error: opentracing/propagation.h: No such file or directory
 #include <opentracing/propagation.h>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
otherpath/CMakeFiles/tracing.dir/build.make:62: recipe for target 'otherpath/CMakeFiles/tracing.dir/TextMapCarrier.cpp.o' failed
make[3]: *** [otherpath/CMakeFiles/tracing.dir/TextMapCarrier.cpp.o] Error 1
make[3]: *** Waiting for unfinished jobs....
In file included from /somepath/TraceContext.cpp:12:0:
/somepath/TraceContext.h:14:10: fatal error: opentracing/tracer.h: No such file or directory
 #include <opentracing/tracer.h>
          ^~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
otherpath/tracing.dir/build.make:75: recipe for target 'src/tracing/CMakeFiles/tracing.dir/TraceContext.cpp.o' failed
make[3]: *** [otherpath/tracing.dir/TraceContext.cpp.o] Error 1
/sompath/TracerUtil.cpp:14:10: fatal error: opentracing/dynamic_load.h: No such file or directory
 #include <opentracing/dynamic_load.h>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

REASON

The reason is your CMakeLists.txt didn't give opentracing target a correct interface include directories. List below.

if (BUILD_SHARED_LIBS)
  add_library(opentracing SHARED ${SRCS})
  target_link_libraries(opentracing ${LIBRARIES})
  target_include_directories(opentracing INTERFACE "$<INSTALL_INTERFACE:include/>")
 ...
endif()

if (BUILD_STATIC_LIBS)
  add_library(opentracing-static STATIC ${SRCS})
 ...
  target_include_directories(opentracing-static INTERFACE "$<INSTALL_INTERFACE:include/>")
...
endif()

You only give an INSTALL_INTERFACE include directories for the target

So if I don't install (If I use CLion or trying to integrate opentracing with my own cmake project), When I link with opentracing, the above build errors will occur.

Suggestions

add other include directories to opentracing's INTERFACE include directories, something like this:

if (BUILD_SHARED_LIBS)
  add_library(opentracing SHARED ${SRCS})
  target_link_libraries(opentracing ${LIBRARIES})
  target_include_directories( opentracing INTERFACE 
"$<INSTALL_INTERFACE:include/>"
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/include> )
 ...
endif()

`expected` compilation errors

Keep seeing this anytime I try to get the result of Extract into a unique_ptr object using std::move.

expected.hpp:666:39: error: could not convert 
โ€˜((opentracing::expected<std::unique_ptr<opentracing::v1::SpanContext> >*)this)- >
opentracing::expected<std::unique_ptr<opentracing::v1::SpanContext>>::contained.opentracing::
expected_detail::storage_t<std::unique_ptr<opentracing::v1::SpanContext>, std::error_code>::error()โ€™ 
from โ€˜opentracing::expected_detail::storage_t<std::unique_ptr<opentracing::v1::SpanContext>, 
std::error_code>::error_type {aka std::error_code}โ€™ to โ€˜std::__exception_ptr::exception_ptrโ€™

Confusion over how to best declare a tracer

I'm just trying to make a span and have that span log a few values then close. I'm pretty sure my span code is fine, I just don't know how to declare a tracer than will send traces to my localhost:9411 (run through docker). I've tried declaring a MockTracer with default constructed options and an auto constructed NoopTracer but when I run nothing shows up on the zipkin api. It would be a huge help if you could tell me how I can declare a basic tracer (which was never fully addressed in any of the specs) and if I need to make any calls to make sure my traces are sent out to the localhost.

Dynamic casting

I am concerned about the requirement to use dynamic_cast to downcast from an opentracing span to a Jaeger span for my Jaeger client implementation. It is a potential performance bottleneck I'd like to avoid. Is it possible to use the visitor pattern instead? For example, instead of

    class Tracer : public opentracing::Tracer {
        // ...
        virtual opentracing::expected<void> Inject(
            const opentracing::SpanContext& sp,
            const opentracing::TextMapWriter& writer) const override
        {
            // Forced to use dynamic_cast here to downcast to Jaeger span
            const SpanContext* ctx = dynamic_cast<const SpanContext*>(&sp);
            if (!ctx) {
                return opentracing::make_expected_from_error<void>(
                    opentracing::invalid_span_context_error);
            }
            // Encode Jaeger context...
            return opentracing::make_expected();
        }

can SpanContext have a virtual method named Inject with a default implementation that returns an error so I could write something like this?

    class SpanContext : public opentracing::SpanContext {
        // ...
        opentracing::expected<void> Inject(const opentracing::TextMapWriter& writer) const override
        {
            // Encode Jaeger context...
            return opentracing::make_expected();
        }
        // ...
    };
    class Tracer : public opentracing::Tracer {
        // ...
        virtual opentracing::expected<void> Inject(const opentracing::SpanContext& sp,
                                                                                const opentracing::TextMapWriter& writer) const override
        {
            return sp.Inject(writer);
        }
    };

In fact, that latter would probably remove the need for a Tracer::Inject method entirely.

bool return for Finish to indicate dropped Span

Currently there is no means to know if a span gets dropped, or has some sort of failure - Finish is a void return function. I would like to submit a PR that adds a bool return type to Finish and FinishWithOptions.

What is the likely hood of that being accepted?

Adding functionality to package this repo into rpms for centos and fedora users

I'm building this repository into an RPM, and the only issue I'm having is including version.h in the rpm. It seems version.h is made from version.h.in, but I can't figure out what is turning version.h.in into version.h and it isn't happening just from the make.

Sorry, I resolved my issue above. I made changes so that running make rpm in .build/ now makes two rpms (one with .so's and one with headers). I also implemented this with your zipkin repository. I can contribute these to github if any centos or fedora users want to package opentracing as an rpm. It's just an addition to the CMakeList.txt and two additional .spec files. Let me know if I can contribute this and I'll push it.
Thanks!

Support for sampling priority

Do not find anything in here about sampling priority. I think it should be added, potentially to Span::SetTag documentation.

Provide some links to tracing implementations

The mock_tracer and the readme examples of some_tracing_impl.h are fine for conceptually showing the library but there should be links or an easy way to find actual tracing implementations that can be used and demonstration of this in the examples. i.e. where would I find tracing for opencensus/opentelemetry/jaeger?

Provide an example for usage of HTTPHeadersReader

I am trying to implement how to use HTTPHeadersReader especially what to override for following

  virtual expected<void> ForeachKey(
      std::function<expected<void>(string_view key, string_view value)> f)
      const = 0;

Can't build cmake project with opentracing

Given this small test program:

#include <iostream>
#include <opentracing/tracer.h>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

and this CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)
project(tracingtest)

set(CMAKE_CXX_STANDARD 11)

add_subdirectory(opentracing-cpp-master)
add_executable(main main.cpp)
target_link_libraries(main opentracing)

I'm unable to build the target main:

/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/tw/devel/tracingtest/cmake-build-debug --target main -- -j 4
Scanning dependencies of target opentracing
[ 30%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/dynamic_load.cpp.o
[ 40%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/propagation.cpp.o
[ 40%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/noop.cpp.o
[ 40%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/tracer.cpp.o
[ 50%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/tracer_factory.cpp.o
[ 70%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/ext/tags.cpp.o
[ 70%] Building CXX object opentracing-cpp-master/CMakeFiles/opentracing.dir/src/dynamic_load_unix.cpp.o
[ 80%] Linking CXX shared library ../output/libopentracing.dylib
[ 80%] Built target opentracing
Scanning dependencies of target main
[ 90%] Building CXX object CMakeFiles/main.dir/main.cpp.o
/Users/tw/devel/tracingtest/main.cpp:2:10: fatal error: 'opentracing/tracer.h' file not found
#include <opentracing/tracer.h>
         ^~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make[3]: *** [CMakeFiles/main.dir/main.cpp.o] Error 1
make[2]: *** [CMakeFiles/main.dir/all] Error 2
make[1]: *** [CMakeFiles/main.dir/rule] Error 2
make: *** [main] Error 2

Building with VERBOSE=1 shows the following compiler command, which is missing the include directories to opentracing:

/Library/Developer/CommandLineTools/usr/bin/c++    -g   -std=gnu++11 -o CMakeFiles/main.dir/main.cpp.o -c /Users/tw/devel/tracingtest/main.cpp

The test, example targets from the Opentracing source dir however build and run successfully. What do I have to do to make opentracing available in my C++ code? This is current opentracing-cpp master, also occurs with the opentracing-cpp 1.5.0 release.

C API

Not sure if this has ever been addressed, but would it make sense to include a C API header? I was going to try and write one for my own client, but realized it probably makes more sense to wrap the OpenTracing API than my own custom API. Just to reference an example of what I mean, see LevelDB's C header in c.h. Adding a header like that for the OpenTracing API would simplify writing bindings for C based languages such as Python and Lua.

C++20 compatibility for library users / std::result_of removed

As a library user, i would like to compile my code using the C++20 standard.

But in /3rd_party/include/opentracing/variant/variant.hpp' the std::result_of<>` template is used:

This template was removed in C++20: see https://en.cppreference.com/w/cpp/types/result_of

std::invoke_result<> can be used as an drop in replacement.

To make the code still compile in C++ versions below C++17 the code can use
__cpp_lib_is_invocable (https://en.cppreference.com/w/cpp/feature_test) to different

e. g.

            template <typename F, typename V, typename Enable = void>
            struct result_of_unary_visit
            {
#ifdef __cpp_lib_is_invocable
                using type = typename std::invoke_result<F, V&>::type;
#else
                using type = typename std::result_of<F(V&)>::type;
#endif
            };
            template <typename F, typename V, typename Enable = void>
            struct result_of_binary_visit
            {
#ifdef __cpp_lib_is_invocable
                using type = typename std::invoke_result<F, V&, V&>::type;
#else
                using type = typename std::result_of<F(V&, V&)>::type;
#endif
            };

string_view error

according to tutorial, when i include <opentracing/mocktracer/json_recorder.h>, reporting some errors
In file included from /usr/local/include/opentracing/mocktracer/json_recorder.h:4:
In file included from /usr/local/include/opentracing/mocktracer/recorder.h:4:
In file included from /usr/local/include/opentracing/tracer.h:4:
In file included from /usr/local/include/opentracing/propagation.h:4:
/usr/local/include/opentracing/string_view.h:55:16: error: expected ';' at end of declaration list
string_view() noexcept : data_(nullptr), length_(0) {}
^
/usr/local/include/opentracing/string_view.h:96:58: error: expected function body after function declarator
inline bool operator==(string_view lhs, string_view rhs) noexcept {
^
In file included from ../src/HelloWorld.cpp:2:
In file included from /usr/local/include/opentracing/mocktracer/json_recorder.h:4:
In file included from /usr/local/include/opentracing/mocktracer/recorder.h:4:
In file included from /usr/local/include/opentracing/tracer.h:4:
In file included from /usr/local/include/opentracing/propagation.h:5:
In file included from /usr/local/include/opentracing/util.h:13:
/usr/local/include/opentracing/expected/expected.hpp:105:5: error: unknown type name 'constexpr'
constexpr value_type const & value() const &
^
/usr/local/include/opentracing/expected/expected.hpp:105:15: error: duplicate member 'value_type'
constexpr value_type const & value() const &
^
/usr/local/include/opentracing/expected/expected.hpp:68:15: note: previous declaration is here
typedef T value_type;
^
/usr/local/include/opentracing/expected/expected.hpp:105:25: error: expected ';' at end of declaration list
constexpr value_type const & value() const &
^
/usr/local/include/opentracing/expected/expected.hpp:77:15: error: use of undeclared identifier 'm_value'
new( &m_value ) value_type( v );
^
/usr/local/include/opentracing/expected/expected.hpp:82:15: error: use of undeclared identifier 'm_value'
new( &m_value ) value_type( std::forward( v ) );
^
/usr/local/include/opentracing/expected/expected.hpp:87:9: error: use of undeclared identifier 'm_value'
m_value.~value_type();
^
/usr/local/include/opentracing/expected/expected.hpp:204:5: error: unknown type name 'constexpr'
constexpr explicit unexpected_type( error_type const & error )
^
/usr/local/include/opentracing/expected/expected.hpp:204:15: error: expected member name or ';' after declaration specifiers
constexpr explicit unexpected_type( error_type const & error )
~~~~~~~~~ ^
/usr/local/include/opentracing/expected/expected.hpp:271:1: error: unknown type name 'constexpr'
constexpr bool operator==( unexpected_type const & x, unexpected_type const & y )
^
/usr/local/include/opentracing/expected/expected.hpp:271:11: error: expected unqualified-id
constexpr bool operator==( unexpected_type const & x, unexpected_type const & y )
^
/usr/local/include/opentracing/expected/expected.hpp:332:8: error: explicit specialization of non-template struct 'is_unexpected'
struct is_unexpected< unexpected_type > : std::true_type {};
^ ~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/opentracing/expected/expected.hpp:337:18: error: 'auto' not allowed in function return type
nsel_constexpr14 auto
^~~~
/usr/local/include/opentracing/expected/expected.hpp:338:25: error: expected ';' at end of declaration
make_unexpected( E && v) -> unexpected_type< typename std::decay::type >
^
/usr/local/include/opentracing/expected/expected.hpp:338:26: error: cannot use arrow operator on a type
make_unexpected( E && v) -> unexpected_type< typename std::decay::type >
^
/usr/local/include/opentracing/expected/expected.hpp:344:42: error: expected function body after function declarator
make_unexpected_from_current_exception() -> unexpected_type< std::exception_ptr >
^
/usr/local/include/opentracing/expected/expected.hpp:353:1: error: unknown type name 'constexpr'
constexpr in_place_t in_place{};
^
/usr/local/include/opentracing/expected/expected.hpp:353:21: error: expected ';' after top level declarator
constexpr in_place_t in_place{};
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [src/HelloWorld.o] Error 1

Make fails on Apple M1 arm64 architecture

Hi,
I have an issue if I try to execute make in the build folder

.build git:(master) โœ— make
[ 12%] Built target opentracing
[ 24%] Built target opentracing-static
[ 43%] Built target opentracing_mocktracer
[ 60%] Built target opentracing_mocktracer-static
Consolidate compiler generated dependencies of target mocktracer_tracer_test
[ 61%] Building CXX object mocktracer/test/CMakeFiles/mocktracer_tracer_test.dir/tracer_test.cpp.o
In file included from opentracing-cpp/mocktracer/test/tracer_test.cpp:9:
opentracing-cpp/3rd_party/include/opentracing/catch2/catch.hpp:4167:13: error: unrecognized instruction mnemonic, did you mean: bit, cnt, hint, ins, not?
            CATCH_BREAK_INTO_DEBUGGER();
            ^

following be similiar errors..
Do you have an idea how to resolve the issue? Thanks in advance!

Build error

My main code :
auto config = jaegertracing::Config(
false,
jaegertracing::samplers::Config(jaegertracing::kSamplerTypeConst, 1),
jaegertracing::reporters::Config(
jaegertracing::reporters::Config::kDefaultQueueSize,
std::chrono::seconds(1), true));
std::shared_ptropentracing::Tracer tracer = jaegertracing::Tracer::make("c++", config);
auto span = tracer->StartSpan("abc");
std::this_thread::sleep_for(std::chrono::milliseconds{10});
span->Finish();
std::this_thread::sleep_for(std::chrono::seconds{5});
tracer->Close();

then build error is :
clang++ -D__GXX_EXPERIMENTAL_CXX0X__ -D__cplusplus=201103L -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -stdlib=libc++ -MMD -MP -MF"src/jaegertracing/thrift-gen/Agent.d" -MT"src/jaegertracing/thrift-gen/Agent.o" -o "src/jaegertracing/thrift-gen/Agent.o" "../src/jaegertracing/thrift-gen/Agent.cpp"
../src/jaegertracing/thrift-gen/Agent.cpp:70:10: error: no member named 'incrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'incrementInputRecursionDepth'?
oprot->incrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
incrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:557:8: note: 'incrementInputRecursionDepth' declared here
void incrementInputRecursionDepth() {
^
../src/jaegertracing/thrift-gen/Agent.cpp:87:10: error: no member named 'decrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'decrementInputRecursionDepth'?
oprot->decrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
decrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:562:8: note: 'decrementInputRecursionDepth' declared here
void decrementInputRecursionDepth() { --input_recursion_depth_; }
^
../src/jaegertracing/thrift-gen/Agent.cpp:98:10: error: no member named 'incrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'incrementInputRecursionDepth'?
oprot->incrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
incrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:557:8: note: 'incrementInputRecursionDepth' declared here
void incrementInputRecursionDepth() {
^
../src/jaegertracing/thrift-gen/Agent.cpp:115:10: error: no member named 'decrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'decrementInputRecursionDepth'?
oprot->decrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
decrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:562:8: note: 'decrementInputRecursionDepth' declared here
void decrementInputRecursionDepth() { --input_recursion_depth_; }
^
../src/jaegertracing/thrift-gen/Agent.cpp:166:10: error: no member named 'incrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'incrementInputRecursionDepth'?
oprot->incrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
incrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:557:8: note: 'incrementInputRecursionDepth' declared here
void incrementInputRecursionDepth() {
^
../src/jaegertracing/thrift-gen/Agent.cpp:175:10: error: no member named 'decrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'decrementInputRecursionDepth'?
oprot->decrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
decrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:562:8: note: 'decrementInputRecursionDepth' declared here
void decrementInputRecursionDepth() { --input_recursion_depth_; }
^
../src/jaegertracing/thrift-gen/Agent.cpp:186:10: error: no member named 'incrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'incrementInputRecursionDepth'?
oprot->incrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
incrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:557:8: note: 'incrementInputRecursionDepth' declared here
void incrementInputRecursionDepth() {
^
../src/jaegertracing/thrift-gen/Agent.cpp:195:10: error: no member named 'decrementRecursionDepth' in 'apache::thrift::protocol::TProtocol'; did you mean 'decrementInputRecursionDepth'?
oprot->decrementRecursionDepth();
^~~~~~~~~~~~~~~~~~~~~~~
decrementInputRecursionDepth
/usr/local/include/thrift/protocol/TProtocol.h:562:8: note: 'decrementInputRecursionDepth' declared here
void decrementInputRecursionDepth() { --input_recursion_depth_; }
^
8 errors generated.
make: *** [src/jaegertracing/thrift-gen/Agent.o] Error 1

my local thrift version is 0.9.3

Conventions for ABI changes?

When an app loads a C++ tracer dynamically, all the C++ tracers currently do a comparison of the version of the OT API they were built with to the version of the OT API the app was built with. If there's any difference, they fail with a incompatible_library_versions_error. This is meant to protect against using a tracer and app with incompatible ABIs. Any differences in the ABI can cause the app to segfault.

While this was probably ok behavior to start with, I think it may be too strict as it will cause loading to fail for even minor non-ABI-breaking changes.

I'm wondering if we can establish some conventions for ABI changes to allow for less strict checking.

Perhaps require any ABI change to update at least the minor version of the repository so the comparison can ignore the patch version?

And for reference, these are examples of some changes and how they would affect the ABI:

  • Adding, removing, or reordering data members for structs like StartSpanOptions, SpanReference, etc. (Breaks ABI)
  • Adding, removing, or reordering virtual functions. (Breaks ABI).
  • Adding a non-virtual function. (Doesn't change ABI).

Enable opentracing-cpp on ppc64le arch #94

Hey!

Thanks for the awesome readme/tutorials on opentracing-cpp. I could build opentracing-cpp from source & run the tests outlined successfully on ppc64le.

Incase, if you are wondering what ppc64le architecture is?
It is a RISC Architecture and is IBM's prodigy, IBM recently has made it's ISA (Instruction Set Architecture) opensource,
doing so they have contributed back to opensource world. Many of the pioneers of banking, HPC industries today run on ppc64le architecture.

As an ongoing effort to enable opensource projects to which ppc64le architecture can add value to, we are trying to enable this project. We have seen absolute no deviation in build/test instructions. I will soon submit a PR to enable build/testing on ppc64l architecture as well.

Virtual hierarchy

I have encountered a handful of issues in my attempt to implement the opentracing-cpp API for my Jaeger C++ client (https://github.com/isaachier/cpp-client).

First, I have found that the only way to do type checking is dynamic casting. I am convinced this is not ideal for any C++ class hierarchy. I wonder what other solution there might be for identifying subclasses at runtime. Perhaps a visitor pattern would be more appropriate (i.e. add a virtual visit method to Span etc.).

Second, I noticed many virtual methods are declared const and noexcept. In my experience, this tends to look good upfront, but the implementations will struggle to maintain these guarantees.

Third, related to the second point, is that the const-ness seems to be incorrect in a number of situations. For example, the readers and writers in propagation.h should not use const methods for reading and writing. Why would I want to modify a const Reader/Writer by allowing client to change the seek position in the input/output stream? Also, I find Inject, Extract, and especially StartSpanWithOptions are difficult to implement in the Tracer without sacrificing a good deal of const correctness.

I'd say you can probably replace the const-ness of the virtual methods without sacrificing much backwards-compatibility, but there is no perfect solution. Please let me know what you think.

const noexcept override try

I'm getting compilation error "expected ';' at end of declaration list" from the following line of code: https://github.com/opentracing/opentracing-cpp/blob/master/include/opentracing/tracer.h#L219

I'm not familiar with the expected behavior of this code. Is wrapping with curly braces an option?

void Apply(StartSpanOptions& options) const noexcept override {
 try {
    if (referenced_) options.references.emplace_back(type_, referenced_);
  } catch (const std::bad_alloc&) {
    // Ignore reference if memory can't be allocated for it.
  }
}

Link dynamic_load-example against -pthread

I was trying to test the dynamic_load-example with jaeger tracer in libjaegertracing.so and ended up with a segmentation fault. When I tested dynamic_load-example with libopentracing_mocktracer.so then everything worked as expected.

gdb indicated, that the segmentation fault occurs right when libjaegertracing.so tries to create a std::thread that is related to reporting the traces. The problem is solved if I link the dynamic_load-example against -pthread in the CMakeLists.txt:

target_link_libraries(dynamic_load-example opentracing -pthread)

This is likely a tracing library specific problem but it took a significant amount of time to realize the underlying issue, so would it be reasonable to add -pthread to the CMakeLists.txt
when building on unix?

Virtual `const`/`noexcept` methods

I am having trouble with the fact that many of the virtual methods force the implementation to be const and/or noexcept. For example, I would like all of my spans to have a reference to the tracer so they can report when they are finished. Simply, this could be implemented like so

class Tracer : public opentracing::Tracer {
    // ...
    void StartSpanWithOptions(opentracing::string_view operationName,
                         const opentracing::StartSpanOptions& options) const noexcept override
    {
        return Span(*this, operationName, options);
    }

    void reportSpan(const Span& span);
};

class Span : public opentracing::Span {
    // ...
    Span(Tracer& tracer, opentracing::string_view operationName, const opentracing::StartSpanOptions& options)
        : _tracer(tracer)
    {
    }

    void FinishWithOptions(const opentracing::FinishSpanOptions& finishSpanOptions) noexcept override
    {
        // Finish span
        _tracer.reportSpan(*this);

        // Parenthetically, this would not work in the header without introducing a cyclic dependency
        // between Tracer and Span, but illustrates the point regardless of the actual location of
        // this code.
    }

    // ...
    Tracer& _tracer;
};

However, the above does not work, because the type of the tracer reference passed to the span is const Tracer& tracer. The reason being that Tracer::StartSpanWithOptions is const when it need not be. This forces me into the awkward position of deciding between using const_casting the reference to the tracer, or making reportSpan a const method when it logically should not be called on a const Tracer object.

Build failure on Windows

The build fails on Windows because of the following issues:

  • dlfcn.h header is not used in opentracing-cpp/src/dynamic_load.cpp and this header is not available on Windows
  • cctype header must be included in opentracing-cpp/mocktracer/src/tracer_factory.cpp in order to use std::isprint and std::isspace

I already have a branch with the fix. If you grant me access I can open a pull request.

Macos gcc/clang error

Hello, everyone.When i use Eclipse to build c++ code ,that is ok.But in terminal there is link error.

clang++ -std=c++11 AMQPClientSend.cpp -o send -lSimpleAmqpClient -lopentracing -lcurl -ljaegertracing -v
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.11.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name AMQPClientSend.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 274.1 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0 -stdlib=libc++ -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Users/xujie/Desktop/C_Project/AMQP_Opentrainc/src -ferror-limit 19 -fmessage-length 117 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.11.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/8h/yw85sq4j5mjf9q19rm24vv340000gn/T/AMQPClientSend-b52538.o -x c++ AMQPClientSend.cpp
clang -cc1 version 8.0.0 (clang-800.0.42.1) default target x86_64-apple-darwin15.6.0
ignoring nonexistent directory "/usr/include/c++/v1"
#include "..." search starts here:
#include <...> search starts here:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.11.0 -o send /var/folders/8h/yw85sq4j5mjf9q19rm24vv340000gn/T/AMQPClientSend-b52538.o -lSimpleAmqpClient -lopentracing -lcurl -ljaegertracing -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"TraceSingleton::getInstance()", referenced from:
CreateTrace(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >) in AMQPClientSend-b52538.o
"TraceSingleton::CreateTracer(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::map<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, opentracing::v1::Value, std::__1::less<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const, opentracing::v1::Value> > >, std::initializer_list<std::__1::pair<opentracing::v1::string_view, opentracing::v1::Value> >, std::__1::map<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > > > >, DHTracer*)", referenced from:
CreateTrace(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >) in AMQPClientSend-b52538.o
"TraceSingleton::SendContextWithRequest()", referenced from:
CreateTrace(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >) in AMQPClientSend-b52538.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Please clarify what is the current status of this project

I'm interested to know whether there are plans to continue to support/maintain and/or improve this package in-light of recent developments in OpenTelemetry, and if so, for how long and what are the plans for migration if any?

Based on my observation, OpenTelemetry is still in early development, and at this time the C++ implementation is mostly empty/TBD (see https://github.com/open-telemetry/opentelemetry-cpp), so there is value in having a mature tracing implementation available now, and for the near future.

Furthermore, (based on interactions in OpenTelemetry working groups) there are plans to offer some backwards support for OpenTracing in OpenTelemetry (i.e. you can still use the OpenTracing APIs to instrument your code but the Tracer will forward to OpenTelemetry's SDK), so any further improvements to OpenTracing may still be used in this model.

Can you please share your views/plans with regards to this?

I am interested in contributing to parts of this implementation but did not want to do this if the project is no longer accepting enhancements.

Thanks

OpenTracing support for dynamic loading.

Many C/C++ projects (e.g. nginx, haproxy, varnish, envoy) that would benefit from OpenTracing instrumentation are distributed as binary executables instead of libraries.

When instrumenting such projects, the practice so far has been to write code for each tracer that exposes its configuration options as part of the applications configuration. (See for example nginx-opentracing/lightstep and nginx-opentracing/zipkin).

This increases the cost of maintaining these projects and goes against OpenTracing's goal of making it easy to switch tracing implementations. Furthermore, since many of the projects are used as building blocks in larger systems that interact with the application's configuration, the cost compounds since those systems also need to be aware a tracer's configuration. (See for example how OpenTracing was incorporated into Kubernetes' ingress-nginx controller).

I propose we adopt some conventions for C++ tracers that would allow applications to load tracers in dynamically using dlopen and decouple applications from specific tracer configuration options.

This could be done by standardizing on a function that could be looked up from a tracer's shared library using dlsym. Consider for example a C function (to avoid mangling) like

extern "C" int opentracing_make_vendor_tracer(void** tracer, const char* json_configuration);

that would take in a configuration string for the tracer in JSON, set tracer, and return 0 on success or some non-zero error code on failure.

A user of an application like nginx, then, might configure a tracer by adding something like

opentracing_tracer_option access_token abc123;
opentracing_tracer_option collector_host localhost;
opentracing_load_tracer liblightstep_tracer.so;

into nginx.conf which would cause nginx to lookup opentracing_make_vendor_tracerin liblightstep_tracer.so and call it with

{
  "access_token": "abc123",
  "collector_host": "localhost"
}

avoiding the need to have specific configuration directives for each LightStep option.

Projects that want to avoid the pains associated with dynamic library management could still link in some tracers statically, but might also add dynamic loading functionality like this as an optional way to plug in additional tracers.

Standards around both trace encoding and transport (such as what's outlined here) might make it possible some day to have a vendor neutral tracer that could report to any tracing system and avoid the need to dynamically load anything in, but this would address a more immediate need to make OpenTracing scalable and maintainable for these projects.

compiler restriction for mocktracer are too strict

#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"

see https://github.com/nlohmann/json#supported-compilers

I believe a library like opentracing-cpp cannot be as strict in supported compilers as mentioned here, IMHO the line should be c++11, which is AFAIU gcc 4.8.5 (with certain cpu architectures excluded).

So, either this check is wrong, or this component is not a good dependency.

OpenTracing in Vcpkg

More than an issue an announcement :)

I have added OpenTracing to vcpkg (C++ Library Manager) repository via this merged PR: microsoft/vcpkg#5974

It works in Windows and Linux (probably in macOS but vcpkg doesn't run in macOS yet).

During the porting I have found two problems:

  • no UWP support (not important)
  • cannot build the static version without the dynamic one (so vcpkg builds either the dynamic version or the static AND dynamic version)

Install the package with:

vcpkg install opentracing

Then use it in cmake (dynamic version):

find_package(OpenTracing CONFIG REQUIRED)
target_link_libraries(main PRIVATE OpenTracing::opentracing)

or (static version):

find_package(OpenTracing CONFIG REQUIRED)
target_link_libraries(main PRIVATE OpenTracing::opentracing-static)

`Span::context()` should return value, not reference

Jaeger tries to implement a multithreaded Span by keeping the SpanContext immutable (for the most part, details about sampling flag not relevant here). Whenever the baggage changes, the span swaps the current SpanContext instance with a new SpanContext object with an identical baggage map other than the appended key-value pair. The problem arises with the following code.

std::unique_ptr<opentracing::Span> span = tracer->StartSpan("operation");

// Thread #1
SpanContext ctx(span->context());

// Thread #2
span->SetBaggageItem("key", "value");

Here is the issue with this paradigm.

Thread #1: acquire lock on span
Thread #1: get reference to span's context
Thread #1: release lock on span
Thread #2: acquire lock on span
Thread #1: return reference to caller
Thread #2: swap span's context, overwriting initial context

The code above shows a potential interleaving of instructions in such a way that the caller of Span::context() is left with undefined behavior. There is no way for the caller to prevent the existing memory from being overwritten. I proposed changing the return type to a value so we can safely copy the existing span context into a new memory location in the caller's domain, eliminating all race conditions.

Sending binary objects via opentracing apis and converting to key-value pairs in the collector

Is there a way to send a binary object (protobuf) as a value for an attribute, and then outside the program being traced, convert the binary object to key value pairs.

What I am looking for is for hooks where I can insert my code to convert binary globs in to additional (attribute, value) pairs that I can use to filter and analyze my traces. I however want to do this offline. I do not want to pay the cost of converting big binary objects in to attribute-value pairs inline in my code because my processor & memory are very small. It is an embedded software environment.

Add log function for runtime types

As of now, a user must use an initializer list to log key-value pairs. The problem is, this effectively disables any dynamic logging. For example, if I want to log a list of key-value pairs, I have to know this list at compile time, seeing as no STL container can be converted into an initializer list at runtime.

Here are a few ideas for a new log function overload:

using Iterator = std::vector<std::pair<string_view, Value>>::const_iterator;
virtual void Log(Iterator first, Iterator last) noexcept = 0;

or

Build with -fPIC

Opentracing should really default to building a shared lib with -fPIC (gcc); there's not really any good reason not to build position-indepedent code anymore.

Lack of -fPIC upsets jaeger-cpp among other things.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.