Skip to content
This repository was archived by the owner on Oct 3, 2023. It is now read-only.

Commit 2951f96

Browse files
authored
Fix duplicate spans issue and clean up (#545)
* Clean up and ignore non root spans * fix build * Add isRootSpan on the span
1 parent f68aa53 commit 2951f96

File tree

16 files changed

+117
-107
lines changed

16 files changed

+117
-107
lines changed

packages/opencensus-core/src/exporters/console-exporter.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import {Exporter, ExporterConfig, StatsEventListener} from './types';
2424
/** Do not send span data */
2525
export class NoopExporter implements Exporter {
2626
logger?: loggerTypes.Logger;
27-
onStartSpan(root: modelTypes.Span) {}
28-
onEndSpan(root: modelTypes.Span) {}
29-
publish(rootSpans: modelTypes.Span[]) {
27+
onStartSpan(span: modelTypes.Span) {}
28+
onEndSpan(span: modelTypes.Span) {}
29+
publish(spans: modelTypes.Span[]) {
3030
return Promise.resolve();
3131
}
3232
}
@@ -39,7 +39,7 @@ export class ConsoleExporter implements Exporter {
3939
private buffer: ExporterBuffer;
4040

4141
/**
42-
* Constructs a new ConsoleLogExporter instance.
42+
* Constructs a new ConsoleExporter instance.
4343
* @param config Exporter configuration object to create a console log
4444
* exporter.
4545
*/
@@ -55,19 +55,22 @@ export class ConsoleExporter implements Exporter {
5555
* @param span Ended span.
5656
*/
5757
onEndSpan(span: modelTypes.Span) {
58+
// Add spans of a trace together when root is ended, skip non root spans.
59+
// publish function will extract child spans from root.
60+
if (!span.isRootSpan()) return;
5861
this.buffer.addToBuffer(span);
5962
}
6063

6164
/**
6265
* Sends the spans information to the console.
63-
* @param rootSpans A list of root spans to publish.
66+
* @param spans A list of spans to publish.
6467
*/
65-
publish(rootSpans: modelTypes.Span[]) {
66-
rootSpans.map((root) => {
67-
const ROOT_STR = `RootSpan: {traceId: ${root.traceId}, spanId: ${
68-
root.id}, name: ${root.name} }`;
69-
const SPANS_STR: string[] = root.spans.map(
70-
(span) => [`\t\t{spanId: ${span.id}, name: ${span.name}}`].join(
68+
publish(spans: modelTypes.Span[]) {
69+
spans.map((span) => {
70+
const ROOT_STR = `RootSpan: {traceId: ${span.traceId}, spanId: ${
71+
span.id}, name: ${span.name} }`;
72+
const SPANS_STR: string[] = span.spans.map(
73+
(child) => [`\t\t{spanId: ${child.id}, name: ${child.name}}`].join(
7174
'\n'));
7275

7376
const result: string[] = [];
@@ -85,7 +88,6 @@ export class ConsoleStatsExporter implements StatsEventListener {
8588
/**
8689
* Event called when a view is registered
8790
* @param view registered view
88-
* @param measure registered measure
8991
*/
9092
onRegisterView(view: View) {
9193
console.log(`View registered: ${view.name}, Measure registered: ${

packages/opencensus-core/src/exporters/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import * as modelTypes from '../trace/model/types';
2222
/** Defines a trace exporter interface. */
2323
export interface Exporter extends modelTypes.SpanEventListener {
2424
/**
25-
* Sends a list of root spans to the service.
26-
* @param rootSpans A list of root spans to publish.
25+
* Sends a list of spans to the service.
26+
* @param spans A list of spans to publish.
2727
*/
28-
publish(rootSpans: modelTypes.Span[]): Promise<number|string|void>;
28+
publish(spans: modelTypes.Span[]): Promise<number|string|void>;
2929
}
3030

3131
/**

packages/opencensus-core/src/trace/model/no-record/no-record-root-span.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ export class NoRecordRootSpan extends NoRecordSpan {
5757
this.logger = this.tracer.logger || logger.logger();
5858
}
5959

60+
/** Returns whether a span is root or not. */
61+
isRootSpan(): boolean {
62+
return true;
63+
}
64+
6065
/** No-op implementation of this method. */
6166
get traceId(): string {
6267
return this.traceIdLocal;

packages/opencensus-core/src/trace/model/no-record/no-record-span.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ export class NoRecordSpan implements types.Span {
8080
this.logger = (this.root && this.root.logger) || this.logger;
8181
}
8282

83+
/** Returns whether a span is root or not. */
84+
isRootSpan(): boolean {
85+
return false;
86+
}
87+
8388
/** Gets trace id of no-record span. */
8489
get traceId(): string {
8590
return '';

packages/opencensus-core/src/trace/model/root-span.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ export class RootSpan extends Span {
5555
this.activeTraceParams = tracer.activeTraceParams;
5656
}
5757

58+
/** Returns whether a span is root or not. */
59+
isRootSpan(): boolean {
60+
return true;
61+
}
62+
5863
/** Gets trace id from rootspan instance. */
5964
get traceId(): string {
6065
return this.traceIdLocal;

packages/opencensus-core/src/trace/model/span.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ export class Span implements types.Span {
9494
this.logger = (this.root && this.root.logger) || this.logger;
9595
}
9696

97+
/** Returns whether a span is root or not. */
98+
isRootSpan(): boolean {
99+
return false;
100+
}
101+
97102
/** Gets the trace ID. */
98103
get traceId(): string {
99104
return this.root.traceId;
@@ -330,6 +335,8 @@ export class Span implements types.Span {
330335
this.endedLocal = true;
331336
this.clock.end();
332337

338+
// TODO: Should ending a span force its children to end by default?
339+
// Issue: https://github.com/open-telemetry/opentelemetry-node/issues/4
333340
for (const span of this.spansLocal) {
334341
if (!span.ended && span.started) {
335342
span.truncate();

packages/opencensus-core/src/trace/model/tracer-base.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -152,22 +152,15 @@ export class CoreTracerBase implements types.TracerBase {
152152
}
153153

154154
/** Notifies listeners of the span start. */
155-
onStartSpan(root: types.Span): void {
155+
onStartSpan(span: types.Span): void {
156156
if (!this.active) return;
157-
if (!root) {
158-
return this.logger.debug('cannot start trace - no active trace found');
159-
}
160-
this.notifyStartSpan(root);
157+
this.notifyStartSpan(span);
161158
}
162159

163160
/** Notifies listeners of the span end. */
164-
onEndSpan(root: types.Span): void {
161+
onEndSpan(span: types.Span): void {
165162
if (!this.active) return;
166-
if (!root) {
167-
this.logger.debug('cannot end trace - no active trace found');
168-
return;
169-
}
170-
this.notifyEndSpan(root);
163+
this.notifyEndSpan(span);
171164
}
172165

173166
/**
@@ -191,19 +184,15 @@ export class CoreTracerBase implements types.TracerBase {
191184

192185
private notifyStartSpan(span: types.Span) {
193186
this.logger.debug('starting to notify listeners the start of spans');
194-
if (this.eventListenersLocal && this.eventListenersLocal.length > 0) {
195-
for (const listener of this.eventListenersLocal) {
196-
listener.onStartSpan(span);
197-
}
187+
for (const listener of this.eventListenersLocal) {
188+
listener.onStartSpan(span);
198189
}
199190
}
200191

201192
private notifyEndSpan(span: types.Span) {
202193
this.logger.debug('starting to notify listeners the end of spans');
203-
if (this.eventListenersLocal && this.eventListenersLocal.length > 0) {
204-
for (const listener of this.eventListenersLocal) {
205-
listener.onEndSpan(span);
206-
}
194+
for (const listener of this.eventListenersLocal) {
195+
listener.onEndSpan(span);
207196
}
208197
}
209198

packages/opencensus-core/src/trace/model/tracer.ts

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import * as cls from '../../internal/cls';
18-
1918
import {NoRecordSpan} from './no-record/no-record-span';
2019
import {CoreTracerBase} from './tracer-base';
2120
import * as types from './types';
@@ -73,32 +72,25 @@ export class CoreTracer extends CoreTracerBase implements types.Tracer {
7372
}
7473

7574
/** Notifies listeners of the span start. */
76-
onStartSpan(root: types.Span): void {
75+
onStartSpan(span: types.Span): void {
7776
if (!this.active) return;
78-
if (!root) {
79-
return this.logger.debug('cannot start trace - no active trace found');
80-
}
8177
if (!this.currentRootSpan ||
82-
this.currentRootSpan.traceId !== root.traceId) {
78+
this.currentRootSpan.traceId !== span.traceId) {
8379
this.logger.debug(
8480
'currentRootSpan != root on notifyStart. Need more investigation.');
8581
}
86-
return super.onStartSpan(root);
82+
return super.onStartSpan(span);
8783
}
8884

8985
/** Notifies listeners of the span end. */
90-
onEndSpan(root: types.Span): void {
86+
onEndSpan(span: types.Span): void {
9187
if (!this.active) return;
92-
if (!root) {
93-
this.logger.debug('cannot end trace - no active trace found');
94-
return;
95-
}
9688
if (!this.currentRootSpan ||
97-
this.currentRootSpan.traceId !== root.traceId) {
89+
this.currentRootSpan.traceId !== span.traceId) {
9890
this.logger.debug(
9991
'currentRootSpan != root on notifyEnd. Need more investigation.');
10092
}
101-
super.onEndSpan(root);
93+
super.onEndSpan(span);
10294
}
10395

10496
/** Clears the current root span. */

packages/opencensus-core/src/trace/model/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,9 @@ export interface Span {
460460

461461
/** Starts a new Span instance as a child of this instance */
462462
startChildSpan(options?: SpanOptions): Span;
463+
464+
/** Returns whether a span is root or not. */
465+
isRootSpan(): boolean;
463466
}
464467

465468
/** Interface for TracerBase */

packages/opencensus-exporter-instana/src/instana.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export class InstanaTraceExporter implements Exporter {
6363
onStartSpan(span: Span) {}
6464

6565
onEndSpan(span: Span) {
66+
// Add spans of a trace together when root is ended, skip non root spans.
67+
// translateRootSpans function will extract child spans from root.
68+
if (!span.isRootSpan()) return;
6669
this.exporterBuffer.addToBuffer(span);
6770
}
6871

@@ -76,13 +79,13 @@ export class InstanaTraceExporter implements Exporter {
7679
*
7780
* This Promise is meant as a problem indicator for tests only.
7881
*
79-
* @param rootSpans The spans to transmit to Instana
82+
* @param spans The list of spans to transmit to Instana
8083
* @returns An indicator whether publishing was successful.
8184
*/
82-
publish(rootSpans: Span[]): Promise<void> {
85+
publish(spans: Span[]): Promise<void> {
8386
try {
8487
return this
85-
.transmit(this.translateRootSpans(rootSpans))
88+
.transmit(this.translateRootSpans(spans))
8689

8790
.catch(e => e);
8891
} catch (e) {
@@ -92,11 +95,11 @@ export class InstanaTraceExporter implements Exporter {
9295
}
9396
}
9497

95-
private translateRootSpans(rootSpans: Span[]): InstanaSpan[] {
98+
private translateRootSpans(spans: Span[]): InstanaSpan[] {
9699
const result: InstanaSpan[] = [];
97-
return rootSpans.reduce((agg, rootSpan) => {
98-
agg.push(this.translateSpan(rootSpan));
99-
return agg.concat(rootSpan.spans.map(this.translateSpan));
100+
return spans.reduce((agg, span) => {
101+
agg.push(this.translateSpan(span));
102+
return agg.concat(span.spans.map(this.translateSpan));
100103
}, result);
101104
}
102105

0 commit comments

Comments
 (0)