Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Field 'ai.operation.name' on type 'ContextTagKeys' is too long Expected: 1024 characters #1692 #1693

Merged
merged 1 commit into from
Oct 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1530,5 +1530,49 @@ export class SenderTests extends AITestClass {
QUnit.assert.equal(SendRequestReason.MaxBatchSize, sendNotifications[0].sendReason);
}
});

this.testCase({
name: 'Envelope: operation.name is correctly truncated if required',
test: () => {
const excessiveName = new Array(1234).join("a"); // exceeds max of 1024

const bd = new Exception(
null,
new Error(),
{"property1": "val1", "property2": "val2" },
{"measurement1": 50.0, "measurement2": 1.3 }
);
const inputEnvelope: ITelemetryItem = {
name: "test",
time: new Date("2018-06-12").toISOString(),
iKey: "iKey",
baseType: Exception.dataType,
baseData: bd,
data: {
"property3": "val3",
"measurement3": 3.0
},
ext: {
"trace": {
"traceID": "1528B5FF-6455-4657-BE77-E6664CAC72DC",
"parentID": "1528B5FF-6455-4657-BE77-E6664CACEEEE",
"name": excessiveName
}
},
tags: [
{"user.accountId": "TestAccountId"},
],
};

// Act
const appInsightsEnvelope = Sender.constructEnvelope(inputEnvelope, this._instrumentationKey, null);
const baseData = appInsightsEnvelope.data.baseData;

QUnit.assert.equal("val3", baseData.properties["property3"], "ExceptionData: customProperties (item.data) are added to the properties of the envelope and not included in the item.data")
QUnit.assert.equal("val1", baseData.properties["property1"], "ExceptionData: properties (item.baseData.properties) are added to telemetry envelope");
QUnit.assert.equal(50.0, baseData.measurements["measurement1"], "ExceptionData: measurements (item.baseData.measurements) are added to telemetry envelope");
QUnit.assert.equal(1024, appInsightsEnvelope.tags["ai.operation.name"].length, "The ai.operation.name should have been truncated to the maximum");
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
IPageViewPerformanceTelemetry, CtxTagKeys,
HttpMethod, IPageViewTelemetryInternal, IWeb,
IExceptionInternal,
SampleRate
SampleRate,
dataSanitizeString
} from "@microsoft/applicationinsights-common";
import {
ITelemetryItem, IDiagnosticLogger, LoggingSeverity, _InternalMessageId, hasJSON, getJSON, objForEachKey,
Expand All @@ -25,7 +26,7 @@ function _setValueIf<T>(target:T, field:keyof T, value:any) {
/*
* Maps Part A data from CS 4.0
*/
function _extractPartAExtensions(item: ITelemetryItem, env: IEnvelope) {
function _extractPartAExtensions(logger: IDiagnosticLogger, item: ITelemetryItem, env: IEnvelope) {
// todo: switch to keys from common in this method
let envTags = env.tags = env.tags || {};
let itmExt = item.ext = item.ext || {};
Expand Down Expand Up @@ -77,7 +78,7 @@ function _extractPartAExtensions(item: ITelemetryItem, env: IEnvelope) {
let extTrace = itmExt.trace;
if (extTrace) {
_setValueIf(envTags, CtxTagKeys.operationParentId, extTrace.parentID);
_setValueIf(envTags, CtxTagKeys.operationName, extTrace.name);
_setValueIf(envTags, CtxTagKeys.operationName, dataSanitizeString(logger, extTrace.name));
_setValueIf(envTags, CtxTagKeys.operationId, extTrace.traceID);
}

Expand Down Expand Up @@ -157,7 +158,7 @@ function _createEnvelope<T>(logger: IDiagnosticLogger, envelopeType: string, tel
envelope.name = envelope.name.replace("{0}", iKeyNoDashes);

// extract all extensions from ctx
_extractPartAExtensions(telemetryItem, envelope);
_extractPartAExtensions(logger, telemetryItem, envelope);

// loop through the envelope tags (extension of Part A) and pick out the ones that should go in outgoing envelope tags
telemetryItem.tags = telemetryItem.tags || [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
IExceptionTelemetry, ITraceTelemetry, IMetricTelemetry, IAutoExceptionTelemetry,
IPageViewTelemetryInternal, IPageViewTelemetry, IPageViewPerformanceTelemetry, IPageViewPerformanceTelemetryInternal,
dateTimeUtilsDuration, IExceptionInternal, PropertiesPluginIdentifier, AnalyticsPluginIdentifier, stringToBoolOrDefault, createDomEvent,
strNotSpecified, isCrossOriginError, utlDisableStorage
strNotSpecified, isCrossOriginError, utlDisableStorage, dataSanitizeString
} from "@microsoft/applicationinsights-common";

import {
Expand Down Expand Up @@ -684,7 +684,8 @@ export class ApplicationInsights extends BaseTelemetryPlugin implements IAppInsi
traceLocationName = _location.pathname + (_location.hash || "");
}

_properties.context.telemetryTrace.name = traceLocationName;
// This populates the ai.operation.name which has a maximum size of 1024 so we need to sanitize it
_properties.context.telemetryTrace.name = dataSanitizeString(_self.diagLog(), traceLocationName);
}
if (_currUri) {
_prevUri = _currUri;
Expand Down
14 changes: 7 additions & 7 deletions shared/AppInsightsCommon/src/Telemetry/Common/DataSanitizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ export function dataSanitizeKeyAndAddUniqueness(logger: IDiagnosticLogger, key:
export function dataSanitizeKey(logger: IDiagnosticLogger, name: any) {
let nameTrunc: String;
if (name) {
// Remove any leading or trailing whitepace
// Remove any leading or trailing whitespace
name = strTrim(name.toString());

// truncate the string to 150 chars
if (name.length > DataSanitizerValues.MAX_NAME_LENGTH) {
nameTrunc = name.substring(0, DataSanitizerValues.MAX_NAME_LENGTH);
logger.throwInternal(
logger && logger.throwInternal(
LoggingSeverity.WARNING,
_InternalMessageId.NameTooLong,
"name is too long. It has been truncated to " + DataSanitizerValues.MAX_NAME_LENGTH + " characters.",
Expand All @@ -84,7 +84,7 @@ export function dataSanitizeString(logger: IDiagnosticLogger, value: any, maxLen
value = strTrim(value);
if (value.toString().length > maxLength) {
valueTrunc = value.toString().substring(0, maxLength);
logger.throwInternal(
logger && logger.throwInternal(
LoggingSeverity.WARNING,
_InternalMessageId.StringValueTooLong,
"string value is too long. It has been truncated to " + maxLength + " characters.",
Expand All @@ -104,7 +104,7 @@ export function dataSanitizeMessage(logger: IDiagnosticLogger, message: any) {
if (message) {
if (message.length > DataSanitizerValues.MAX_MESSAGE_LENGTH) {
messageTrunc = message.substring(0, DataSanitizerValues.MAX_MESSAGE_LENGTH);
logger.throwInternal(
logger && logger.throwInternal(
LoggingSeverity.WARNING, _InternalMessageId.MessageTruncated,
"message is too long, it has been truncated to " + DataSanitizerValues.MAX_MESSAGE_LENGTH + " characters.",
{ message },
Expand All @@ -122,7 +122,7 @@ export function dataSanitizeException(logger: IDiagnosticLogger, exception: any)
let value:string = "" + exception;
if (value.length > DataSanitizerValues.MAX_EXCEPTION_LENGTH) {
exceptionTrunc = value.substring(0, DataSanitizerValues.MAX_EXCEPTION_LENGTH);
logger.throwInternal(
logger && logger.throwInternal(
LoggingSeverity.WARNING, _InternalMessageId.ExceptionTruncated, "exception is too long, it has been truncated to " + DataSanitizerValues.MAX_EXCEPTION_LENGTH + " characters.",
{ exception }, true);
}
Expand All @@ -140,7 +140,7 @@ export function dataSanitizeProperties(logger: IDiagnosticLogger, properties: an
try {
value = getJSON().stringify(value);
} catch (e) {
logger.throwInternal(LoggingSeverity.WARNING, _InternalMessageId.CannotSerializeObjectNonSerializable, "custom property is not valid", { exception: e}, true);
logger && logger.throwInternal(LoggingSeverity.WARNING, _InternalMessageId.CannotSerializeObjectNonSerializable, "custom property is not valid", { exception: e}, true);
}
}
value = dataSanitizeString(logger, value, DataSanitizerValues.MAX_PROPERTY_LENGTH);
Expand Down Expand Up @@ -177,7 +177,7 @@ export function dataSanitizeInput(logger: IDiagnosticLogger, input: any, maxLeng
input = strTrim(input);
if (input.length > maxLength) {
inputTrunc = input.substring(0, maxLength);
logger.throwInternal(
logger && logger.throwInternal(
LoggingSeverity.WARNING,
_msgId,
"input is too long, it has been truncated to " + maxLength + " characters.",
Expand Down