Skip to content

Commit

Permalink
feat(sdk-trace-base): add dropped attributes and events count on span
Browse files Browse the repository at this point in the history
  • Loading branch information
mohitk05 committed Jan 27, 2023
1 parent 3670071 commit b2c9f40
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 15 deletions.
6 changes: 5 additions & 1 deletion api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ export {
export type { PropagationAPI } from './api/propagation';

// Trace APIs
export { SpanAttributes, SpanAttributeValue } from './trace/attributes';
export {
SpanAttributes,
SpanAttributeValue,
SpanDroppedAttributes,
} from './trace/attributes';
export { Link } from './trace/link';
export { ProxyTracer, TracerDelegator } from './trace/ProxyTracer';
export { ProxyTracerProvider } from './trace/ProxyTracerProvider';
Expand Down
6 changes: 6 additions & 0 deletions api/src/trace/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,9 @@ export type SpanAttributes = Attributes;
* @deprecated please use {@link AttributeValue}
*/
export type SpanAttributeValue = AttributeValue;

/**
* Dropped attributes count is a map of key-value pairs
* of attributes that were dropped due to collection limits
*/
export type SpanDroppedAttributes = Attributes | undefined;
15 changes: 15 additions & 0 deletions experimental/packages/exporter-trace-otlp-proto/tsconfig.esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
},
{
"path": "../../../packages/opentelemetry-core"
},
{
"path": "../../../packages/opentelemetry-resources"
},
{
"path": "../../../packages/opentelemetry-sdk-trace-base"
},
{
"path": "../otlp-exporter-base"
},
{
"path": "../otlp-proto-exporter-base"
},
{
"path": "../otlp-transformer"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
},
{
"path": "../../../packages/opentelemetry-core"
},
{
"path": "../../../packages/opentelemetry-resources"
},
{
"path": "../../../packages/opentelemetry-sdk-trace-base"
},
{
"path": "../otlp-exporter-base"
},
{
"path": "../otlp-proto-exporter-base"
},
{
"path": "../otlp-transformer"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
},
{
"path": "../../../packages/opentelemetry-core"
},
{
"path": "../otlp-exporter-base"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
{
"extends": "../../../tsconfig.base.esnext.json",
"compilerOptions": {
"allowJs": true,
"outDir": "build/esnext",
"rootDir": "src",
"outDir": "build/esnext",
"tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo"
},
"include": [
"src/**/*.ts",
"src/generated/*.js",
"src/**/*.ts"
],
"references": [
{
"path": "../../../api"
},
{
"path": "../../../packages/opentelemetry-core"
},
{
"path": "../otlp-exporter-base"
}
]
}
41 changes: 32 additions & 9 deletions packages/opentelemetry-sdk-trace-base/src/Span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
SpanAttributes,
SpanAttributeValue,
SpanContext,
SpanDroppedAttributes,
SpanKind,
SpanStatus,
SpanStatusCode,
Expand All @@ -47,7 +48,7 @@ import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { ExceptionEventName } from './enums';
import { ReadableSpan } from './export/ReadableSpan';
import { SpanProcessor } from './SpanProcessor';
import { TimedEvent } from './TimedEvent';
import { SpanDroppedEvents, TimedEvent } from './TimedEvent';
import { Tracer } from './Tracer';
import { SpanLimits } from './types';

Expand All @@ -66,6 +67,10 @@ export class Span implements APISpan, ReadableSpan {
readonly startTime: HrTime;
readonly resource: Resource;
readonly instrumentationLibrary: InstrumentationLibrary;

droppedAttributesCount: SpanDroppedAttributes;
droppedEventsCount: SpanDroppedEvents;

name: string;
status: SpanStatus = {
code: SpanStatusCode.UNSET,
Expand Down Expand Up @@ -141,6 +146,10 @@ export class Span implements APISpan, ReadableSpan {
this._spanLimits.attributeCountLimit! &&
!Object.prototype.hasOwnProperty.call(this.attributes, key)
) {
if (!this.droppedAttributesCount) {
this.droppedAttributesCount = {};
}
this.droppedAttributesCount[key] = this._truncateToSize(value);
return this;
}
this.attributes[key] = this._truncateToSize(value);
Expand All @@ -167,14 +176,6 @@ export class Span implements APISpan, ReadableSpan {
timeStamp?: TimeInput
): this {
if (this._isSpanEnded()) return this;
if (this._spanLimits.eventCountLimit === 0) {
diag.warn('No events allowed.');
return this;
}
if (this.events.length >= this._spanLimits.eventCountLimit!) {
diag.warn('Dropping extra events.');
this.events.shift();
}

if (isTimeInput(attributesOrStartTime)) {
if (!isTimeInput(timeStamp)) {
Expand All @@ -184,6 +185,28 @@ export class Span implements APISpan, ReadableSpan {
}

const attributes = sanitizeAttributes(attributesOrStartTime);

if (this._spanLimits.eventCountLimit === 0) {
diag.warn('No events allowed.');
if (!this.droppedEventsCount) {
this.droppedEventsCount = {};
}
this.droppedEventsCount[name] = {
name,
attributes,
time: this._getTime(timeStamp),
};
return this;
}
if (this.events.length >= this._spanLimits.eventCountLimit!) {
diag.warn('Dropping extra events.');
const dropped = this.events.shift();
if (!this.droppedEventsCount) {
this.droppedEventsCount = {};
}
this.droppedEventsCount[dropped!.name] = dropped!;
}

this.events.push({
name,
attributes,
Expand Down
6 changes: 6 additions & 0 deletions packages/opentelemetry-sdk-trace-base/src/TimedEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ export interface TimedEvent {
/** The attributes of the event. */
attributes?: SpanAttributes;
}

export type SpanDroppedEvents =
| {
[name: string]: TimedEvent;
}
| undefined;
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import {
HrTime,
Link,
SpanContext,
SpanDroppedAttributes,
} from '@opentelemetry/api';
import { Resource } from '@opentelemetry/resources';
import { InstrumentationLibrary } from '@opentelemetry/core';
import { TimedEvent } from '../TimedEvent';
import { TimedEvent, SpanDroppedEvents } from '../TimedEvent';

export interface ReadableSpan {
readonly name: string;
Expand All @@ -41,4 +42,6 @@ export interface ReadableSpan {
readonly ended: boolean;
readonly resource: Resource;
readonly instrumentationLibrary: InstrumentationLibrary;
readonly droppedAttributesCount: SpanDroppedAttributes;
readonly droppedEventsCount: SpanDroppedEvents;
}
43 changes: 43 additions & 0 deletions packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,17 @@ describe('Span', () => {
assert.strictEqual(span.attributes['foo99'], 'bar99');
assert.strictEqual(span.attributes['foo149'], undefined);
});

it('should store all dropped attributes in droppedAttributesCount', () => {
assert.ok(span.droppedAttributesCount);
assert.strictEqual(
Object.keys(span.droppedAttributesCount).length,
50
);
assert.strictEqual(span.droppedAttributesCount['foo100'], 'bar100');
assert.strictEqual(span.droppedAttributesCount['foo149'], 'bar149');
assert.strictEqual(span.droppedAttributesCount['foo99'], undefined);
});
});

describe('when "attributeValueLengthLimit" option defined', () => {
Expand Down Expand Up @@ -791,6 +802,38 @@ describe('Span', () => {
assert.strictEqual(span.events[span.events.length - 1].name, 'sent149');
});

it('should store dropped events in droppedEventsCount', () => {
const span = new Span(
tracer,
ROOT_CONTEXT,
name,
spanContext,
SpanKind.CLIENT
);
const testAttributes = {
attribute_1: 'forty-two',
};
for (let i = 0; i < 150; i++) {
if (i === 42) {
span.addEvent('sent42', testAttributes);
} else {
span.addEvent('sent' + i);
}
}
span.end();

assert.ok(span.droppedEventsCount);
assert.strictEqual(Object.keys(span.droppedEventsCount).length, 50);
assert.strictEqual(span.droppedEventsCount['sent0'].name, 'sent0');
assert.strictEqual(span.droppedEventsCount['sent42'].name, 'sent42');
assert.ok(span.droppedEventsCount['sent42'].attributes);
assert.strictEqual(
span.droppedEventsCount['sent42'].attributes['attribute_1'],
'forty-two'
);
assert.strictEqual(span.droppedEventsCount['sent50'], undefined);
});

it('should add no event', () => {
const tracer = new BasicTracerProvider({
spanLimits: {
Expand Down
6 changes: 6 additions & 0 deletions tsconfig.esm.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
{
"path": "experimental/packages/exporter-trace-otlp-http/tsconfig.esm.json"
},
{
"path": "experimental/packages/exporter-trace-otlp-proto/tsconfig.esm.json"
},
{
"path": "experimental/packages/opentelemetry-browser-detector/tsconfig.esm.json"
},
Expand All @@ -29,6 +32,9 @@
{
"path": "experimental/packages/otlp-exporter-base/tsconfig.esm.json"
},
{
"path": "experimental/packages/otlp-proto-exporter-base/tsconfig.esm.json"
},
{
"path": "experimental/packages/otlp-transformer/tsconfig.esm.json"
},
Expand Down
6 changes: 6 additions & 0 deletions tsconfig.esnext.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
{
"path": "experimental/packages/exporter-trace-otlp-http/tsconfig.esnext.json"
},
{
"path": "experimental/packages/exporter-trace-otlp-proto/tsconfig.esnext.json"
},
{
"path": "experimental/packages/opentelemetry-browser-detector/tsconfig.esnext.json"
},
Expand All @@ -29,6 +32,9 @@
{
"path": "experimental/packages/otlp-exporter-base/tsconfig.esnext.json"
},
{
"path": "experimental/packages/otlp-proto-exporter-base/tsconfig.esnext.json"
},
{
"path": "experimental/packages/otlp-transformer/tsconfig.esnext.json"
},
Expand Down

0 comments on commit b2c9f40

Please sign in to comment.