Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
Karen Xu committed Oct 17, 2020
2 parents 5c8e9b3 + 5c89114 commit 29898c7
Show file tree
Hide file tree
Showing 18 changed files with 450 additions and 142 deletions.
14 changes: 11 additions & 3 deletions sdk/include/opentelemetry/sdk/trace/sampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ class Sampler
/**
* Called during Span creation to make a sampling decision.
*
* @param parent_context a const pointer of the SpanContext of a parent Span.
* null if this is a root span.
* @param parent_context a const reference to the SpanContext of a parent Span.
* An invalid SpanContext if this is a root span.
* @param trace_id the TraceId for the new Span. This will be identical to that in
* the parentContext, unless this is a root span.
* the parentContext, unless this is a root span.
* @param name the name of the new Span.
* @param spanKind the trace_api::SpanKind of the Span.
* @param attributes list of AttributeValue with their keys.
Expand All @@ -65,12 +65,20 @@ class Sampler
* @since 0.1.0
*/

<<<<<<< HEAD
virtual SamplingResult ShouldSample(
const trace_api::SpanContext *parent_context,
trace_api::TraceId trace_id,
nostd::string_view name,
trace_api::SpanKind span_kind,
const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0;
=======
virtual SamplingResult ShouldSample(const trace_api::SpanContext &parent_context,
trace_api::TraceId trace_id,
nostd::string_view name,
trace_api::SpanKind span_kind,
const trace_api::KeyValueIterable &attributes) noexcept = 0;
>>>>>>> origin/master

/**
* Returns the sampler name or short description with the configuration.
Expand Down
11 changes: 5 additions & 6 deletions sdk/include/opentelemetry/sdk/trace/samplers/always_off.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ class AlwaysOffSampler : public Sampler
/**
* @return Returns DROP always
*/
SamplingResult ShouldSample(
const trace_api::SpanContext * /*parent_context*/,
trace_api::TraceId /*trace_id*/,
nostd::string_view /*name*/,
trace_api::SpanKind /*span_kind*/,
const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override
SamplingResult ShouldSample(const trace_api::SpanContext & /*parent_context*/,
trace_api::TraceId /*trace_id*/,
nostd::string_view /*name*/,
trace_api::SpanKind /*span_kind*/,
const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override
{
return {Decision::DROP, nullptr};
}
Expand Down
2 changes: 1 addition & 1 deletion sdk/include/opentelemetry/sdk/trace/samplers/always_on.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class AlwaysOnSampler : public Sampler
* @return Always return Decision RECORD_AND_SAMPLE
*/
inline SamplingResult ShouldSample(
const trace_api::SpanContext * /*parent_context*/,
const trace_api::SpanContext & /*parent_context*/,
trace_api::TraceId /*trace_id*/,
nostd::string_view /*name*/,
trace_api::SpanKind /*span_kind*/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,25 @@ namespace trace
namespace trace_api = opentelemetry::trace;

/**
* The parent or else sampler is a composite sampler. ParentOrElse(delegateSampler) either respects
* The ParentBased sampler is a composite sampler. ParentBased(delegateSampler) either respects
* the parent span's sampling decision or delegates to delegateSampler for root spans.
*/
class ParentOrElseSampler : public Sampler
class ParentBasedSampler : public Sampler
{
public:
explicit ParentOrElseSampler(std::shared_ptr<Sampler> delegate_sampler) noexcept;
explicit ParentBasedSampler(std::shared_ptr<Sampler> delegate_sampler) noexcept;
/** The decision either respects the parent span's sampling decision or delegates to
* delegateSampler for root spans
* @return Returns DROP always
*/
SamplingResult ShouldSample(
const trace_api::SpanContext *parent_context,
trace_api::TraceId trace_id,
nostd::string_view name,
trace_api::SpanKind span_kind,
const opentelemetry::common::KeyValueIterable &attributes) noexcept override;
SamplingResult ShouldSample(const trace_api::SpanContext &parent_context,
trace_api::TraceId trace_id,
nostd::string_view name,
trace_api::SpanKind span_kind,
const opentelemetry::common::KeyValueIterable &attributes) noexcept override;

/**
* @return Description MUST be ParentOrElse{delegate_sampler_.getDescription()}
* @return Description MUST be ParentBased{delegate_sampler_.getDescription()}
*/
nostd::string_view GetDescription() const noexcept override;

Expand Down
50 changes: 0 additions & 50 deletions sdk/include/opentelemetry/sdk/trace/samplers/probability.h

This file was deleted.

49 changes: 49 additions & 0 deletions sdk/include/opentelemetry/sdk/trace/samplers/trace_id_ratio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

#include "opentelemetry/sdk/trace/sampler.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace trace
{
namespace trace_api = opentelemetry::trace;
/**
* The TraceIdRatioBased sampler computes and returns a decision based on the
* provided trace_id and the configured ratio.
*/
class TraceIdRatioBasedSampler : public Sampler
{
public:
/**
* @param ratio a required value, 1.0 >= ratio >= 0.0. If the given trace_id
* falls into a given ratio of all possible trace_id values, ShouldSample will
* return RECORD_AND_SAMPLE.
* @throws invalid_argument if ratio is out of bounds [0.0, 1.0]
*/
explicit TraceIdRatioBasedSampler(double ratio);

/**
* @return Returns either RECORD_AND_SAMPLE or DROP based on current
* sampler configuration and provided trace_id and ratio. trace_id
* is used as a pseudorandom value in conjunction with the predefined
* ratio to determine whether this trace should be sampled
*/
SamplingResult ShouldSample(const trace_api::SpanContext & /*parent_context*/,
trace_api::TraceId trace_id,
nostd::string_view /*name*/,
trace_api::SpanKind /*span_kind*/,
const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override;

/**
* @return Description MUST be TraceIdRatioBasedSampler{0.000100}
*/
nostd::string_view GetDescription() const noexcept override;

private:
std::string description_;
const uint64_t threshold_;
};
} // namespace trace
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
2 changes: 1 addition & 1 deletion sdk/src/trace/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
add_library(
opentelemetry_trace
tracer_provider.cc tracer.cc span.cc batch_span_processor.cc
samplers/parent_or_else.cc samplers/probability.cc)
samplers/parent.cc samplers/trace_id_ratio.cc)

target_link_libraries(opentelemetry_trace opentelemetry_common)
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
#include "opentelemetry/sdk/trace/samplers/parent_or_else.h"
#include "opentelemetry/sdk/trace/samplers/parent.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace trace
{
ParentOrElseSampler::ParentOrElseSampler(std::shared_ptr<Sampler> delegate_sampler) noexcept
ParentBasedSampler::ParentBasedSampler(std::shared_ptr<Sampler> delegate_sampler) noexcept
: delegate_sampler_(delegate_sampler),
description_("ParentOrElse{" + std::string{delegate_sampler->GetDescription()} + "}")
description_("ParentBased{" + std::string{delegate_sampler->GetDescription()} + "}")
{}

SamplingResult ParentOrElseSampler::ShouldSample(
const trace_api::SpanContext *parent_context,
SamplingResult ParentBasedSampler::ShouldSample(
const trace_api::SpanContext &parent_context,
trace_api::TraceId trace_id,
nostd::string_view name,
trace_api::SpanKind span_kind,
const opentelemetry::common::KeyValueIterable &attributes) noexcept
{
if (parent_context == nullptr)
if (!parent_context.IsValid())
{
// If no parent (root span) exists returns the result of the delegateSampler
return delegate_sampler_->ShouldSample(parent_context, trace_id, name, span_kind, attributes);
}

// If parent exists:
if (parent_context->IsSampled())
if (parent_context.IsSampled())
{
return {Decision::RECORD_AND_SAMPLE, nullptr};
}

return {Decision::DROP, nullptr};
}

nostd::string_view ParentOrElseSampler::GetDescription() const noexcept
nostd::string_view ParentBasedSampler::GetDescription() const noexcept
{
return description_;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "opentelemetry/sdk/trace/samplers/probability.h"
#include "opentelemetry/sdk/trace/samplers/trace_id_ratio.h"

#include <cmath>
#include <cstdint>
Expand All @@ -24,26 +24,26 @@ namespace trace_api = opentelemetry::trace;
namespace
{
/**
* Converts a probability in [0, 1] to a threshold in [0, UINT64_MAX]
* Converts a ratio in [0, 1] to a threshold in [0, UINT64_MAX]
*
* @param probability a required value top be converted to uint64_t. is
* bounded by 1 >= probability >= 0.
* @return Returns threshold value computed after converting probability to
* @param ratio a required value top be converted to uint64_t. is
* bounded by 1 >= ratio >= 0.
* @return Returns threshold value computed after converting ratio to
* uint64_t datatype
*/
uint64_t CalculateThreshold(double probability) noexcept
uint64_t CalculateThreshold(double ratio) noexcept
{
if (probability <= 0.0)
if (ratio <= 0.0)
return 0;
if (probability >= 1.0)
if (ratio >= 1.0)
return UINT64_MAX;

// We can't directly return probability * UINT64_MAX.
// We can't directly return ratio * UINT64_MAX.
//
// UINT64_MAX is (2^64)-1, but as a double rounds up to 2^64.
// For probabilities >= 1-(2^-54), the product wraps to zero!
// Instead, calculate the high and low 32 bits separately.
const double product = UINT32_MAX * probability;
const double product = UINT32_MAX * ratio;
double hi_bits, lo_bits = ldexp(modf(product, &hi_bits), 32) + product;
return (static_cast<uint64_t>(hi_bits) << 32) + static_cast<uint64_t>(lo_bits);
}
Expand All @@ -62,9 +62,9 @@ uint64_t CalculateThresholdFromBuffer(const trace_api::TraceId &trace_id) noexce
uint64_t res = 0;
std::memcpy(&res, &trace_id, 8);

double probability = (double)res / UINT64_MAX;
double ratio = (double)res / UINT64_MAX;

return CalculateThreshold(probability);
return CalculateThreshold(ratio);
}
} // namespace

Expand All @@ -73,35 +73,23 @@ namespace sdk
{
namespace trace
{
ProbabilitySampler::ProbabilitySampler(double probability)
: threshold_(CalculateThreshold(probability))
TraceIdRatioBasedSampler::TraceIdRatioBasedSampler(double ratio)
: threshold_(CalculateThreshold(ratio))
{
if (probability > 1.0)
probability = 1.0;
if (probability < 0.0)
probability = 0.0;
description_ = "ProbabilitySampler{" + std::to_string(probability) + "}";
if (ratio > 1.0)
ratio = 1.0;
if (ratio < 0.0)
ratio = 0.0;
description_ = "TraceIdRatioBasedSampler{" + std::to_string(ratio) + "}";
}

SamplingResult ProbabilitySampler::ShouldSample(
const trace_api::SpanContext *parent_context,
SamplingResult TraceIdRatioBasedSampler::ShouldSample(
const trace_api::SpanContext & /*parent_context*/,
trace_api::TraceId trace_id,
nostd::string_view /*name*/,
trace_api::SpanKind /*span_kind*/,
const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept
{
if (parent_context && !parent_context->HasRemoteParent())
{
if (parent_context->IsSampled())
{
return {Decision::RECORD_AND_SAMPLE, nullptr};
}
else
{
return {Decision::DROP, nullptr};
}
}

if (threshold_ == 0)
return {Decision::DROP, nullptr};

Expand All @@ -113,7 +101,7 @@ SamplingResult ProbabilitySampler::ShouldSample(
return {Decision::DROP, nullptr};
}

nostd::string_view ProbabilitySampler::GetDescription() const noexcept
nostd::string_view TraceIdRatioBasedSampler::GetDescription() const noexcept
{
return description_;
}
Expand Down
3 changes: 1 addition & 2 deletions sdk/src/trace/tracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ nostd::shared_ptr<trace_api::Span> Tracer::StartSpan(
{
trace_api::SpanContext parent = GetCurrentSpanContext(options.parent);

// TODO: replace nullptr with parent context in span context
auto sampling_result =
sampler_->ShouldSample(nullptr, parent.trace_id(), name, options.kind, attributes);
sampler_->ShouldSample(parent, parent.trace_id(), name, options.kind, attributes);
if (sampling_result.decision == Decision::DROP)
{
// Don't allocate a no-op span for every DROP decision, but use a static
Expand Down
8 changes: 4 additions & 4 deletions sdk/test/trace/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ cc_test(
)

cc_test(
name = "parent_or_else_sampler_test",
name = "parent_sampler_test",
srcs = [
"parent_or_else_sampler_test.cc",
"parent_sampler_test.cc",
],
deps = [
"//sdk/src/trace",
Expand All @@ -91,9 +91,9 @@ cc_test(
)

cc_test(
name = "probability_sampler_test",
name = "trace_id_ratio_sampler_test",
srcs = [
"probability_sampler_test.cc",
"trace_id_ratio_sampler_test.cc",
],
deps = [
"//sdk/src/common:random",
Expand Down
Loading

0 comments on commit 29898c7

Please sign in to comment.