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

Commit

Permalink
Enforce attribute limit (#330)
Browse files Browse the repository at this point in the history
* Enforce attributes limits

* fix tests

* style fix and add more tests

* fix review comments

* Revert Attributes interface and add droppedAttributesCount to span
  • Loading branch information
mayurkale22 authored Feb 6, 2019
1 parent 57b1da5 commit 923148a
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 24 deletions.
1 change: 1 addition & 0 deletions packages/opencensus-core/src/trace/model/root-span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export class RootSpan extends SpanBase implements types.RootSpan {
this.spansLocal = [];
this.kind = context && context.kind ? context.kind : null;
this.logger = tracer.logger || logger.logger();
this.activeTraceParams = tracer.activeTraceParams;
}

/** Gets span list from rootspan instance. */
Expand Down
16 changes: 16 additions & 0 deletions packages/opencensus-core/src/trace/model/span-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import {Logger} from '../../common/types';
import {Clock} from '../../internal/clock';
import {randomSpanId} from '../../internal/util';
import * as configTypes from '../config/types';
import * as types from './types';

const STATUS_OK = {
Expand Down Expand Up @@ -58,6 +59,11 @@ export abstract class SpanBase implements types.Span {
status: types.Status = STATUS_OK;
/** set isRootSpan */
abstract get isRootSpan(): boolean;
/** Trace Parameters */
activeTraceParams: configTypes.TraceParams;

/** The number of dropped attributes. */
droppedAttributesCount = 0;

/** Constructs a new SpanBaseModel instance. */
constructor() {
Expand Down Expand Up @@ -136,6 +142,16 @@ export abstract class SpanBase implements types.Span {
* @param value The result of an operation.
*/
addAttribute(key: string, value: string|number|boolean) {
if (this.attributes[key]) {
delete this.attributes[key];
}

if (Object.keys(this.attributes).length >=
this.activeTraceParams.numberOfAttributesPerSpan) {
this.droppedAttributesCount++;
const attributeKeyToDelete = Object.keys(this.attributes).shift();
delete this.attributes[attributeKeyToDelete];
}
this.attributes[key] = value;
}

Expand Down
1 change: 1 addition & 0 deletions packages/opencensus-core/src/trace/model/span.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class Span extends SpanBase implements types.Span {
this.root = root;
this.logger = this.root.logger || logger.logger();
this.parentSpanId = root.id;
this.activeTraceParams = this.root.activeTraceParams;
}

/** Gets trace id of span. */
Expand Down
12 changes: 2 additions & 10 deletions packages/opencensus-core/src/trace/model/tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import * as cls from '../../internal/cls';
import * as configTypes from '../config/types';
import {TraceParams} from '../config/types';
import {Propagation} from '../propagation/types';
import * as samplerConstants from '../sampler/sampler';
import {SamplerBuilder, TraceParamsBuilder} from '../sampler/sampler';
import * as samplerTypes from '../sampler/types';

Expand All @@ -45,26 +44,19 @@ export class CoreTracer implements types.Tracer {
private endedTraces: types.RootSpan[] = [];
/** Bit to represent whether trace is sampled or not. */
private readonly IS_SAMPLED = 0x1;
private readonly DEFAULT_TRACE_PARAMS: TraceParams = {
numberOfAnnontationEventsPerSpan:
samplerConstants.DEFAULT_SPAN_MAX_NUM_ANNOTATIONS,
numberOfAttributesPerSpan: samplerConstants.DEFAULT_SPAN_MAX_NUM_ATTRIBUTES,
numberOfLinksPerSpan: samplerConstants.DEFAULT_SPAN_MAX_NUM_LINKS,
numberOfMessageEventsPerSpan: samplerConstants
.DEFAULT_SPAN_MAX_NUM_MESSAGE_EVENTS
};
/** A sampler used to make sample decisions */
sampler: samplerTypes.Sampler;
/** A configuration for starting the tracer */
logger: loggerTypes.Logger = logger.logger();
/** A configuration object for trace parameters */
activeTraceParams: TraceParams = this.DEFAULT_TRACE_PARAMS;
activeTraceParams: TraceParams;

/** Constructs a new TraceImpl instance. */
constructor() {
this.activeLocal = false;
this.contextManager = cls.createNamespace();
this.clearCurrentTrace();
this.activeTraceParams = {};
}

/** Gets the current root span. */
Expand Down
9 changes: 9 additions & 0 deletions packages/opencensus-core/src/trace/model/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,12 @@ export interface Span {
/** Gives the TraceContext of the span. */
readonly spanContext: SpanContext;

/** The number of dropped attributes. */
droppedAttributesCount: number;

/** Trace Parameters */
activeTraceParams: configTypes.TraceParams;

/**
* Adds an atribute to the span.
* @param key Describes the value added.
Expand Down Expand Up @@ -393,6 +399,9 @@ export interface Tracer extends SpanEventListener {
/** A configuration for starting the tracer */
logger: loggerTypes.Logger;

/** A configuration object for trace parameters */
activeTraceParams: configTypes.TraceParams;

/** A propagation instance */
readonly propagation: Propagation;

Expand Down
10 changes: 6 additions & 4 deletions packages/opencensus-core/test/test-tracer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,13 @@ describe('Tracer', () => {
const tracer = new CoreTracer();
tracer.start(defaultConfig);
assert.equal(
tracer.activeTraceParams.numberOfAnnontationEventsPerSpan, 32);
assert.equal(tracer.activeTraceParams.numberOfAttributesPerSpan, 32);
assert.equal(tracer.activeTraceParams.numberOfLinksPerSpan, 32);
tracer.activeTraceParams.numberOfAnnontationEventsPerSpan,
undefined);
assert.equal(
tracer.activeTraceParams.numberOfMessageEventsPerSpan, 128);
tracer.activeTraceParams.numberOfAttributesPerSpan, undefined);
assert.equal(tracer.activeTraceParams.numberOfLinksPerSpan, undefined);
assert.equal(
tracer.activeTraceParams.numberOfMessageEventsPerSpan, undefined);
});

it('should create a tracer with default TraceParams when parameters with values higher than maximum limit are specified upon initialisation',
Expand Down
11 changes: 6 additions & 5 deletions packages/opencensus-exporter-ocagent/src/adapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ const spanKindToEnum =
* @param attributes Attributes
* @returns opencensus.proto.trace.v1.Span.Attributes
*/
const adaptAttributes = (attributes: Attributes):
const adaptAttributes = (attributes: Attributes,
droppedAttributesCount: number):
opencensus.proto.trace.v1.Span.Attributes|null => {
if (!attributes) {
return null;
Expand Down Expand Up @@ -122,7 +123,7 @@ const adaptAttributes = (attributes: Attributes):
attributeMap[name] = {stringValue, intValue, boolValue};
});

return {attributeMap, droppedAttributesCount: null};
return {attributeMap, droppedAttributesCount};
};

/**
Expand Down Expand Up @@ -167,7 +168,7 @@ const adaptTimeEvents =
time: null,
annotation: {
description: stringToTruncatableString(annotation.description),
attributes: adaptAttributes(annotation.attributes)
attributes: adaptAttributes(annotation.attributes, 0)
}
});
});
Expand Down Expand Up @@ -235,7 +236,7 @@ const adaptLink = (link: Link): opencensus.proto.trace.v1.Span.Link => {
}
}

const attributes = adaptAttributes(link.attributes);
const attributes = adaptAttributes(link.attributes, 0);

return {traceId, spanId, type, attributes};
};
Expand Down Expand Up @@ -272,7 +273,7 @@ export const adaptSpan = (span: Span): opencensus.proto.trace.v1.Span => {
kind: spanKindToEnum(span.kind),
startTime: millisToTimestamp(span.startTime),
endTime: millisToTimestamp(span.endTime),
attributes: adaptAttributes(span.attributes),
attributes: adaptAttributes(span.attributes, span.droppedAttributesCount),
stackTrace: null, // Unsupported by nodejs
timeEvents: adaptTimeEvents(span.annotations, span.messageEvents),
links: adaptLinks(span.links),
Expand Down
15 changes: 13 additions & 2 deletions packages/opencensus-exporter-ocagent/test/test-ocagent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,11 @@ describe('OpenCensus Agent Exporter', () => {
bufferSize: 1,
bufferTimeout: 0
});
tracing = nodeTracing.start(
{exporter: ocAgentExporter, samplingRate: INITIAL_SAMPLER_PROBABILITY});
tracing = nodeTracing.start({
exporter: ocAgentExporter,
samplingRate: INITIAL_SAMPLER_PROBABILITY,
traceParams: {numberOfAttributesPerSpan: 4}
});
});

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

// Attribute
rootSpan.addAttribute('my_first_attribute', 'foo');
rootSpan.addAttribute('my_second_attribute', 'foo2');
rootSpan.addAttribute('my_attribute_string', 'bar2');
rootSpan.addAttribute('my_first_attribute', 'foo1');
rootSpan.addAttribute('my_attribute_number', 456);
rootSpan.addAttribute('my_attribute_boolean', false);

Expand Down Expand Up @@ -397,13 +403,18 @@ describe('OpenCensus Agent Exporter', () => {
return;
}
assert.deepEqual(span.attributes.attributeMap, {
my_first_attribute: {
value: 'stringValue',
stringValue: {value: 'foo1', truncatedByteCount: 0}
},
my_attribute_string: {
value: 'stringValue',
stringValue: {value: 'bar2', truncatedByteCount: 0}
},
my_attribute_number: {value: 'intValue', intValue: '456'},
my_attribute_boolean: {value: 'boolValue', boolValue: false}
});
assert.equal(span.attributes.droppedAttributesCount, 1);

// Time Events
assert.deepEqual(span.timeEvents, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ export const defaultConfig = {
plugins: {},
bufferSize: Constants.DEFAULT_BUFFER_SIZE,
bufferTimeout: Constants.DEFAULT_BUFFER_TIMEOUT,
samplingRate: 1
samplingRate: 1,
traceParams: Constants.DEFAULT_TRACE_PARAMS
};
10 changes: 8 additions & 2 deletions packages/opencensus-nodejs/src/trace/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

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


/** General purpose constants. */
const constants = {
/** Default maximum size of a buffer. */
Expand All @@ -28,7 +27,14 @@ const constants = {
/** OpenCensus Scope */
OPENCENSUS_SCOPE: '@opencensus',
/** Default prefix for instrumentation modules */
DEFAULT_PLUGIN_PACKAGE_NAME_PREFIX: 'instrumentation'
DEFAULT_PLUGIN_PACKAGE_NAME_PREFIX: 'instrumentation',
/** Default Limit for Trace Parameters */
DEFAULT_TRACE_PARAMS: {
numberOfAnnontationEventsPerSpan: 32,
numberOfAttributesPerSpan: 32,
numberOfLinksPerSpan: 32,
numberOfMessageEventsPerSpan: 128
}
};

export {constants as Constants};
36 changes: 36 additions & 0 deletions packages/opencensus-nodejs/test/test-tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ describe('Tracing', () => {
tracing.config.plugins['https'],
`${Constants.OPENCENSUS_SCOPE}/${
Constants.DEFAULT_PLUGIN_PACKAGE_NAME_PREFIX}-https`);
assert.strictEqual(
defaultConfig.traceParams.numberOfAnnontationEventsPerSpan, 32);
assert.strictEqual(
defaultConfig.traceParams.numberOfAttributesPerSpan, 32);
assert.strictEqual(defaultConfig.traceParams.numberOfLinksPerSpan, 32);
assert.strictEqual(
defaultConfig.traceParams.numberOfMessageEventsPerSpan, 128);
});

it('should start tracing with a non-default logLevel', () => {
Expand Down Expand Up @@ -157,6 +164,35 @@ describe('Tracing', () => {
`${Constants.OPENCENSUS_SCOPE}/${
Constants.DEFAULT_PLUGIN_PACKAGE_NAME_PREFIX}-https`);
});

it('should start with a non-default traceparams', () => {
tracing.start({
traceParams: {
numberOfAttributesPerSpan: 10,
numberOfAnnontationEventsPerSpan: 5,
numberOfLinksPerSpan: 8,
numberOfMessageEventsPerSpan: 100
}
});
assert.strictEqual(
tracing.config.traceParams.numberOfAttributesPerSpan, 10);
assert.strictEqual(
tracing.config.traceParams.numberOfAnnontationEventsPerSpan, 5);
assert.strictEqual(tracing.config.traceParams.numberOfLinksPerSpan, 8);
assert.strictEqual(
tracing.config.traceParams.numberOfMessageEventsPerSpan, 100);
});

it('should start with a non-default and default traceparams', () => {
tracing.start({traceParams: {numberOfAttributesPerSpan: 10}});
assert.strictEqual(
tracing.config.traceParams.numberOfAttributesPerSpan, 10);
assert.strictEqual(
tracing.config.traceParams.numberOfAnnontationEventsPerSpan, 32);
assert.strictEqual(tracing.config.traceParams.numberOfLinksPerSpan, 32);
assert.strictEqual(
tracing.config.traceParams.numberOfMessageEventsPerSpan, 128);
});
});
});

Expand Down

0 comments on commit 923148a

Please sign in to comment.