diff --git a/packages/opencensus-core/src/trace/model/span-base.ts b/packages/opencensus-core/src/trace/model/span-base.ts index bd9a71ef2..e070ba6df 100644 --- a/packages/opencensus-core/src/trace/model/span-base.ts +++ b/packages/opencensus-core/src/trace/model/span-base.ts @@ -64,9 +64,12 @@ export abstract class SpanBase implements types.Span { /** The number of dropped attributes. */ droppedAttributesCount = 0; - /** The number of dropped links. */ droppedLinksCount = 0; + /** The number of dropped annotations. */ + droppedAnnotationsCount = 0; + /** The number of dropped message events. */ + droppedMessageEventsCount = 0; /** Constructs a new SpanBaseModel instance. */ constructor() { @@ -166,6 +169,11 @@ export abstract class SpanBase implements types.Span { */ addAnnotation( description: string, attributes?: types.Attributes, timestamp = 0) { + if (this.annotations.length >= + this.activeTraceParams.numberOfAnnontationEventsPerSpan) { + this.annotations.shift(); + this.droppedAnnotationsCount++; + } this.annotations.push({ 'description': description, 'attributes': attributes, @@ -203,6 +211,11 @@ export abstract class SpanBase implements types.Span { * @param timestamp A time in milliseconds. Defaults to Date.now() */ addMessageEvent(type: string, id: string, timestamp = 0) { + if (this.messageEvents.length >= + this.activeTraceParams.numberOfMessageEventsPerSpan) { + this.messageEvents.shift(); + this.droppedMessageEventsCount++; + } this.messageEvents.push({ 'type': type, 'id': id, diff --git a/packages/opencensus-core/src/trace/model/types.ts b/packages/opencensus-core/src/trace/model/types.ts index efb51b345..941c2211b 100644 --- a/packages/opencensus-core/src/trace/model/types.ts +++ b/packages/opencensus-core/src/trace/model/types.ts @@ -329,6 +329,12 @@ export interface Span { /** The number of dropped links. */ droppedLinksCount: number; + /** The number of dropped annotations. */ + droppedAnnotationsCount: number; + + /** The number of dropped message events. */ + droppedMessageEventsCount: number; + /** * Adds an atribute to the span. * @param key Describes the value added. diff --git a/packages/opencensus-core/test/test-root-span.ts b/packages/opencensus-core/test/test-root-span.ts index fe2ff92d4..a6ac03c41 100644 --- a/packages/opencensus-core/test/test-root-span.ts +++ b/packages/opencensus-core/test/test-root-span.ts @@ -206,6 +206,7 @@ describe('RootSpan', () => { rootSpan.addAnnotation('description test', {} as Attributes, Date.now()); assert.ok(rootSpan.annotations.length > 0); + assert.equal(rootSpan.droppedAnnotationsCount, 0); assert.ok(instanceOfAnnotation(rootSpan.annotations[0])); }); }); @@ -251,6 +252,7 @@ describe('RootSpan', () => { rootSpan.addMessageEvent('TYPE_UNSPECIFIED', 'message_event_test_id'); assert.ok(rootSpan.messageEvents.length > 0); + assert.equal(rootSpan.droppedMessageEventsCount, 0); assert.ok(instanceOfLink(rootSpan.messageEvents[0])); }); }); diff --git a/packages/opencensus-core/test/test-span.ts b/packages/opencensus-core/test/test-span.ts index 868bca087..e802baba6 100644 --- a/packages/opencensus-core/test/test-span.ts +++ b/packages/opencensus-core/test/test-span.ts @@ -28,7 +28,9 @@ import {Annotation, Attributes, Link} from '../src/trace/model/types'; const tracer = new CoreTracer(); tracer.activeTraceParams = { numberOfAttributesPerSpan: 32, - numberOfLinksPerSpan: 32 + numberOfLinksPerSpan: 32, + numberOfAnnontationEventsPerSpan: 32, + numberOfMessageEventsPerSpan: 32 }; describe('Span', () => { @@ -226,8 +228,23 @@ describe('Span', () => { span.addAnnotation('description test', {} as Attributes, Date.now()); assert.ok(span.annotations.length > 0); + assert.equal(span.droppedAnnotationsCount, 0); assert.ok(instanceOfAnnotation(span.annotations[0])); }); + + it('should drop extra annotations', () => { + const rootSpan = new RootSpan(tracer); + rootSpan.start(); + + const span = new Span(rootSpan); + span.start(); + for (let i = 0; i < 40; i++) { + span.addAnnotation('description test', {} as Attributes, Date.now()); + } + + assert.equal(span.annotations.length, 32); + assert.equal(span.droppedAnnotationsCount, 8); + }); }); /** @@ -289,8 +306,23 @@ describe('Span', () => { span.addMessageEvent('TYPE_UNSPECIFIED', 'message_event_test_id'); assert.ok(span.messageEvents.length > 0); + assert.equal(span.droppedMessageEventsCount, 0); assert.ok(instanceOfLink(span.messageEvents[0])); }); + + it('should drop extra Message Event', () => { + const rootSpan = new RootSpan(tracer); + rootSpan.start(); + + const span = new Span(rootSpan); + span.start(); + for (let i = 0; i < 35; i++) { + span.addMessageEvent('TYPE_UNSPECIFIED', 'message_event_test_id'); + } + + assert.equal(span.messageEvents.length, 32); + assert.equal(span.droppedMessageEventsCount, 3); + }); }); describe('setStatus()', () => { diff --git a/packages/opencensus-exporter-ocagent/src/adapters.ts b/packages/opencensus-exporter-ocagent/src/adapters.ts index 8dec96ac0..7a7c4a178 100644 --- a/packages/opencensus-exporter-ocagent/src/adapters.ts +++ b/packages/opencensus-exporter-ocagent/src/adapters.ts @@ -157,7 +157,8 @@ const adaptMessageEventType = (value: string): opencensus.proto.trace.v1.Span * @returns opencensus.proto.trace.v1.Span.TimeEvents */ const adaptTimeEvents = - (annotations: Annotation[], messageEvents: MessageEvent[]): + (annotations: Annotation[], messageEvents: MessageEvent[], + droppedAnnotationsCount: number, droppedMessageEventsCount: number): opencensus.proto.trace.v1.Span.TimeEvents => { const timeEvents: opencensus.proto.trace.v1.Span.TimeEvent[] = []; @@ -188,8 +189,8 @@ const adaptTimeEvents = return { timeEvent: timeEvents, - droppedAnnotationsCount: null, - droppedMessageEventsCount: null + droppedAnnotationsCount, + droppedMessageEventsCount }; }; @@ -274,7 +275,9 @@ export const adaptSpan = (span: Span): opencensus.proto.trace.v1.Span => { endTime: millisToTimestamp(span.endTime), attributes: adaptAttributes(span.attributes, span.droppedAttributesCount), stackTrace: null, // Unsupported by nodejs - timeEvents: adaptTimeEvents(span.annotations, span.messageEvents), + timeEvents: adaptTimeEvents( + span.annotations, span.messageEvents, span.droppedAnnotationsCount, + span.droppedMessageEventsCount), links: adaptLinks(span.links, span.droppedLinksCount), status: span.status, sameProcessAsParentSpan: adaptBoolean(!span.remoteParent), diff --git a/packages/opencensus-exporter-ocagent/test/test-ocagent.ts b/packages/opencensus-exporter-ocagent/test/test-ocagent.ts index e3ccb4d3a..8386bd44e 100644 --- a/packages/opencensus-exporter-ocagent/test/test-ocagent.ts +++ b/packages/opencensus-exporter-ocagent/test/test-ocagent.ts @@ -175,7 +175,12 @@ describe('OpenCensus Agent Exporter', () => { tracing = nodeTracing.start({ exporter: ocAgentExporter, samplingRate: INITIAL_SAMPLER_PROBABILITY, - traceParams: {numberOfAttributesPerSpan: 4, numberOfLinksPerSpan: 3} + traceParams: { + numberOfAttributesPerSpan: 4, + numberOfLinksPerSpan: 3, + numberOfAnnontationEventsPerSpan: 2, + numberOfMessageEventsPerSpan: 3 + } }); }); @@ -344,9 +349,16 @@ describe('OpenCensus Agent Exporter', () => { // Annotation rootSpan.addAnnotation( 'my_annotation', {myString: 'bar', myNumber: 123, myBoolean: true}); + rootSpan.addAnnotation( + 'my_annotation1', {myString: 'bar1', myNumber: 456, myBoolean: true}); + rootSpan.addAnnotation( + 'my_annotation2', {myString: 'bar2', myNumber: 789, myBoolean: true}); + rootSpan.addAnnotation( + 'my_annotation3', {myString: 'bar3', myNumber: 789, myBoolean: true}); // Message Event const timeStamp = 123456789; + rootSpan.addMessageEvent('MessageEventTypeSent', 'aaaa', timeStamp); rootSpan.addMessageEvent('MessageEventTypeSent', 'ffff', timeStamp); rootSpan.addMessageEvent('MessageEventTypeRecv', 'ffff', timeStamp); // Use of `null` is to force a `TYPE_UNSPECIFIED` value @@ -420,27 +432,46 @@ describe('OpenCensus Agent Exporter', () => { // Time Events assert.deepEqual(span.timeEvents, { - droppedAnnotationsCount: 0, - droppedMessageEventsCount: 0, + droppedAnnotationsCount: 2, + droppedMessageEventsCount: 1, timeEvent: [ { value: 'annotation', time: null, annotation: { description: - {value: 'my_annotation', truncatedByteCount: 0}, + {value: 'my_annotation2', truncatedByteCount: 0}, attributes: { attributeMap: { myString: { value: 'stringValue', - stringValue: {value: 'bar', truncatedByteCount: 0} + stringValue: {value: 'bar2', truncatedByteCount: 0} }, - myNumber: {value: 'intValue', intValue: '123'}, + myNumber: {value: 'intValue', intValue: '789'}, myBoolean: {value: 'boolValue', boolValue: true} }, droppedAttributesCount: 0 } - } + }, + }, + { + value: 'annotation', + time: null, + annotation: { + description: + {value: 'my_annotation3', truncatedByteCount: 0}, + attributes: { + attributeMap: { + myString: { + value: 'stringValue', + stringValue: {value: 'bar3', truncatedByteCount: 0} + }, + myNumber: {value: 'intValue', intValue: '789'}, + myBoolean: {value: 'boolValue', boolValue: true} + }, + droppedAttributesCount: 0 + } + }, }, { messageEvent: {