diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..fee94ae58b --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# OpenTelemetry Community Code of Conduct + +OpenTelemetry follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). diff --git a/README.md b/README.md index 3cb0634ce4..fc0b39480a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Slack](https://img.shields.io/badge/slack-@cncf/otel/cpp-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01N3AT62SJ) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-cpp/branch/main/graphs/badge.svg?)](https://codecov.io/gh/open-telemetry/opentelemetry-cpp/) [![Build -Status](https://action-badges.now.sh/open-telemetry/opentelemetry-cpp)](https://github.com/open-telemetry/opentelemetry-cpp/actions) +Status](https://github.com/open-telemetry/opentelemetry-cpp/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/open-telemetry/opentelemetry-cpp/actions) [![Release](https://img.shields.io/github/v/release/open-telemetry/opentelemetry-cpp?include_prereleases&style=)](https://github.com/open-telemetry/opentelemetry-cpp/releases/) The C++ [OpenTelemetry](https://opentelemetry.io/) client. diff --git a/api/include/opentelemetry/trace/propagation/http_trace_context.h b/api/include/opentelemetry/trace/propagation/http_trace_context.h index cc3527c286..12ca07200e 100644 --- a/api/include/opentelemetry/trace/propagation/http_trace_context.h +++ b/api/include/opentelemetry/trace/propagation/http_trace_context.h @@ -36,8 +36,8 @@ static const size_t kTraceParentSize = 55; // The HttpTraceContext provides methods to extract and inject // context into headers of HTTP requests with traces. // Example: -// HttpTraceContext().inject(setter, carrier, context); -// HttpTraceContext().extract(getter, carrier, context); +// HttpTraceContext().Inject(carrier, context); +// HttpTraceContext().Extract(carrier, context); class HttpTraceContext : public opentelemetry::context::propagation::TextMapPropagator { diff --git a/ci/setup_grpc.sh b/ci/setup_grpc.sh index eab6210e31..ed32f5e9d9 100755 --- a/ci/setup_grpc.sh +++ b/ci/setup_grpc.sh @@ -10,8 +10,10 @@ fi export BUILD_DIR=/tmp/ export INSTALL_DIR=/usr/local/ pushd $BUILD_DIR -git clone --recurse-submodules -b v1.34.0 https://github.com/grpc/grpc +git clone --depth=1 -b v1.34.0 https://github.com/grpc/grpc cd grpc +git submodule init +git submodule update --depth 1 mkdir -p cmake/build pushd cmake/build cmake -DgRPC_INSTALL=ON \ diff --git a/examples/http/server.cc b/examples/http/server.cc index a9f1a81e08..190f40eac1 100644 --- a/examples/http/server.cc +++ b/examples/http/server.cc @@ -25,7 +25,7 @@ class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback auto prop = opentelemetry::context::propagation::GlobalTextMapPropagator::GetGlobalPropagator(); auto current_ctx = opentelemetry::context::RuntimeContext::GetCurrent(); auto new_context = prop->Extract(carrier, current_ctx); - options.parent = GetSpanFromContext(new_context)->GetContext(); + options.parent = opentelemetry::trace::propagation::GetSpan(new_context)->GetContext(); // start span with parent context extracted from http header auto span = get_tracer("http-server") diff --git a/examples/http/tracer_common.h b/examples/http/tracer_common.h index 2f517e5601..276ed3d9a2 100644 --- a/examples/http/tracer_common.h +++ b/examples/http/tracer_common.h @@ -16,19 +16,6 @@ namespace { -// TBD - This function be removed once #723 is merged -inline nostd::shared_ptr GetSpanFromContext( - const opentelemetry::context::Context &context) -{ - opentelemetry::context::ContextValue span = context.GetValue(opentelemetry::trace::kSpanKey); - if (nostd::holds_alternative>(span)) - { - return nostd::get>(span); - } - static nostd::shared_ptr invalid_span{ - new opentelemetry::trace::DefaultSpan(opentelemetry::trace::SpanContext::GetInvalid())}; - return invalid_span; -} template class HttpTextMapCarrier : public opentelemetry::context::propagation::TextMapCarrier diff --git a/ext/src/http/client/curl/CMakeLists.txt b/ext/src/http/client/curl/CMakeLists.txt index 4208de0607..2f63a686aa 100644 --- a/ext/src/http/client/curl/CMakeLists.txt +++ b/ext/src/http/client/curl/CMakeLists.txt @@ -5,7 +5,12 @@ if(CURL_FOUND) set_target_properties(http_client_curl PROPERTIES EXPORT_NAME http_client_curl) - target_link_libraries(http_client_curl PUBLIC CURL::libcurl) + if(TARGET CURL::libcurl) + target_link_libraries(http_client_curl PUBLIC CURL::libcurl) + else() + include_directories(${CURL_INCLUDE_DIRS}) + target_link_libraries(http_client_curl PUBLIC ${CURL_LIBRARIES}) + endif() install( TARGETS http_client_curl diff --git a/sdk/src/trace/span.cc b/sdk/src/trace/span.cc index 395b3c3dd7..32eba9cbec 100644 --- a/sdk/src/trace/span.cc +++ b/sdk/src/trace/span.cc @@ -47,11 +47,11 @@ Span::Span(std::shared_ptr &&tracer, const trace_api::SpanContextKeyValueIterable &links, const trace_api::StartSpanOptions &options, const trace_api::SpanContext &parent_span_context, - const nostd::shared_ptr trace_state, - const bool sampled) noexcept + std::unique_ptr span_context) noexcept : tracer_{std::move(tracer)}, recordable_{tracer_->GetProcessor().MakeRecordable()}, start_steady_time{options.start_steady_time}, + span_context_(std::move(span_context)), has_ended_{false} { if (recordable_ == nullptr) @@ -60,32 +60,9 @@ Span::Span(std::shared_ptr &&tracer, } recordable_->SetName(name); recordable_->SetInstrumentationLibrary(tracer_->GetInstrumentationLibrary()); - - trace_api::TraceId trace_id; - trace_api::SpanId span_id = tracer_->GetIdGenerator().GenerateSpanId(); - trace_api::SpanId parent_span_id; - bool is_parent_span_valid = false; - - if (parent_span_context.IsValid()) - { - trace_id = parent_span_context.trace_id(); - parent_span_id = parent_span_context.span_id(); - is_parent_span_valid = true; - } - else - { - trace_id = tracer_->GetIdGenerator().GenerateTraceId(); - } - - span_context_ = std::unique_ptr(new trace_api::SpanContext( - trace_id, span_id, - sampled ? trace_api::TraceFlags{trace_api::TraceFlags::kIsSampled} : trace_api::TraceFlags{}, - false, - trace_state ? trace_state - : is_parent_span_valid ? parent_span_context.trace_state() - : trace_api::TraceState::GetDefault())); - - recordable_->SetIdentity(*span_context_, parent_span_id); + recordable_->SetIdentity(*span_context_, parent_span_context.IsValid() + ? parent_span_context.span_id() + : trace_api::SpanId()); attributes.ForEachKeyValue( [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { diff --git a/sdk/src/trace/span.h b/sdk/src/trace/span.h index decb2d89c9..b0c674d98a 100644 --- a/sdk/src/trace/span.h +++ b/sdk/src/trace/span.h @@ -21,9 +21,7 @@ class Span final : public trace_api::Span const trace_api::SpanContextKeyValueIterable &links, const trace_api::StartSpanOptions &options, const trace_api::SpanContext &parent_span_context, - const nostd::shared_ptr trace_state = - trace_api::TraceState::GetDefault(), - const bool sampled = false) noexcept; + std::unique_ptr span_context) noexcept; ~Span() override; diff --git a/sdk/src/trace/tracer.cc b/sdk/src/trace/tracer.cc index 57558def28..3cbc978576 100644 --- a/sdk/src/trace/tracer.cc +++ b/sdk/src/trace/tracer.cc @@ -5,6 +5,8 @@ #include "opentelemetry/version.h" #include "src/trace/span.h" +#include + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -22,11 +24,26 @@ nostd::shared_ptr Tracer::StartSpan( const trace_api::SpanContextKeyValueIterable &links, const trace_api::StartSpanOptions &options) noexcept { - trace_api::SpanContext parent = + trace_api::SpanContext parent_context = options.parent.IsValid() ? options.parent : GetCurrentSpan()->GetContext(); - auto sampling_result = context_->GetSampler().ShouldSample(parent, parent.trace_id(), name, + trace_api::TraceId trace_id; + trace_api::SpanId span_id = GetIdGenerator().GenerateSpanId(); + bool is_parent_span_valid = false; + + if (parent_context.IsValid()) + { + trace_id = parent_context.trace_id(); + is_parent_span_valid = true; + } + else + { + trace_id = GetIdGenerator().GenerateTraceId(); + } + + auto sampling_result = context_->GetSampler().ShouldSample(parent_context, trace_id, name, options.kind, attributes, links); + if (sampling_result.decision == Decision::DROP) { // Don't allocate a no-op span for every DROP decision, but use a static @@ -38,9 +55,16 @@ nostd::shared_ptr Tracer::StartSpan( } else { + + auto span_context = std::unique_ptr(new trace_api::SpanContext( + trace_id, span_id, trace_api::TraceFlags{trace_api::TraceFlags::kIsSampled}, false, + sampling_result.trace_state ? sampling_result.trace_state + : is_parent_span_valid ? parent_context.trace_state() + : trace_api::TraceState::GetDefault())); + auto span = nostd::shared_ptr{ - new (std::nothrow) Span{this->shared_from_this(), name, attributes, links, options, parent, - sampling_result.trace_state, true}}; + new (std::nothrow) Span{this->shared_from_this(), name, attributes, links, options, + parent_context, std::move(span_context)}}; // if the attributes is not nullptr, add attributes to the span. if (sampling_result.attributes) diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index e5775b812b..bf912744ea 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -21,25 +21,37 @@ using opentelemetry::exporter::memory::InMemorySpanExporter; using opentelemetry::trace::SpanContext; /** - * A mock sampler that returns non-empty sampling results attributes. + * A mock sampler with ShouldSample returning: + * Decision::RECORD_AND_SAMPLE if trace_id is valid + * Decision::DROP otherwise. */ class MockSampler final : public Sampler { public: SamplingResult ShouldSample( const SpanContext & /*parent_context*/, - trace_api::TraceId /*trace_id*/, + trace_api::TraceId trace_id, nostd::string_view /*name*/, trace_api::SpanKind /*span_kind*/, const opentelemetry::common::KeyValueIterable & /*attributes*/, const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/) noexcept override { - // Return two pairs of attributes. These attributes should be added to the - // span attributes - return {Decision::RECORD_AND_SAMPLE, - nostd::unique_ptr>( - new const std::map( - {{"sampling_attr1", 123}, {"sampling_attr2", "string"}}))}; + // Sample only if valid trace_id ( This is to test Sampler get's valid trace id) + if (trace_id.IsValid()) + { + // Return two pairs of attributes. These attributes should be added to the + // span attributes + return {Decision::RECORD_AND_SAMPLE, + nostd::unique_ptr>( + new const std::map( + {{"sampling_attr1", 123}, {"sampling_attr2", "string"}}))}; + } + else + { + // we should never reach here + assert(false); + return {Decision::DROP}; + } } nostd::string_view GetDescription() const noexcept override { return "MockSampler"; } @@ -599,3 +611,15 @@ TEST(Tracer, ExpectParent) EXPECT_EQ(spandata_first->GetSpanId(), spandata_second->GetParentSpanId()); EXPECT_EQ(spandata_second->GetSpanId(), spandata_third->GetParentSpanId()); } + +TEST(Tracer, ValidTraceIdToSampler) +{ + std::unique_ptr exporter(new InMemorySpanExporter()); + std::shared_ptr span_data = exporter->GetData(); + auto tracer = initTracer(std::move(exporter), new MockSampler()); + + auto span = tracer->StartSpan("span 1"); + // sampler was fed with valid trace_id, so span shouldn't be NoOp Span. + EXPECT_TRUE(span->IsRecording()); + EXPECT_TRUE(span->GetContext().IsValid()); +}