-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tracing: Support OpenTracing API #2017
Conversation
8d67e8f
to
3f2ed0d
Compare
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Thanks @rnburn. This is great. I will spend time with this tomorrow morning. |
@jmillikin-stripe this is related I think to our other conversation yesterday about the warnings. If possible can you review the bazel portion of this change? @htuch also? I will review the code. |
That opentracing/lightstep build stuff looks painful. Lets see if we can convince them to put some BUILD files in their repo. Their libraries don't look complicated, so hopefully they'll be OK with it. I'll send them PRs and link them here. |
OpenTracing PR: opentracing/opentracing-cpp#37 |
Thanks. I'm fine with supporting bazel builds in those projects. I just merged in the PR for opentracing. |
@rnburn Thanks, that's great to know! I've sent another PR for Lightstep's C++ tracer: lightstep/lightstep-tracer-cpp#85 The BUILD files for Lightstep are a bit strange because it vendors part of |
Thanks. The googleapis were copied in because they're not installed anywhere as part of gRPC's build for C++. And putting the lightstep proto headers in the system include was done so that the compiler warnings won't apply to them (which they will if they're included normally). |
Sure, but |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is cool stuff. Some comments to get started. I'm going to need to take multiple passes through this as we start making changes. Thank you for your effort on this.
span_.SetOperationName(operation); | ||
Grpc::Common::chargeStat(*driver_.cluster(), lightstep::CollectorServiceFullName(), | ||
lightstep::CollectorMethodName(), true); | ||
if (!Grpc::Common::deserializeBody(response->bodyAsString(), *active_response_)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This involves multiple copies of the body through the entire code path. You should be able to use https://github.com/envoyproxy/envoy/blob/master/source/common/buffer/zero_copy_input_stream_impl.h after draining off the first 5 bytes of the response. Take a look at how this is used elsewhere in similar situations. Then you can remove the added deserializeBody function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
lightstep::CollectorMethodName()); | ||
message->body() = Grpc::Common::serializeBody(request); | ||
|
||
uint64_t timeout = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
|
||
void LightStepRecorder::enableTimer() { | ||
void LightStepDriver::TlsLightStepTracer::enableTimer() { | ||
uint64_t flush_interval = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: const
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
tls_options.use_single_key_propagation = true; | ||
tls_options.logger_sink = LightStepLogger{}; | ||
tls_options.max_buffered_spans = std::function<size_t()>{[this] { | ||
auto result = runtime_.snapshot().getInteger("tracing.lightstep.min_flush_spans", 5U); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: just return, don't need local var
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -399,6 +399,23 @@ void HeaderMapImpl::iterateReverse(ConstIterateCb cb, void* context) const { | |||
} | |||
} | |||
|
|||
HeaderMap::Lookup HeaderMapImpl::lookup(const LowerCaseString& key, | |||
const HeaderEntry** entry) const { | |||
StaticLookupEntry::EntryCb cb = ConstSingleton<StaticLookupTable>::get().find(key.get().c_str()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we potentially have a findConst() or something which returns a ConstEntryCb so that we don't need the const_cast below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Via a macro, each of the O(1) headers adds a lambda funtion that takes HTTPHeaderMapImpl&
as an argument. The only way I see around const_cast is to have them also add entries for a const HTTPHeaderMapImpl&
lambda.
IMO const_cast is the better option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could go either way. I think it's slightly cleaner to have the init code add a const callback and then have a fineConst(), but I'm ok with this. I would just add a comment on the tradeoff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment for const_cast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: For the next person that comes along and asks "why const_cast" can you add a brief additional comment on the tradeoffs between this and ^.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added explanation for choosing const_cast.
SpanPtr OpenTracingSpan::spawnChild(const Config&, const std::string& name, SystemTime start_time) { | ||
std::unique_ptr<opentracing::Span> ot_span = span_->tracer().StartSpan( | ||
name, {opentracing::ChildOf(&span_->context()), opentracing::StartTimestamp(start_time)}); | ||
if (ot_span == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when does this return nullptr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the OpenTracing API is noexcept. LightStep's StartSpan would only return nullptr if something like std::bad_alloc
was thrown while it was trying to allocate memory. I could change this to use RELEASE_ASSERT since nullptr would likely mean the application is on the verge of crashing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah preference to either use RELEASE_ASSERT for these types of things or in the case of nullptr just let Envoy crash via null-ptr dereference.
const opentracing::expected<void> was_successful = | ||
span_->tracer().Inject(span_->context(), oss); | ||
if (!was_successful) { | ||
ENVOY_LOG(warn, "Failed to inject span context: {}", was_successful.error().message()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comments as below on error handling (sorry comments are coming out of order). In general, error handling should:
- not log above debug if it can happen via user supplied input
- stat
- if it's something that just shouldn't happen, it should be an ASSERT or possibly RELEAS_ASSERT (please see error handling section in style guide)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to log at debug level, but still need to add a stat.
void OpenTracingSpan::injectContext(Http::HeaderMap& request_headers) { | ||
if (use_single_header_propagation_) { | ||
// Inject the span context using Envoy's single-header format. | ||
std::ostringstream oss; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as below about string stream
parent_span_ctx_maybe.error().message()); | ||
} | ||
} else if (use_tracer_propagation) { | ||
const OpenTracingHTTPHeadersReader reader{request_headers}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From looking through, I think LS driver uses this path, but not the other one. Do we have Envoy test coverage to 100% on the other paths? (Please see coverage report in CI). We will need coverage for both paths.
Also, what header is the LS driver actually using in the current version when it goes through this path? x-ot-span-ctx? Or some new header? It's not super clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add test coverage for the other path.
It's using the same x-ot-span-context header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added test coverage for the other code path.
namespace Envoy { | ||
namespace Tracing { | ||
|
||
class OpenTracingSpan : public Span, Logger::Loggable<Logger::Id::tracing> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have some links to docs here or just a set of comments somewhere on how a driver is actually created? It's a little confusing to me re: what the various propagation modes are, what the driver implements, how the header lookup code works (in terms of what the OT code expects), etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added documentation.
@jmillikin-stripe -- yeah, the path could be changed like that. I just meant having them included with |
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
I just verified that the following Bazel repository entries work as expected with the new Lightstep/OpenTracing build rules: native.git_repository(
name = "io_opentracing_cpp",
remote = "https://github.com/opentracing/opentracing-cpp",
commit = "713c15d40ae63185d2bec99bf3b03823967d7108",
)
native.git_repository(
name = "com_lightstep_tracer_cpp",
remote = "https://github.com/lightstep/lightstep-tracer-cpp",
commit = "LIGHTSTEP_COMMIT_HERE",
)
native.new_git_repository(
name = "com_lightstep_tracer_common",
remote = "https://github.com/lightstep/lightstep-tracer-common",
commit = "3943f3f04e3547e7e68d7900ef2efde045fa8901",
build_file = "@com_lightstep_tracer_cpp//:lightstep-tracer-common/BUILD",
)
native.new_git_repository(
name = "lightstep_vendored_googleapis",
remote = "https://github.com/google/googleapis",
commit = "d6f78d948c53f3b400bb46996eb3084359914f9b",
build_file = "@com_lightstep_tracer_cpp//:lightstep-tracer-common/third_party/googleapis/BUILD",
)
native.bind(
name="lightstep",
actual="@com_lightstep_tracer_cpp//:lightstep_tracer",
) For the things that lightstep-tracer-cpp is vendoring, I used the commits in the LS readme files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat stuff.
include/envoy/http/header_map.h
Outdated
enum class Lookup { Found, NotFound, NotSupported }; | ||
|
||
/** | ||
* Lookup one of the O(1) headers by key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be clearer to refer to these as something like "predefined inline header (see ALL_INLINE_HEADERS below)". Using the complexity alone elides the semantic info here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed naming.
void LightStepSpan::finishSpan() { span_.Finish(); } | ||
void LightStepDriver::LightStepTransporter::onSuccess(Http::MessagePtr&& response) { | ||
try { | ||
Grpc::Common::validateResponse(*response); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Envoy has a gRPC client layered above Http::AsyncClient
in https://github.com/envoyproxy/envoy/blob/master/source/common/grpc/async_client_impl.h. Can you make use of this? This would avoid having to hand parse out gRPC messages..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grpc::AsyncClientImpl
can't be used with an abstract base class for the response since it constructs an instance of the class.
I'd rather not expose LightStep's protobuf message types directly since that would provide less encapsulation and potentially break code using the library if they were to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I discussed this a while ago with @htuch and although I think we could fixup the gRPC async client to work OK with raw messages, don't worry about this for now. I would potentially just add a TODO to look into cleaning this up in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added TODO note.
} | ||
} | ||
|
||
opentracing::expected<void> ForeachKey(OpenTracingCb f) const override { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: forEachKey
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function comes from the the OT API and since it's override a virtual function the name has to match.
private: | ||
const Http::HeaderMap& request_headers_; | ||
|
||
static Http::HeaderMap::Iterate header_map_callback(const Http::HeaderEntry& header, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: headerMapCallback
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed.
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
@@ -4,7 +4,6 @@ cc_library( | |||
name = "all_external", | |||
srcs = [":empty.cc"], | |||
deps = [ | |||
"@com_github_lightstep_lightstep_tracer_cpp//:lightstep", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This target is used to pre-build the dependencies when generating the Docker image. We still want to pre-build Lightstep and all its deps since they're pretty big.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
bazel/repositories.bzl
Outdated
@@ -312,23 +313,36 @@ def _com_github_gcovr_gcovr(): | |||
actual = "@com_github_gcovr_gcovr//:gcovr", | |||
) | |||
|
|||
def _com_github_opentracing_opentracing_cpp(): | |||
location = REPOSITORY_LOCATIONS[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use _repository_impl()
here so that downstream builders of Envoy can override the dependency definition.
_repository_impl("io_opentracing_cpp")
native.bind(
name = "opentracing",
actual = "@io_opentracing_cpp//:opentracing",
)
You'll want to adjust the repository_locations.bzl
name to match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to use _repository_impl and matched names to keys in REPOSITORY_LOCATIONS.
bazel/repositories.bzl
Outdated
], | ||
genrule_cmd_file = "@envoy//bazel/external:lightstep.genrule_cmd", | ||
build_file = "@envoy//bazel/external:lightstep.BUILD", | ||
native.git_repository( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
bazel/repository_locations.bzl
Outdated
urls = ["https://github.com/lightstep/lightstep-tracer-cpp/releases/download/v0_36/lightstep-tracer-cpp-0.36.tar.gz"], | ||
commit = "c9d9215b5c3652c7eb5640903697d9a683e1df76", | ||
remote = "https://github.com/lightstep/lightstep-tracer-cpp", | ||
googleapis = dict( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's pretty confusing to have this extra level of nesting. How about giving googleapis its own location?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separated out. Is it ok to build target in the same function as lightstep?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. The functions only exist for human readability, and it makes sense to have all the lightstep stuff in one place.
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
@mattklein123 -- this should be ready for another round of reviewing. I think I addressed all the comments except for the concerns on stringstream performance. There were some objections on opentracing/opentracing-cpp#42 to adding more direct binary propagation support for strings. I changed the span context extraction code to use a more efficient version of std::istream that doesn't copy the data string (unlike std::istringstream), but it's still using std::ostringstream for injection since I don't know that there's an easy way to make a faster replacement (see StackOverflow). |
@rnburn FYI I'm trying to get the 1.5.0 release out the door so I might be a bit delayed in looking at this. Sorry. It's on my backlog. |
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking solid. A bunch of random nits. Excited to move this forward.
@lita: Can you please work with @goaway and @junr03 to smoke test this change on a front Envoy edge node at Lyft. This is a pretty scary change and I would like to get a quick sanity test on this before we merge. Thank you!
source/common/common/utility.h
Outdated
/** | ||
* Class used for creating non-copying std::istream's. See IMemoryStream below. | ||
*/ | ||
class MemoryStreamBuffer : public std::streambuf { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can we call this ConstMemoryStreamBuffer
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed.
source/common/common/utility.h
Outdated
* | ||
* See https://stackoverflow.com/a/13059195/4447365. | ||
*/ | ||
class IMemoryStream : public virtual MemoryStreamBuffer, public std::istream { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: InputConstMemoryStream
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed.
@@ -399,6 +399,23 @@ void HeaderMapImpl::iterateReverse(ConstIterateCb cb, void* context) const { | |||
} | |||
} | |||
|
|||
HeaderMap::Lookup HeaderMapImpl::lookup(const LowerCaseString& key, | |||
const HeaderEntry** entry) const { | |||
StaticLookupEntry::EntryCb cb = ConstSingleton<StaticLookupTable>::get().find(key.get().c_str()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: For the next person that comes along and asks "why const_cast" can you add a brief additional comment on the tradeoffs between this and ^.
namespace { | ||
class LightStepLogger : Logger::Loggable<Logger::Id::tracing> { | ||
public: | ||
void operator()(lightstep::LogLevel level, opentracing::string_view message) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with opentracing::string_view
. Can this by passed by const reference? Same Q in a bunch of other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could, but it's usually faster to take small objects like string_view
by value.
Also, passing by value will be the convention for std::string_view
and is what's done in the C++17 standard library. (See for example operator<<
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure how it can be faster to pass small objects by value vs. reference (would be curious if you have doc/article I can read on that), but totally fine to leave as is if that's what C++17 will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The members of small objects can get split and passed in registers, so accessing std::string_view::data
can be a simple read from the register. If it's passed by const std::string_view&
then it needs to go through an extra dereference to access std::string_view::data
. You can see it in the generated assembly.
template <typename T>
void do_not_optimize_away(T const& val) {
asm volatile("" : : "g"(val) : "memory");
}
void f1(std::string_view s) {
char x = *s.data();
char y = x + (char)1;
do_not_optimize_away(y);
}
void f2(const std::string_view& s) {
char x = *s.data();
char y = x + (char)1;
do_not_optimize_away(y);
}
compiled with g++ -O3 -S
shows
f1:
.globl __Z2f1St17basic_string_viewIcSt11char_traitsIcEE
__Z2f1St17basic_string_viewIcSt11char_traitsIcEE:
LFB758:
movzbl (%rsi), %eax
addl $1, %eax
ret
and f2:
.globl __Z2f2RKSt17basic_string_viewIcSt11char_traitsIcEE
__Z2f2RKSt17basic_string_viewIcSt11char_traitsIcEE:
LFB759:
movq 8(%rdi), %rax
movzbl (%rax), %eax
addl $1, %eax
ret
Note the extra dereferencing instructions in f2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, that makes sense. Thanks for the explanation!
Event::Dispatcher& dispatcher) | ||
: builder_(tracer), driver_(driver) { | ||
LightStepDriver::TlsLightStepTracer::TlsLightStepTracer( | ||
std::shared_ptr<lightstep::LightStepTracer>&& tracer, LightStepDriver& driver, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: moving shared_ptr is a little bit of an anti-pattern IMO. I would let compiler optimize this and just pass normally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
|
||
Upstream::ClusterManager& clusterManager() { return cm_; } | ||
Upstream::ClusterInfoConstSharedPtr cluster() { return cluster_; } | ||
Runtime::Loader& runtime() { return runtime_; } | ||
LightstepTracerStats& tracerStats() { return tracer_stats_; } | ||
void setPropagationMode(PropagationMode propagation_mode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any reason this can't be passed via constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add it as a constructor argument also. I only put it there for testing to get coverage for the different versions of Inject/Extract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the tests can you use constructor to construct a new driver? IMO it's cleaner to have this be part of object creation and not settable. If it's really required for testing please call it setPropagationModeForTest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to use constructor.
// Tracer::TracingDriver | ||
SpanPtr startSpan(const Config& config, Http::HeaderMap& request_headers, | ||
const std::string& operation_name, SystemTime start_time) override; | ||
// Tracer::OpenTracingDriver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super nit: overrides (with comment) go below other functions in a specific visibility scope (so it's clear what is what).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rearranged.
return opentracing::make_unexpected(opentracing::key_not_found_error); | ||
case Http::HeaderMap::Lookup::NotSupported: | ||
return opentracing::make_unexpected(opentracing::lookup_key_not_supported_error); | ||
default: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just remove the default, and put the NOT_REACHED at the end of the function.
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you @rnburn! We will get this some tested early this week.
@@ -105,7 +103,7 @@ class LightStepDriver : public OpenTracingDriver { | |||
ThreadLocal::SlotPtr tls_; | |||
Runtime::Loader& runtime_; | |||
std::unique_ptr<lightstep::LightStepTracerOptions> options_; | |||
PropagationMode propagation_mode_ = PropagationMode::TracerNative; | |||
PropagationMode propagation_mode_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be const now I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Signed-off-by: Ryan Burn <ryan.burn@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rnburn @lita just finished up a smoke test. Things look good. I took a look a perf profile and this does already look better than the old setup from an allocation/copy perspective, but I think there is more we can do here. We can chat about it offline and iterate.
Thank you for seeing this through!!!
@mattklein123 Thanks. Improving the performance is definitely something I'm going to look into. I expect there are quite a few cases in the OpenTracing API where we can use move semantics to avoid unnecessary allocations. |
@rnburn what should trigger a change in the commit versions for opentracing_cpp and lightstep_tracer_cpp? Should this match to releases for the project or should there be some other trigger to update? They are currently:
lightstep_tracer_cpp is 12 commits ahead of the latest release and opentracing_cpp is behind the latest minor version bump but ahead of the latest release. |
I put in a release for the lightstep tracer for the bazel support so that envoy is now synced to 0.6.0. I also put in #2226 to update opentracing to match the commit for version 1.2.0. |
Does it also provides the capability to use jaeger as a tracing solution since it is based on OpenTracing standard? |
@abbi-gaurav Not yet. Jaeger has some compatibility with Zipkin so you can report spans to it using the Zipkin tracer (example), but it won't interoperate with other jaeger tracing without changes to the setup and it won't support sampling. I'm working on a PR (#2252) that will let you dynamically load in a tracer library, which would allow you to use Jaeger's C++ client directly. I have a small example that shows how it can work, but it's still under development. |
* Add a new TCP cluster rewrite filter This commit adds a new TCP cluster rewrite filter which allows users to rewrite TCP cluster names obtained via TLS SNI by matching via regex configuration. Signed-off-by: Venil Noronha <veniln@vmware.com> * Make TCP cluster rewrite stackable on SNI filter This commit updates the TCP Cluster Rewrite filter to be stackable on the SNI Cluster filter. Signed-off-by: Venil Noronha <veniln@vmware.com>
This commit adds a new TCP cluster rewrite filter which allows users to rewrite TCP cluster names obtained via TLS SNI by matching via regex configuration. Signed-off-by: Venil Noronha <veniln@vmware.com>
* Improve performance by removing MD5 for check cache keys (envoyproxy#2002) * Improve performance by removing MD5 for check cache keys Signed-off-by: Wayne Zhang <qiwzhang@google.com> * not to allocate memory from stack Signed-off-by: Wayne Zhang <qiwzhang@google.com> * Make debug string readable Signed-off-by: Wayne Zhang <qiwzhang@google.com> * alts: remove ALTS (envoyproxy#2003) Signed-off-by: Lizan Zhou <lizan@tetrate.io> * Use std::hash for check cache. (envoyproxy#2009) Signed-off-by: Wayne Zhang <qiwzhang@google.com> * Remove tests to compare signature values (envoyproxy#2015) Signed-off-by: Wayne Zhang <qiwzhang@google.com> * update sample envoy config to latest version (envoyproxy#2016) * Add a new TCP cluster rewrite filter (envoyproxy#2017) * Add a new TCP cluster rewrite filter This commit adds a new TCP cluster rewrite filter which allows users to rewrite TCP cluster names obtained via TLS SNI by matching via regex configuration. Signed-off-by: Venil Noronha <veniln@vmware.com> * Make TCP cluster rewrite stackable on SNI filter This commit updates the TCP Cluster Rewrite filter to be stackable on the SNI Cluster filter. Signed-off-by: Venil Noronha <veniln@vmware.com> * Update TCP Cluster Rewrite filter name (envoyproxy#2019) This commit updates the TCP Cluster Rewrite filter name to envoy.filters.network.tcp_cluster_rewrite. Signed-off-by: Venil Noronha <veniln@vmware.com> * Enable TCP Cluster Rewrite filter registration (envoyproxy#2021) This commit enables the static registration of the TCP Cluster Rewrite filter by updating the build configuration. Signed-off-by: Venil Noronha <veniln@vmware.com> * Update Envoy SHA to 4ef8562 (envoyproxy#2023) Envoy /server_info API was inconsistent intermittently causing errors on a Proxy update on Istio. This update will bring in the API fix to Istio. Signed-off-by: Venil Noronha <veniln@vmware.com> * add proxy postsubmit periodic (envoyproxy#2025)
* Improve performance by removing MD5 for check cache keys (envoyproxy#2002) * Improve performance by removing MD5 for check cache keys Signed-off-by: Wayne Zhang <qiwzhang@google.com> * not to allocate memory from stack Signed-off-by: Wayne Zhang <qiwzhang@google.com> * Make debug string readable Signed-off-by: Wayne Zhang <qiwzhang@google.com> * alts: remove ALTS (envoyproxy#2003) Signed-off-by: Lizan Zhou <lizan@tetrate.io> * Use std::hash for check cache. (envoyproxy#2009) Signed-off-by: Wayne Zhang <qiwzhang@google.com> * Remove tests to compare signature values (envoyproxy#2015) Signed-off-by: Wayne Zhang <qiwzhang@google.com> * update sample envoy config to latest version (envoyproxy#2016) * Add a new TCP cluster rewrite filter (envoyproxy#2017) * Add a new TCP cluster rewrite filter This commit adds a new TCP cluster rewrite filter which allows users to rewrite TCP cluster names obtained via TLS SNI by matching via regex configuration. Signed-off-by: Venil Noronha <veniln@vmware.com> * Make TCP cluster rewrite stackable on SNI filter This commit updates the TCP Cluster Rewrite filter to be stackable on the SNI Cluster filter. Signed-off-by: Venil Noronha <veniln@vmware.com> * Update TCP Cluster Rewrite filter name (envoyproxy#2019) This commit updates the TCP Cluster Rewrite filter name to envoy.filters.network.tcp_cluster_rewrite. Signed-off-by: Venil Noronha <veniln@vmware.com> * Enable TCP Cluster Rewrite filter registration (envoyproxy#2021) This commit enables the static registration of the TCP Cluster Rewrite filter by updating the build configuration. Signed-off-by: Venil Noronha <veniln@vmware.com> * Update Envoy SHA to 4ef8562 (envoyproxy#2023) Envoy /server_info API was inconsistent intermittently causing errors on a Proxy update on Istio. This update will bring in the API fix to Istio. Signed-off-by: Venil Noronha <veniln@vmware.com> * add proxy postsubmit periodic (envoyproxy#2025) * Update Envoy SHA to c41fa71 (envoyproxy#2029) * Update Envoy SHA Signed-off-by: JimmyCYJ <jimmychen.0102@gmail.com> * Fix format. Signed-off-by: JimmyCYJ <jimmychen.0102@gmail.com> * bazel: Allow to distdir all dependencies (envoyproxy#2034) To use --distdir option of Bazel (which allows to use previously fetched tarballs instead of downloading dependencies during build), all dependencies should use http instead of git and need to have sha256 sums specified. Signed-off-by: Michal Rostecki <mrostecki@suse.de> * bazel: Remove BoringSSL repository (envoyproxy#2035) Pull request envoyproxy#2002 removed signature calculation which was using BoringSSL as a dependency. BoringSSL is not needed anymore. Signed-off-by: Michal Rostecki <mrostecki@suse.de> * Update Envoy SHA to fcc68f1 (envoyproxy#2037) * Update Envoy SHA to fcc68f1 Signed-off-by: JimmyCYJ <jimmychen.0102@gmail.com> * Update SHA256 Signed-off-by: JimmyCYJ <jimmychen.0102@gmail.com>
Description:
OpenTracingDriver
that implementsTracing::Driver
using the OpenTracing API. With it, an OpenTracing-compliant tracer can be added into envoy by deriving fromOpenTracingDrive
r and implementing the abstracttracer
method, reducing the amount of code that must be maintained for each tracer implementation.OpenTracingDriver
. The latest version of LightStep provides a customizable transport, so the code that implements an Envoy-specific Reporter and interacts directly with LightStep's protobuf classes was removed in order to bind less tightly to the LightStep code.A few notes:
Http::HeaderMap::lookup
that takes a header key and uses theStaticLookupTable
to find the header's entry. If the tracer's headers don't belong to the O(1) list, propagation will still work; but the tracer will have to iterate through all of the entries.CC=""
toopentracing.genrule_cmd
andlightstep.genrule_cmd
in order to work around the problem. (Not sure if there's a better solution.)Fixes #1196
Risk Level: High
Testing:
Http::HeaderMap::lookup
function.