Skip to content

[Tracer] Refactor stats computation into StatsAggregator#3133

Merged
zacharycmontoya merged 14 commits into
masterfrom
zach/stats/refactor-sampler
Sep 7, 2022
Merged

[Tracer] Refactor stats computation into StatsAggregator#3133
zacharycmontoya merged 14 commits into
masterfrom
zach/stats/refactor-sampler

Conversation

@zacharycmontoya

@zacharycmontoya zacharycmontoya commented Aug 27, 2022

Copy link
Copy Markdown
Contributor

Summary of changes

In #3048, the logic for keeping a trace chunk occurred twice: once in the TraceContext and then again in the StatsAggregator. This PR moves all of the logic into the StatsAggregator.

Reason for change

Simplifies the logic.

Implementation details

Main changes

  • Adds a new method to run all the trace chunk sampling logic: bool IStatsAggregator.ShouldKeepTrace(ArraySegment<Span> trace)
  • Adds a new interface to cleanly define each rule: Datadog.Trace.Agent.ITraceSampler
    • The one required method is: bool Sample(ArraySegment<Span> trace)
    • Derived types include:
      • AnalyticsEventSampler
      • ErrorSampler
      • PrioritySampler
      • RareSampler
  • Fixes the following bugs identified in the previous PR and adds regression tests:
    • Spans caught by the RareSampler must have the metric _dd.rare=1
    • Ensure that traces with errors (possibly in child spans) always get reported to the trace agent
      • Note: the trace agent has a more nuanced ErrorSampler, but this works for now and still eliminates a great deal of traffic

Other changes

  • Undoes some of changes introduced in the last PR:
    • Changes the return types of IStatsAggregator.Add/IStatsAggregator.AddRange from bool to void since this is no longer making a sampling decision
    • Removes bool shouldSerializeSpans, which used to be calculated in TraceContext and propagated through to the AgentWriter
    • Removes the tests added to TraceContextTests, since now the TraceContext should be unchanged
  • Moves the traceId sampling into a common method SamplingHelpers.SampleByRate
  • Cleans up TraceContextTests.SetAASContext ever so slightly

Test coverage

Other details

Some thoughts I'd like some feedback on:

  • IStatsAggregator.RunSamplers mimics the name in the trace agent code, but should we use another name? Perhaps IStatsAggregator.SampleTrace?
  • Does the sampling belong in the IStatsAggregator or in the AgentWriter? We only have to do the sampling when stats computation is enabled so that's why I originally stuck it in IStatsAggregator
  • Is the ITraceSampler interface necessary? We could easily in-line all of the logic, but the separation makes it very easy to improve our sampling logic in the future so that we don't send spans that the trace agent will end up dropping.

@andrewlock

This comment has been minimized.

@andrewlock

This comment has been minimized.

@bouwkast bouwkast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the refactorings done to the samplers makes it a lot cleaner and easier to understand :)

Comment thread tracer/src/Datadog.Trace/Util/SamplingHelpers.cs Outdated
Comment thread tracer/src/Datadog.Trace/Agent/TraceSamplers/AnalyticsEventsSampler.cs Outdated
@andrewlock

This comment has been minimized.

@zacharycmontoya
zacharycmontoya force-pushed the zach/stats/refactor-sampler branch from 1ed8df4 to 414732d Compare August 30, 2022 21:12
@andrewlock

This comment has been minimized.

…default value `true`. This should make comprehension easier
- The span sampled by the RareSampler receives the metric _dd.rare=1
- A trace is kept if any span in the trace has an error
- A trace is kept if any span is sampled by its analytic events sample rate
…sampling is done at the AgentWriter level, not the TraceContext level
@zacharycmontoya
zacharycmontoya force-pushed the zach/stats/refactor-sampler branch from 414732d to 6885ce6 Compare August 31, 2022 15:20
@andrewlock

This comment has been minimized.

@andrewlock

This comment has been minimized.

@andrewlock

This comment has been minimized.

@andrewlock andrewlock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I like the refactoring

Comment thread tracer/src/Datadog.Trace/Agent/AgentWriter.cs
Comment thread tracer/src/Datadog.Trace/Agent/TraceSamplers/RareSampler.cs Outdated
}
}

return false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, HandlePriorityTrace always returns false? Also, _keys seems to have unbounded growth unless I'm mistaken?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the unbounded keys, we said last time that as we already have clients with more than 1000 resources it could be worth it to limit the size of the set indeed (as it is done in Java IIRC what Zach had answered).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm, HandlePriorityTrace always returns false?

Yes, according to the agent logic we should return false when the trace has a positive sampling priority.

Also, _keys seems to have unbounded growth unless I'm mistaken?

Yes, I didn't fix this in the last PR but now would be a good time to implement this. I'll think on the implementation and get back to this point.

Comment thread tracer/src/Datadog.Trace/Agent/TraceSamplers/RareSampler.cs Outdated
Comment on lines +118 to +120
// TODO: Add ability to disable the RareSampler, which the trace agent has
// Run the RareSampler early to make sure the signature gets counted
var rare = _rareSampler.Sample(trace);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the rare sampler is the only one with state, had we may as well just return immediately if this is true? If so, then FWIW, you could short-circuit here if preferable for readability:

    return _rareSampler.Sample(trace)
        || _prioritySampler.Sample(trace)
        || _errorSampler.Sample(trace)
        || _analyticsEventSampler.Sample(trace);

@zacharycmontoya zacharycmontoya Sep 6, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What you propose has really great readability. I'll try to do something similar in my coming changes, but note that the RareSampler must always run first (unless disabled), but its result is used as the very last fallback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I made a refactor similar to what you suggest in 69b3115 . The difference is that the last OR operand is the result of the _rareSampler.Sample(trace), which was run earlier in the method. The reason for this is documented in the code, so hopefully that's clear

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I made a refactor similar to what you suggest in 69b3115
Cool.

The reason for this is documented in the code, so hopefully that's clear

The reasoning there is clear, thanks. And I understand keeping it like this for consistency with other traceers, but...

but note that the RareSampler must always run first (unless disabled), but its result is used as the very last fallback

This makes sense to me if the other samplers have side-effects. But as far as I can see, they don't. so if the rareSpanFound is true, the result is always true, and running the other samplers is unnecessary?

I'm not passionate about it, especially as if the other samplers do have side effects (or might in the future), then the order is important

@zacharycmontoya zacharycmontoya Sep 7, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see what you're saying about side effects, I wasn't fully understanding what you were saying that earlier. Yes since the other samplers have no side effects (right now) then we could possibly return early. I'll keep this as-is for now since we might eventually want to make more robust samplers (closer to what the agent has) that would need to keep some state

Comment thread tracer/test/Datadog.Trace.IntegrationTests/StatsTests.cs

@pierotibou pierotibou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refacto, thank you for doing it. I mainly have comments on RareSampling. And to answer your questions in the description:

IStatsAggregator.RunSamplers mimics the name in the trace agent code, but should we use another name? Perhaps IStatsAggregator.SampleTrace?

I think it should be named ShouldKeepTrace personally.

Does the sampling belong in the IStatsAggregator or in the AgentWriter? We only have to do the sampling when stats computation is enabled so that's why I originally stuck it in IStatsAggregator

I think it's fine here for now. What I challenge more is to have all this in AgentWriter personally. I think those steps should happen beforehand. But clearly we can come back to this later (if we agree).

Is the ITraceSampler interface necessary?

I think it makes sense to have dedicated classes for the various behaviours, it's easier to read. That said, I'm not sure all samplers fit the interface currently, I think the RareSampler should implement 2 distinct methods (cf comments)

}
}

public bool RunSamplers(ArraySegment<Span> trace)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it returns a boolean, I believe it would be better to call this ShouldKeepTrace

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 03e94ef

public bool RunSamplers(ArraySegment<Span> trace)
{
// TODO: Add ability to disable the RareSampler, which the trace agent has
// Run the RareSampler early to make sure the signature gets counted

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could split the RareSampler in 2 parts:

  • Span? Dectect(ArraySegment) that will register keys and return the first rare span if any
  • bool Sample(Span?) that will add the tag if there's a span

The sampling part would be called only after all other samplers have been called.
I believe that would simplify the RareSampler code as you wouldn't have to handle differently spans with positive or negative priorities.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sampling part would be called only after all other samplers have been called.

So after a bit of reading the agent code and testing, this isn't quite true. Here's the algorithm we need:

  • Run the RareSampler first. If the sampling priority is > 0, the RareSampler will not mark any spans with "_dd.rare = 1". Otherwise, the first rare span in the chunk that's determined to be rare is marked as "_dd.rare = 1"
  • If no other samplers decide to sample the trace chunk, return the result of the RareSampler as the decision for the trace

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit 69b3115 I updated the RareSampler slightly. I documented the reasons for the algorithm so the algorithm itself didn't change too much, but I tried to refactor and add comments so it's clearer. Let me know what you think

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Run the RareSampler first. If the sampling priority is > 0, the RareSampler will not mark any spans with "_dd.rare = 1". Otherwise, the first rare span in the chunk that's determined to be rare is marked as "_dd.rare = 1"
If no other samplers decide to sample the trace chunk, return the result of the RareSampler as the decision for the trace

So to make sure IUC, the difference in behaviour with what I suggested is the fact that a span can be marked as _dd.rare = 1 even though it is sampled by another sampler (eg we have a span with prio <=0, it is rare, we add the tag, but it also contains an error, so it is returned anyway). Whereas in my suggestion, we wouldn't add the _dd.rare = 1 in that case. Right?

}
}

return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the unbounded keys, we said last time that as we already have clients with more than 1000 resources it could be worth it to limit the size of the set indeed (as it is done in Java IIRC what Zach had answered).


namespace Datadog.Trace.Util
{
internal class SamplingHelpers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a helper method like MarkedAsKept (not the best name but you see what I mean) that would contain that code
trace.Array[trace.Offset].Context.TraceContext.SamplingPriority is int p && p > 0;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in 45c2227 with name IsKeptBySamplingPriority

…it to helper method SamplingHelpers.IsKeptBySamplingPriority
… main design points:

1) Before running other samplers, if a trace is already kept by sampling priority, send the trace to the RareSampler first only to mark the stats points (but do not return the sampling decision yet)
2) Return the sampling decision of the RareSampler as the last sampler in the sampler chain.
@andrewlock

This comment has been minimized.

@andrewlock

This comment has been minimized.

…0 items in the set of seen spans at all times.
@andrewlock

Copy link
Copy Markdown
Member

Benchmarks Report 🐌

Benchmarks for #3133 compared to master:

  • 1 benchmarks are faster, with geometric mean 1.137
  • All benchmarks have the same allocations

The following thresholds were used for comparing the benchmark speeds:

  • Mann–Whitney U test with statistical test for significance of 5%
  • Only results indicating a difference greater than 10% and 0.3 ns are considered.

Allocation changes below 0.5% are ignored.

Benchmark details

Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net472 723μs 429ns 1.66μs 0.361 0 0 3.18 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 474μs 225ns 873ns 0 0 0 2.59 KB
#3133 WriteAndFlushEnrichedTraces net472 726μs 225ns 812ns 0.361 0 0 3.18 KB
#3133 WriteAndFlushEnrichedTraces netcoreapp3.1 481μs 232ns 898ns 0 0 0 2.58 KB
Benchmarks.Trace.AppSecBodyBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master AllCycleSimpleBody net472 185ns 0.15ns 0.583ns 0.0675 0 0 425 B
master AllCycleSimpleBody netcoreapp3.1 235ns 0.269ns 1.04ns 0.00567 0 0 424 B
master AllCycleMoreComplexBody net472 201ns 0.196ns 0.732ns 0.0637 0 0 401 B
master AllCycleMoreComplexBody netcoreapp3.1 232ns 0.28ns 1.08ns 0.00549 0 0 400 B
master BodyExtractorSimpleBody net472 276ns 0.388ns 1.5ns 0.0573 0 0 361 B
master BodyExtractorSimpleBody netcoreapp3.1 237ns 0.653ns 2.53ns 0.00368 0 0 272 B
master BodyExtractorMoreComplexBody net472 14.5μs 7.99ns 30.9ns 1.21 0.0219 0 7.62 KB
master BodyExtractorMoreComplexBody netcoreapp3.1 11.8μs 9.92ns 35.8ns 0.088 0 0 6.75 KB
#3133 AllCycleSimpleBody net472 202ns 0.274ns 1.06ns 0.0676 0 0 425 B
#3133 AllCycleSimpleBody netcoreapp3.1 235ns 0.253ns 0.912ns 0.00587 0 0 424 B
#3133 AllCycleMoreComplexBody net472 188ns 0.155ns 0.6ns 0.0638 0 0 401 B
#3133 AllCycleMoreComplexBody netcoreapp3.1 233ns 0.302ns 1.17ns 0.00543 0 0 400 B
#3133 BodyExtractorSimpleBody net472 261ns 0.273ns 1.02ns 0.0573 0 0 361 B
#3133 BodyExtractorSimpleBody netcoreapp3.1 233ns 0.312ns 1.21ns 0.00372 0 0 272 B
#3133 BodyExtractorMoreComplexBody net472 14.5μs 8.71ns 33.7ns 1.2 0.0218 0 7.62 KB
#3133 BodyExtractorMoreComplexBody netcoreapp3.1 11.8μs 19.6ns 75.9ns 0.0891 0 0 6.75 KB
Benchmarks.Trace.AspNetCoreBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendRequest net472 0ns 0ns 0ns 0 0 0 0 b
master SendRequest netcoreapp3.1 182μs 174ns 675ns 0.182 0 0 20.57 KB
#3133 SendRequest net472 0ns 0ns 0ns 0 0 0 0 b
#3133 SendRequest netcoreapp3.1 180μs 136ns 509ns 0.269 0 0 20.57 KB
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteNonQuery net472 1.8μs 0.652ns 2.35ns 0.15 0.000902 0 947 B
master ExecuteNonQuery netcoreapp3.1 1.43μs 0.435ns 1.57ns 0.0122 0 0 936 B
#3133 ExecuteNonQuery net472 1.83μs 1.2ns 4.65ns 0.15 0.000918 0 947 B
#3133 ExecuteNonQuery netcoreapp3.1 1.49μs 0.614ns 2.38ns 0.0127 0 0 936 B
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master CallElasticsearch net472 2.54μs 0.772ns 2.99ns 0.184 0 0 1.16 KB
master CallElasticsearch netcoreapp3.1 1.51μs 0.547ns 2.05ns 0.015 0 0 1.1 KB
master CallElasticsearchAsync net472 2.63μs 0.986ns 3.82ns 0.205 0 0 1.29 KB
master CallElasticsearchAsync netcoreapp3.1 1.66μs 0.515ns 1.99ns 0.0157 0 0 1.22 KB
#3133 CallElasticsearch net472 2.48μs 0.586ns 2.19ns 0.184 0 0 1.16 KB
#3133 CallElasticsearch netcoreapp3.1 1.51μs 0.558ns 2.09ns 0.0152 0 0 1.1 KB
#3133 CallElasticsearchAsync net472 2.65μs 0.955ns 3.7ns 0.205 0 0 1.29 KB
#3133 CallElasticsearchAsync netcoreapp3.1 1.66μs 0.803ns 3.11ns 0.0165 0 0 1.22 KB
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteAsync net472 2.67μs 5.61ns 21ns 0.226 0 0 1.42 KB
master ExecuteAsync netcoreapp3.1 1.76μs 3.01ns 10.9ns 0.0184 0 0 1.34 KB
#3133 ExecuteAsync net472 2.64μs 3.72ns 13.9ns 0.225 0 0 1.42 KB
#3133 ExecuteAsync netcoreapp3.1 1.69μs 2.26ns 8.75ns 0.0187 0 0 1.34 KB
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendAsync net472 5.76μs 9.97ns 38.6ns 0.439 0 0 2.77 KB
master SendAsync netcoreapp3.1 3.64μs 8.08ns 31.3ns 0.0346 0 0 2.6 KB
#3133 SendAsync net472 5.72μs 10.8ns 41.7ns 0.439 0 0 2.77 KB
#3133 SendAsync netcoreapp3.1 3.53μs 5.41ns 20.9ns 0.0354 0 0 2.6 KB
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 3.35μs 4.06ns 15.7ns 0.287 0 0 1.81 KB
master EnrichedLog netcoreapp3.1 2.46μs 1.1ns 4.1ns 0.0244 0 0 1.85 KB
#3133 EnrichedLog net472 3.3μs 1.19ns 4.3ns 0.287 0 0 1.81 KB
#3133 EnrichedLog netcoreapp3.1 2.68μs 28.2ns 268ns 0.0257 0 0 1.85 KB
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 152μs 217ns 841ns 0.691 0.23 0 4.65 KB
master EnrichedLog netcoreapp3.1 118μs 192ns 744ns 0.0584 0 0 4.49 KB
#3133 EnrichedLog net472 150μs 234ns 905ns 0.685 0.228 0 4.65 KB
#3133 EnrichedLog netcoreapp3.1 115μs 106ns 382ns 0.0569 0 0 4.49 KB
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 5.72μs 13.5ns 50.5ns 0.569 0.00282 0 3.59 KB
master EnrichedLog netcoreapp3.1 4.39μs 8.06ns 31.2ns 0.0548 0 0 3.91 KB
#3133 EnrichedLog net472 5.62μs 10.8ns 40.4ns 0.568 0.00276 0 3.59 KB
#3133 EnrichedLog netcoreapp3.1 4.38μs 5.27ns 19.7ns 0.0523 0 0 3.91 KB
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendReceive net472 2.4μs 1.83ns 7.09ns 0.217 0 0 1.37 KB
master SendReceive netcoreapp3.1 1.86μs 0.908ns 3.4ns 0.0176 0 0 1.32 KB
#3133 SendReceive net472 2.27μs 0.896ns 3.1ns 0.218 0 0 1.37 KB
#3133 SendReceive netcoreapp3.1 1.85μs 1.38ns 5.35ns 0.0176 0 0 1.32 KB
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 5.1μs 1.45ns 5.44ns 0.354 0 0 2.23 KB
master EnrichedLog netcoreapp3.1 4.31μs 1.48ns 5.56ns 0.0237 0 0 1.8 KB
#3133 EnrichedLog net472 5.1μs 3.59ns 13.9ns 0.354 0 0 2.23 KB
#3133 EnrichedLog netcoreapp3.1 4.5μs 1.61ns 6.24ns 0.0244 0 0 1.8 KB
Benchmarks.Trace.SpanBenchmark - Faster 🎉 Same allocations ✔️

Faster 🎉 in #3133

Benchmark base/diff Base Median (ns) Diff Median (ns) Modality
Benchmarks.Trace.SpanBenchmark.StartFinishSpan‑netcoreapp3.1 1.137 1,042.33 916.74

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StartFinishSpan net472 1.21μs 0.172ns 0.642ns 0.128 0 0 810 B
master StartFinishSpan netcoreapp3.1 1.04μs 0.599ns 2.32ns 0.0103 0 0 760 B
master StartFinishScope net472 1.36μs 0.637ns 2.47ns 0.141 0 0 891 B
master StartFinishScope netcoreapp3.1 1.09μs 1.01ns 3.93ns 0.012 0 0 880 B
#3133 StartFinishSpan net472 1.16μs 2.91ns 10.9ns 0.128 0 0 810 B
#3133 StartFinishSpan netcoreapp3.1 917ns 0.289ns 1.08ns 0.0101 0 0 760 B
#3133 StartFinishScope net472 1.42μs 0.908ns 3.52ns 0.141 0 0 891 B
#3133 StartFinishScope netcoreapp3.1 1.09μs 0.293ns 1.1ns 0.0119 0 0 880 B
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunOnMethodBegin net472 1.51μs 0.417ns 1.61ns 0.141 0 0 891 B
master RunOnMethodBegin netcoreapp3.1 1.15μs 0.232ns 0.898ns 0.0121 0 0 880 B
#3133 RunOnMethodBegin net472 1.53μs 0.972ns 3.77ns 0.141 0 0 891 B
#3133 RunOnMethodBegin netcoreapp3.1 1.11μs 0.423ns 1.52ns 0.0117 0 0 880 B

@andrewlock

Copy link
Copy Markdown
Member

Code Coverage Report 📊

✔️ Merging #3133 into master will not change line coverage
✔️ Merging #3133 into master will not change branch coverage
⛔ Merging #3133 into master will will increase complexity by 38

master #3133 Change
Lines 17633 / 24217 17673 / 24262
Lines % 73% 73% 0% ✔️
Branches 10418 / 14912 10457 / 14946
Branches % 70% 70% 0% ✔️
Complexity 16100 16138 38

View the full report for further details:

Datadog.Trace Breakdown ✔️

master #3133 Change
Lines % 73% 73% 0% ✔️
Branches % 70% 70% 0% ✔️
Complexity 16100 16138 38

The following classes have significant coverage changes.

File Line coverage change Branch coverage change Complexity change
Datadog.Trace.Agent.NullStatsAggregator -30% 0% ✔️ 1
Datadog.Trace.Ci.GitInfo -17% -11% 0 ✔️
Datadog.Trace.Debugger.PInvoke.DebuggerNativeMethods -6% -10% 0 ✔️
Datadog.Trace.Debugger.ProbeStatuses.ProbeStatusPoller 0% ✔️ -6% 0 ✔️
Datadog.Trace.Ci.CIVisibility 5% ✔️ 6% ✔️ 0 ✔️
Datadog.Trace.Agent.DiscoveryService.DiscoveryService 7% ✔️ 0% ✔️ 0 ✔️
Datadog.Trace.Propagators.SpanContextPropagator 8% ✔️ 6% ✔️ 0 ✔️

The following classes were added in #3133:

File Line coverage Branch coverage Complexity
Datadog.Trace.Agent.TraceSamplers.AnalyticsEventsSampler 100% 100% 4
Datadog.Trace.Agent.TraceSamplers.ErrorSampler 100% 100% 4
Datadog.Trace.Agent.TraceSamplers.PrioritySampler 100% 100% 1
Datadog.Trace.Agent.TraceSamplers.RareSampler 95% 96% 30
Datadog.Trace.Util.SamplingHelpers 100% 50% 5

View the full reports for further details:

@zacharycmontoya
zacharycmontoya merged commit 8df43bf into master Sep 7, 2022
@zacharycmontoya
zacharycmontoya deleted the zach/stats/refactor-sampler branch September 7, 2022 15:19
@github-actions github-actions Bot added this to the vNext milestone Sep 7, 2022
@zacharycmontoya
zacharycmontoya restored the zach/stats/refactor-sampler branch September 7, 2022 16:54
@zacharycmontoya
zacharycmontoya deleted the zach/stats/refactor-sampler branch September 8, 2022 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants