-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tracing: Support dynamically loading tracing libraries. (#2252)
This PR adds support for dynamically loading tracers into Envoy. It will allow authors of OpenTracing compliant tracers to support envoy without requiring envoy to bake their tracers into its build. Tracing libraries can be enabled by adding a section like this to envoy's configuration: tracing: http: name: envoy.dynamic.ot config: library: /path/to/tracing/library config: { .... } With this change, Envoy will be able to use Jaeger's new C++ tracing library. Some features this will allow that aren't available when using Jaeger as a collector for Zipkin: Propagation will work correctly with other services using Jaeger without requiring them to make configuration changes. Jaeger's different sampling strategies can be used. More efficient tranports are available. While it might also make sense sometime in the future to offer a version of Jaeger or other tracers built into Envoy, decoupled plug-in support will allow for quicker on-boarding of tracers and more experimentation in the area without making Envoy's external dependencies become unmanageable. Notes: One challenge with using dynamically loaded libraries in Envoy is that the standard c++ library is statically compiled in with the option -static-libstdc++. If plugin libraries are linked to the libstdc++ in a standard way, this will create problems as two versions of the standard library will be loaded and calls to their functions from the plugin will be intermingled between them, breaking many of the standard library functions. The approach I took with Jaeger was to have it also use -static-libstdc++ and then use an export map to ensure that it's version of the standard library is used without any intermingling (see dsohowto for background on the approach). It does mean that there will be multiple copies of libstdc++ running, but from what I've heard this can be made to work. Another approach could be to add a config option to link libstdc++ dynamically. This depends on opentracing/opentracing-cpp#45 being merged in to opentracing-cpp, but I wanted to get a PR in early to get feedback on the approach in case we need to make changes to that PR. Risk Level: Medium Testing: I have a small example that demoes this functionality using docker and a branch of jaeger. I also plan to add unit test coverage using a mock tracer library that will be added to opentracing-cpp. Docs Changes: envoyproxy/data-plane-api#386 Release Notes: Included in PR. Signed-off-by: Ryan Burn <[email protected]>
- Loading branch information
Showing
23 changed files
with
596 additions
and
33 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
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,38 @@ | ||
#include "common/tracing/dynamic_opentracing_driver_impl.h" | ||
|
||
#include "common/common/assert.h" | ||
|
||
namespace Envoy { | ||
namespace Tracing { | ||
|
||
DynamicOpenTracingDriver::DynamicOpenTracingDriver(Stats::Store& stats, const std::string& library, | ||
const std::string& tracer_config) | ||
: OpenTracingDriver{stats} { | ||
std::string error_message; | ||
opentracing::expected<opentracing::DynamicTracingLibraryHandle> library_handle_maybe = | ||
opentracing::DynamicallyLoadTracingLibrary(library.c_str(), error_message); | ||
if (!library_handle_maybe) { | ||
throw EnvoyException{formatErrorMessage(library_handle_maybe.error(), error_message)}; | ||
} | ||
library_handle_ = std::move(*library_handle_maybe); | ||
|
||
opentracing::expected<std::shared_ptr<opentracing::Tracer>> tracer_maybe = | ||
library_handle_.tracer_factory().MakeTracer(tracer_config.c_str(), error_message); | ||
if (!tracer_maybe) { | ||
throw EnvoyException{formatErrorMessage(tracer_maybe.error(), error_message)}; | ||
} | ||
tracer_ = std::move(*tracer_maybe); | ||
RELEASE_ASSERT(tracer_ != nullptr); | ||
} | ||
|
||
std::string DynamicOpenTracingDriver::formatErrorMessage(std::error_code error_code, | ||
const std::string& error_message) { | ||
if (error_message.empty()) { | ||
return fmt::format("{}", error_code.message()); | ||
} else { | ||
return fmt::format("{}: {}", error_code.message(), error_message); | ||
} | ||
} | ||
|
||
} // namespace Tracing | ||
} // namespace Envoy |
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,41 @@ | ||
#pragma once | ||
|
||
#include "envoy/runtime/runtime.h" | ||
#include "envoy/thread_local/thread_local.h" | ||
#include "envoy/tracing/http_tracer.h" | ||
#include "envoy/upstream/cluster_manager.h" | ||
|
||
#include "common/tracing/opentracing_driver_impl.h" | ||
|
||
#include "opentracing/dynamic_load.h" | ||
|
||
namespace Envoy { | ||
namespace Tracing { | ||
|
||
/** | ||
* This driver provides support for dynamically loading tracing libraries into Envoy that provide an | ||
* implementation of the OpenTracing API (see https://github.com/opentracing/opentracing-cpp). | ||
* TODO(rnburn): Add an example showing how to use a tracer library with this driver. | ||
*/ | ||
class DynamicOpenTracingDriver : public OpenTracingDriver { | ||
public: | ||
DynamicOpenTracingDriver(Stats::Store& stats, const std::string& library, | ||
const std::string& tracer_config); | ||
|
||
static std::string formatErrorMessage(std::error_code error_code, | ||
const std::string& error_message); | ||
|
||
// Tracer::OpenTracingDriver | ||
opentracing::Tracer& tracer() override { return *tracer_; } | ||
|
||
PropagationMode propagationMode() const override { | ||
return OpenTracingDriver::PropagationMode::TracerNative; | ||
} | ||
|
||
private: | ||
opentracing::DynamicTracingLibraryHandle library_handle_; | ||
std::shared_ptr<opentracing::Tracer> tracer_; | ||
}; | ||
|
||
} // namespace Tracing | ||
} // namespace Envoy |
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
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
37 changes: 37 additions & 0 deletions
37
source/server/config/http/dynamic_opentracing_http_tracer.cc
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 @@ | ||
#include "server/config/http/dynamic_opentracing_http_tracer.h" | ||
|
||
#include <string> | ||
|
||
#include "envoy/registry/registry.h" | ||
|
||
#include "common/common/utility.h" | ||
#include "common/config/well_known_names.h" | ||
#include "common/tracing/dynamic_opentracing_driver_impl.h" | ||
#include "common/tracing/http_tracer_impl.h" | ||
|
||
namespace Envoy { | ||
namespace Server { | ||
namespace Configuration { | ||
|
||
Tracing::HttpTracerPtr DynamicOpenTracingHttpTracerFactory::createHttpTracer( | ||
const Json::Object& json_config, Server::Instance& server, | ||
Upstream::ClusterManager& /*cluster_manager*/) { | ||
const std::string library = json_config.getString("library"); | ||
const std::string config = json_config.getObject("config")->asJsonString(); | ||
Tracing::DriverPtr dynamic_driver{ | ||
std::make_unique<Tracing::DynamicOpenTracingDriver>(server.stats(), library, config)}; | ||
return std::make_unique<Tracing::HttpTracerImpl>(std::move(dynamic_driver), server.localInfo()); | ||
} | ||
|
||
std::string DynamicOpenTracingHttpTracerFactory::name() { | ||
return Config::HttpTracerNames::get().DYNAMIC_OT; | ||
} | ||
|
||
/** | ||
* Static registration for the dynamic opentracing http tracer. @see RegisterFactory. | ||
*/ | ||
static Registry::RegisterFactory<DynamicOpenTracingHttpTracerFactory, HttpTracerFactory> register_; | ||
|
||
} // namespace Configuration | ||
} // namespace Server | ||
} // namespace Envoy |
29 changes: 29 additions & 0 deletions
29
source/server/config/http/dynamic_opentracing_http_tracer.h
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,29 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
|
||
#include "envoy/server/instance.h" | ||
|
||
#include "server/configuration_impl.h" | ||
|
||
namespace Envoy { | ||
namespace Server { | ||
namespace Configuration { | ||
|
||
/** | ||
* Config registration for the dynamic opentracing tracer. @see HttpTracerFactory. | ||
*/ | ||
class DynamicOpenTracingHttpTracerFactory : public HttpTracerFactory { | ||
public: | ||
// HttpTracerFactory | ||
Tracing::HttpTracerPtr createHttpTracer(const Json::Object& json_config, Server::Instance& server, | ||
Upstream::ClusterManager& cluster_manager) override; | ||
|
||
std::string name() override; | ||
|
||
bool requiresClusterName() const override { return false; } | ||
}; | ||
|
||
} // namespace Configuration | ||
} // namespace Server | ||
} // namespace Envoy |
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
Oops, something went wrong.