Skip to content

Commit e80b42f

Browse files
Lms24claude
andcommitted
test(core): Show that unsampled spans are counted even if they would not be sent
Unsampled spans record their outcome when they start, so spans a sampled transaction would never contain (e.g. unfinished children) are counted too. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 2ffe1b9 commit e80b42f

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

  • dev-packages/node-integration-tests/suites/tracing/sampling-static
  • packages/core/test/lib/tracing

‎dev-packages/node-integration-tests/suites/tracing/sampling-static/test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('negative sampling (static)', () => {
99
createEsmAndCjsTests(__dirname, 'server.mjs', 'instrument.mjs', (createRunner, test) => {
1010
test('records sample_rate outcomes for the transaction and all of its spans', async () => {
1111
// `/health` and `/ok` go through the same middleware, so the `/ok` transaction tells us how many
12-
// spans the dropped `/health` transaction woudl have had. The count differs per runtime (e.g. Bun creates
12+
// spans the dropped `/health` transaction would have had. The count differs per runtime (e.g. Bun creates
1313
// no Express spans), so we derive it instead of hardcoding it.
1414
let okSpanCount: number | undefined;
1515
let droppedSpanCount: number | undefined;

‎packages/core/test/lib/tracing/trace.test.ts‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2828,6 +2828,34 @@ describe('ignoreSpans (core path, streaming)', () => {
28282828
expect(spyOnDroppedEvent).toHaveBeenCalledWith('sample_rate', 'span');
28292829
});
28302830

2831+
// Unsampled spans are counted when they start, so this also counts spans a sampled
2832+
// transaction would never contain (here: a child that never ends).
2833+
it('records sample_rate outcomes for unsampled spans that a sampled transaction would not contain', () => {
2834+
const runScenario = (tracesSampleRate: number): ReturnType<typeof vi.spyOn> => {
2835+
client = new TestClient(getDefaultTestClientOptions({ tracesSampleRate }));
2836+
setCurrentClient(client);
2837+
client.init();
2838+
const spyOnDroppedEvent = vi.spyOn(client, 'recordDroppedEvent');
2839+
2840+
startSpan({ name: 'GET /foo' }, () => {
2841+
startInactiveSpan({ name: 'never ended' });
2842+
});
2843+
2844+
return spyOnDroppedEvent;
2845+
};
2846+
2847+
const sampledSpy = vi.spyOn(TestClient.prototype, 'sendEvent');
2848+
runScenario(1);
2849+
expect(sampledSpy).toHaveBeenCalledWith(expect.objectContaining({ spans: [] }), expect.anything());
2850+
sampledSpy.mockRestore();
2851+
2852+
const unsampledDroppedEventSpy = runScenario(0);
2853+
expect(unsampledDroppedEventSpy).toHaveBeenCalledTimes(3);
2854+
expect(unsampledDroppedEventSpy).toHaveBeenNthCalledWith(1, 'sample_rate', 'transaction');
2855+
expect(unsampledDroppedEventSpy).toHaveBeenNthCalledWith(2, 'sample_rate', 'span');
2856+
expect(unsampledDroppedEventSpy).toHaveBeenNthCalledWith(3, 'sample_rate', 'span');
2857+
});
2858+
28312859
it('records only one ignored outcome for directly ignored child span', () => {
28322860
const options = getDefaultTestClientOptions({
28332861
tracesSampleRate: 1,

0 commit comments

Comments
 (0)