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

Commit 923148a

Browse files
authored
Enforce attribute limit (#330)
* Enforce attributes limits * fix tests * style fix and add more tests * fix review comments * Revert Attributes interface and add droppedAttributesCount to span
1 parent 57b1da5 commit 923148a

File tree

11 files changed

+100
-24
lines changed

11 files changed

+100
-24
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export class RootSpan extends SpanBase implements types.RootSpan {
5454
this.spansLocal = [];
5555
this.kind = context && context.kind ? context.kind : null;
5656
this.logger = tracer.logger || logger.logger();
57+
this.activeTraceParams = tracer.activeTraceParams;
5758
}
5859

5960
/** Gets span list from rootspan instance. */

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import {Logger} from '../../common/types';
1717
import {Clock} from '../../internal/clock';
1818
import {randomSpanId} from '../../internal/util';
19+
import * as configTypes from '../config/types';
1920
import * as types from './types';
2021

2122
const STATUS_OK = {
@@ -58,6 +59,11 @@ export abstract class SpanBase implements types.Span {
5859
status: types.Status = STATUS_OK;
5960
/** set isRootSpan */
6061
abstract get isRootSpan(): boolean;
62+
/** Trace Parameters */
63+
activeTraceParams: configTypes.TraceParams;
64+
65+
/** The number of dropped attributes. */
66+
droppedAttributesCount = 0;
6167

6268
/** Constructs a new SpanBaseModel instance. */
6369
constructor() {
@@ -136,6 +142,16 @@ export abstract class SpanBase implements types.Span {
136142
* @param value The result of an operation.
137143
*/
138144
addAttribute(key: string, value: string|number|boolean) {
145+
if (this.attributes[key]) {
146+
delete this.attributes[key];
147+
}
148+
149+
if (Object.keys(this.attributes).length >=
150+
this.activeTraceParams.numberOfAttributesPerSpan) {
151+
this.droppedAttributesCount++;
152+
const attributeKeyToDelete = Object.keys(this.attributes).shift();
153+
delete this.attributes[attributeKeyToDelete];
154+
}
139155
this.attributes[key] = value;
140156
}
141157

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export class Span extends SpanBase implements types.Span {
3535
this.root = root;
3636
this.logger = this.root.logger || logger.logger();
3737
this.parentSpanId = root.id;
38+
this.activeTraceParams = this.root.activeTraceParams;
3839
}
3940

4041
/** Gets trace id of span. */

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import * as cls from '../../internal/cls';
2020
import * as configTypes from '../config/types';
2121
import {TraceParams} from '../config/types';
2222
import {Propagation} from '../propagation/types';
23-
import * as samplerConstants from '../sampler/sampler';
2423
import {SamplerBuilder, TraceParamsBuilder} from '../sampler/sampler';
2524
import * as samplerTypes from '../sampler/types';
2625

@@ -45,26 +44,19 @@ export class CoreTracer implements types.Tracer {
4544
private endedTraces: types.RootSpan[] = [];
4645
/** Bit to represent whether trace is sampled or not. */
4746
private readonly IS_SAMPLED = 0x1;
48-
private readonly DEFAULT_TRACE_PARAMS: TraceParams = {
49-
numberOfAnnontationEventsPerSpan:
50-
samplerConstants.DEFAULT_SPAN_MAX_NUM_ANNOTATIONS,
51-
numberOfAttributesPerSpan: samplerConstants.DEFAULT_SPAN_MAX_NUM_ATTRIBUTES,
52-
numberOfLinksPerSpan: samplerConstants.DEFAULT_SPAN_MAX_NUM_LINKS,
53-
numberOfMessageEventsPerSpan: samplerConstants
54-
.DEFAULT_SPAN_MAX_NUM_MESSAGE_EVENTS
55-
};
5647
/** A sampler used to make sample decisions */
5748
sampler: samplerTypes.Sampler;
5849
/** A configuration for starting the tracer */
5950
logger: loggerTypes.Logger = logger.logger();
6051
/** A configuration object for trace parameters */
61-
activeTraceParams: TraceParams = this.DEFAULT_TRACE_PARAMS;
52+
activeTraceParams: TraceParams;
6253

6354
/** Constructs a new TraceImpl instance. */
6455
constructor() {
6556
this.activeLocal = false;
6657
this.contextManager = cls.createNamespace();
6758
this.clearCurrentTrace();
59+
this.activeTraceParams = {};
6860
}
6961

7062
/** Gets the current root span. */

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,12 @@ export interface Span {
320320
/** Gives the TraceContext of the span. */
321321
readonly spanContext: SpanContext;
322322

323+
/** The number of dropped attributes. */
324+
droppedAttributesCount: number;
325+
326+
/** Trace Parameters */
327+
activeTraceParams: configTypes.TraceParams;
328+
323329
/**
324330
* Adds an atribute to the span.
325331
* @param key Describes the value added.
@@ -393,6 +399,9 @@ export interface Tracer extends SpanEventListener {
393399
/** A configuration for starting the tracer */
394400
logger: loggerTypes.Logger;
395401

402+
/** A configuration object for trace parameters */
403+
activeTraceParams: configTypes.TraceParams;
404+
396405
/** A propagation instance */
397406
readonly propagation: Propagation;
398407

packages/opencensus-core/test/test-tracer.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,13 @@ describe('Tracer', () => {
245245
const tracer = new CoreTracer();
246246
tracer.start(defaultConfig);
247247
assert.equal(
248-
tracer.activeTraceParams.numberOfAnnontationEventsPerSpan, 32);
249-
assert.equal(tracer.activeTraceParams.numberOfAttributesPerSpan, 32);
250-
assert.equal(tracer.activeTraceParams.numberOfLinksPerSpan, 32);
248+
tracer.activeTraceParams.numberOfAnnontationEventsPerSpan,
249+
undefined);
251250
assert.equal(
252-
tracer.activeTraceParams.numberOfMessageEventsPerSpan, 128);
251+
tracer.activeTraceParams.numberOfAttributesPerSpan, undefined);
252+
assert.equal(tracer.activeTraceParams.numberOfLinksPerSpan, undefined);
253+
assert.equal(
254+
tracer.activeTraceParams.numberOfMessageEventsPerSpan, undefined);
253255
});
254256

255257
it('should create a tracer with default TraceParams when parameters with values higher than maximum limit are specified upon initialisation',

packages/opencensus-exporter-ocagent/src/adapters.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ const spanKindToEnum =
8585
* @param attributes Attributes
8686
* @returns opencensus.proto.trace.v1.Span.Attributes
8787
*/
88-
const adaptAttributes = (attributes: Attributes):
88+
const adaptAttributes = (attributes: Attributes,
89+
droppedAttributesCount: number):
8990
opencensus.proto.trace.v1.Span.Attributes|null => {
9091
if (!attributes) {
9192
return null;
@@ -122,7 +123,7 @@ const adaptAttributes = (attributes: Attributes):
122123
attributeMap[name] = {stringValue, intValue, boolValue};
123124
});
124125

125-
return {attributeMap, droppedAttributesCount: null};
126+
return {attributeMap, droppedAttributesCount};
126127
};
127128

128129
/**
@@ -167,7 +168,7 @@ const adaptTimeEvents =
167168
time: null,
168169
annotation: {
169170
description: stringToTruncatableString(annotation.description),
170-
attributes: adaptAttributes(annotation.attributes)
171+
attributes: adaptAttributes(annotation.attributes, 0)
171172
}
172173
});
173174
});
@@ -235,7 +236,7 @@ const adaptLink = (link: Link): opencensus.proto.trace.v1.Span.Link => {
235236
}
236237
}
237238

238-
const attributes = adaptAttributes(link.attributes);
239+
const attributes = adaptAttributes(link.attributes, 0);
239240

240241
return {traceId, spanId, type, attributes};
241242
};
@@ -272,7 +273,7 @@ export const adaptSpan = (span: Span): opencensus.proto.trace.v1.Span => {
272273
kind: spanKindToEnum(span.kind),
273274
startTime: millisToTimestamp(span.startTime),
274275
endTime: millisToTimestamp(span.endTime),
275-
attributes: adaptAttributes(span.attributes),
276+
attributes: adaptAttributes(span.attributes, span.droppedAttributesCount),
276277
stackTrace: null, // Unsupported by nodejs
277278
timeEvents: adaptTimeEvents(span.annotations, span.messageEvents),
278279
links: adaptLinks(span.links),

packages/opencensus-exporter-ocagent/test/test-ocagent.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,11 @@ describe('OpenCensus Agent Exporter', () => {
172172
bufferSize: 1,
173173
bufferTimeout: 0
174174
});
175-
tracing = nodeTracing.start(
176-
{exporter: ocAgentExporter, samplingRate: INITIAL_SAMPLER_PROBABILITY});
175+
tracing = nodeTracing.start({
176+
exporter: ocAgentExporter,
177+
samplingRate: INITIAL_SAMPLER_PROBABILITY,
178+
traceParams: {numberOfAttributesPerSpan: 4}
179+
});
177180
});
178181

179182
afterEach(() => {
@@ -331,7 +334,10 @@ describe('OpenCensus Agent Exporter', () => {
331334
rootSpan.setStatus(CanonicalCode.OK);
332335

333336
// Attribute
337+
rootSpan.addAttribute('my_first_attribute', 'foo');
338+
rootSpan.addAttribute('my_second_attribute', 'foo2');
334339
rootSpan.addAttribute('my_attribute_string', 'bar2');
340+
rootSpan.addAttribute('my_first_attribute', 'foo1');
335341
rootSpan.addAttribute('my_attribute_number', 456);
336342
rootSpan.addAttribute('my_attribute_boolean', false);
337343

@@ -397,13 +403,18 @@ describe('OpenCensus Agent Exporter', () => {
397403
return;
398404
}
399405
assert.deepEqual(span.attributes.attributeMap, {
406+
my_first_attribute: {
407+
value: 'stringValue',
408+
stringValue: {value: 'foo1', truncatedByteCount: 0}
409+
},
400410
my_attribute_string: {
401411
value: 'stringValue',
402412
stringValue: {value: 'bar2', truncatedByteCount: 0}
403413
},
404414
my_attribute_number: {value: 'intValue', intValue: '456'},
405415
my_attribute_boolean: {value: 'boolValue', boolValue: false}
406416
});
417+
assert.equal(span.attributes.droppedAttributesCount, 1);
407418

408419
// Time Events
409420
assert.deepEqual(span.timeEvents, {

packages/opencensus-nodejs/src/trace/config/default-config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ export const defaultConfig = {
2929
plugins: {},
3030
bufferSize: Constants.DEFAULT_BUFFER_SIZE,
3131
bufferTimeout: Constants.DEFAULT_BUFFER_TIMEOUT,
32-
samplingRate: 1
32+
samplingRate: 1,
33+
traceParams: Constants.DEFAULT_TRACE_PARAMS
3334
};

packages/opencensus-nodejs/src/trace/constants.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import {DEFAULT_INSTRUMENTATION_MODULES} from '@opencensus/instrumentation-all';
1818

19-
2019
/** General purpose constants. */
2120
const constants = {
2221
/** Default maximum size of a buffer. */
@@ -28,7 +27,14 @@ const constants = {
2827
/** OpenCensus Scope */
2928
OPENCENSUS_SCOPE: '@opencensus',
3029
/** Default prefix for instrumentation modules */
31-
DEFAULT_PLUGIN_PACKAGE_NAME_PREFIX: 'instrumentation'
30+
DEFAULT_PLUGIN_PACKAGE_NAME_PREFIX: 'instrumentation',
31+
/** Default Limit for Trace Parameters */
32+
DEFAULT_TRACE_PARAMS: {
33+
numberOfAnnontationEventsPerSpan: 32,
34+
numberOfAttributesPerSpan: 32,
35+
numberOfLinksPerSpan: 32,
36+
numberOfMessageEventsPerSpan: 128
37+
}
3238
};
3339

3440
export {constants as Constants};

0 commit comments

Comments
 (0)