Skip to content

Commit dea97aa

Browse files
HazATrhcarvalho
andauthored
fix(apm): Sampling of traces (getsentry#2500)
* fix(apm): Set sampled to true by default Also set op otherwise span will be discarded by the server * meta: Changelog * fix(apm): Sampling * ref: Remove set default op * fix: Sampling decision * ref: Add comment * ref: typo * ref: Changes to docblock * ref: Change message * Apply suggestions from code review Co-Authored-By: Rodolfo Carvalho <rodolfo.carvalho@sentry.io> * Update packages/types/src/options.ts Co-Authored-By: Rodolfo Carvalho <rodolfo.carvalho@sentry.io> * Update packages/types/src/options.ts Co-Authored-By: Rodolfo Carvalho <rodolfo.carvalho@sentry.io> * ref: Remove deprecated parts * fix: Maxlen * ref: Rework when and how integrations are setup * ref(apm): Send a span if it's not a child * ref: Tracing integration * fix: tests * fix: Span / Transaction creation * ref: CodeReview * fix: Setup integrations when after we bound a client to the hub * ref: CodeReview * fix: tests * Update packages/types/src/span.ts Co-Authored-By: Rodolfo Carvalho <rodolfo.carvalho@sentry.io> * ref: CodeReview * ref: CodeReview * fix: Tests * ref: Refactor SpanRecorder -> SpanList Fix tests * ref: Rename back to SpanRecorder to be consistent with Python * ref: SpanRecorder * ref: Remove makeRoot * ref: Changelog * meta: Changelog Co-authored-by: Rodolfo Carvalho <rodolfo.carvalho@sentry.io>
1 parent 39af3b4 commit dea97aa

File tree

15 files changed

+404
-233
lines changed

15 files changed

+404
-233
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
66

7+
- [apm] fix: Sampling of traces work now only depending on the client option `tracesSampleRate` (#2500)
8+
- [apm] fix: Remove internal `forceNoChild` parameter from `hub.startSpan` (#2500)
9+
- [apm] fix: Made constructor of `Span` internal, only use `hub.startSpan` (#2500)
10+
- [apm] ref: Remove status from tags in transaction (#2497)
11+
- [browser] fix: Respect breadcrumbs sentry:false option (#2499)
12+
713
## 5.14.2
814

915
- [apm] fix: Use Performance API for timings when available, including Web Workers (#2492)

packages/apm/src/hubextensions.ts

+22-25
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
11
import { getMainCarrier, Hub } from '@sentry/hub';
22
import { SpanContext } from '@sentry/types';
3-
import { isInstanceOf } from '@sentry/utils';
43

54
import { Span } from './span';
65

7-
/**
8-
* Checks whether given value is instance of Span
9-
* @param span value to check
10-
*/
11-
function isSpanInstance(span: unknown): span is Span {
12-
return isInstanceOf(span, Span);
13-
}
14-
156
/** Returns all trace headers that are currently on the top scope. */
167
function traceHeaders(): { [key: string]: string } {
178
// @ts-ignore
@@ -33,36 +24,42 @@ function traceHeaders(): { [key: string]: string } {
3324
* and attach a `SpanRecorder`. If it's of type `SpanContext` and there is already a `Span` on the Scope,
3425
* the created Span will have a reference to it and become it's child. Otherwise it'll crete a new `Span`.
3526
*
36-
* @param span Already constructed span which should be started or properties with which the span should be created
27+
* @param spanContext Already constructed span or properties with which the span should be created
3728
*/
38-
function startSpan(spanOrSpanContext?: Span | SpanContext, forceNoChild: boolean = false): Span {
29+
function startSpan(spanContext?: SpanContext): Span {
3930
// @ts-ignore
40-
const that = this as Hub;
41-
const scope = that.getScope();
42-
const client = that.getClient();
31+
const hub = this as Hub;
32+
const scope = hub.getScope();
33+
const client = hub.getClient();
4334
let span;
4435

45-
if (!isSpanInstance(spanOrSpanContext) && !forceNoChild) {
46-
if (scope) {
47-
const parentSpan = scope.getSpan() as Span;
48-
if (parentSpan) {
49-
span = parentSpan.child(spanOrSpanContext);
50-
}
36+
// This flag determines if we already added the span as a child to the span that currently lives on the scope
37+
// If we do not have this, we will add it later on twice to the span recorder and therefore have too many spans
38+
let addedAsChild = false;
39+
40+
if (scope) {
41+
const parentSpan = scope.getSpan() as Span;
42+
if (parentSpan) {
43+
span = parentSpan.child(spanContext);
44+
addedAsChild = true;
5145
}
5246
}
5347

54-
if (!isSpanInstance(span)) {
55-
span = new Span(spanOrSpanContext, that);
48+
if (!span) {
49+
span = new Span(spanContext, hub);
5650
}
5751

58-
if (span.sampled === undefined && span.transaction !== undefined) {
52+
// We only roll the dice on sampling for "root" spans (transactions) because the childs inherit this state
53+
if (span.sampled === undefined && span.isRootSpan()) {
5954
const sampleRate = (client && client.getOptions().tracesSampleRate) || 0;
6055
span.sampled = Math.random() < sampleRate;
6156
}
6257

63-
if (span.sampled) {
58+
// We only want to create a span list if we sampled the transaction
59+
// in case we will discard the span anyway because sampled == false, we safe memory and do not store child spans
60+
if (span.sampled && !addedAsChild) {
6461
const experimentsOptions = (client && client.getOptions()._experiments) || {};
65-
span.initFinishedSpans(experimentsOptions.maxSpans as number);
62+
span.initSpanRecorder(experimentsOptions.maxSpans as number);
6663
}
6764

6865
return span;

0 commit comments

Comments
 (0)