@microsoft/applicationinsights-dependencies-js 2.8.4-nightly.2205-09 → 2.8.5-nightly.2206-02

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/applicationinsights-dependencies-js",
3
- "version": "2.8.4-nightly.2205-09",
3
+ "version": "2.8.5-nightly.2206-02",
4
4
  "description": "Microsoft Application Insights XHR dependencies plugin",
5
5
  "homepage": "https://github.com/microsoft/ApplicationInsights-JS#readme",
6
6
  "author": "Microsoft Application Insights Team",
@@ -50,8 +50,8 @@
50
50
  "dependencies": {
51
51
  "@microsoft/dynamicproto-js": "^1.1.6",
52
52
  "@microsoft/applicationinsights-shims": "2.0.1",
53
- "@microsoft/applicationinsights-core-js": "2.8.4-nightly.2205-09",
54
- "@microsoft/applicationinsights-common": "2.8.4-nightly.2205-09"
53
+ "@microsoft/applicationinsights-core-js": "2.8.5-nightly.2206-02",
54
+ "@microsoft/applicationinsights-common": "2.8.5-nightly.2206-02"
55
55
  },
56
56
  "license": "MIT",
57
57
  "publishConfig": {
@@ -0,0 +1,65 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved.
2
+ // Licensed under the MIT License.
3
+
4
+ import { IAppInsightsCore } from "@microsoft/applicationinsights-core-js";
5
+
6
+ export interface IDependencyListenerDetails {
7
+ /**
8
+ * The current core instance
9
+ */
10
+ core: IAppInsightsCore;
11
+
12
+ /**
13
+ * Provided only if the dependency request is an XHR call
14
+ */
15
+ xhr?: XMLHttpRequest;
16
+
17
+ /**
18
+ * Provided only if the dependency request is a fetch call, this is the input argument being used,
19
+ * re-assigning this value has not affect on the value used for the request, however, when this is a Request
20
+ * object changing the value of the Request will be used for the outbound request.
21
+ */
22
+ input?: Request | string;
23
+
24
+ /**
25
+ * Provided only if the dependency request is a fetch call, this is the init argument being used,
26
+ * re-assigning this value does not change the value used for the request, however, changing properties
27
+ * of this object will be used.
28
+ */
29
+ init?: RequestInit;
30
+
31
+ /**
32
+ * Returns the unique identifier for a trace. All requests / spans from the same trace share the same traceId.
33
+ * Must be read from incoming headers or generated according to the W3C TraceContext specification,
34
+ * in a hex representation of 16-byte array. A.k.a. trace-id, TraceID or Distributed TraceID
35
+ */
36
+ traceId?: string;
37
+
38
+ /**
39
+ * Self-generated 8-bytes identifier of the incoming request. Must be a hex representation of 8-byte array.
40
+ * Also know as the parentId, used to link requests together
41
+ */
42
+ spanId?: string;
43
+
44
+ /**
45
+ * An integer representation of the W3C TraceContext trace-flags.
46
+ * https://www.w3.org/TR/trace-context/#trace-flags
47
+ */
48
+ traceFlags?: number;
49
+ }
50
+
51
+ export declare type DependencyListenerFunction = (dependencyDetails: IDependencyListenerDetails) => void;
52
+
53
+ export interface IDependencyListenerHandler {
54
+ remove(): void;
55
+ }
56
+
57
+ export interface IDependencyListenerContainer {
58
+ /**
59
+ * Add an ajax listener which is called just prior to the request being sent and before the correlation headers are added, to allow you
60
+ * to access the headers and modify the values used to generate the distributed tracing correlation headers. (added in v2.8.4)
61
+ * @param dependencyListener - The Telemetry Initializer function
62
+ * @returns - A IDependencyListenerHandler to enable the initializer to be removed
63
+ */
64
+ addDependencyListener(dependencyListener: DependencyListenerFunction): IDependencyListenerHandler;
65
+ }
package/src/ajax.ts CHANGED
@@ -5,17 +5,18 @@ import {
5
5
  RequestHeaders, CorrelationIdHelper, createTelemetryItem, ICorrelationConfig,
6
6
  RemoteDependencyData, dateTimeUtilsNow, DisabledPropertyName, IDependencyTelemetry,
7
7
  IConfig, ITelemetryContext, PropertiesPluginIdentifier, eDistributedTracingModes, IRequestContext, isInternalApplicationInsightsEndpoint,
8
- eRequestHeaders, formatTraceParent, createTraceParent
8
+ eRequestHeaders, formatTraceParent, createTraceParent, createDistributedTraceContextFromTrace
9
9
  } from "@microsoft/applicationinsights-common";
10
10
  import {
11
11
  isNullOrUndefined, arrForEach, isString, strTrim, isFunction, eLoggingSeverity, _eInternalMessageId,
12
12
  IAppInsightsCore, BaseTelemetryPlugin, ITelemetryPluginChain, IConfiguration, IPlugin, ITelemetryItem, IProcessTelemetryContext,
13
13
  getLocation, getGlobal, strPrototype, IInstrumentCallDetails, InstrumentFunc, InstrumentProto, getPerformance,
14
14
  IInstrumentHooksCallbacks, objForEachKey, generateW3CId, getIEVersion, dumpObj, ICustomProperties, isXhrSupported, eventOn,
15
- mergeEvtNamespace, createUniqueNamespace, createProcessTelemetryContext, _throwInternal
15
+ mergeEvtNamespace, createUniqueNamespace, createProcessTelemetryContext, _throwInternal, IDistributedTraceContext, getExceptionName
16
16
  } from "@microsoft/applicationinsights-core-js";
17
17
  import { ajaxRecord, IAjaxRecordResponse } from "./ajaxRecord";
18
18
  import dynamicProto from "@microsoft/dynamicproto-js";
19
+ import { DependencyListenerFunction, IDependencyListenerContainer, IDependencyListenerDetails, IDependencyListenerHandler } from "./DependencyListener";
19
20
 
20
21
  const AJAX_MONITOR_PREFIX = "ai.ajxmn.";
21
22
  const strDiagLog = "diagLog";
@@ -26,6 +27,11 @@ const strTrackDependencyDataInternal = "trackDependencyDataInternal"; // Using s
26
27
  // Using a global value so that to handle same iKey with multiple app insights instances (mostly for testing)
27
28
  let _markCount: number = 0;
28
29
 
30
+ interface _IInternalDependencyListenerHandler {
31
+ id: number;
32
+ fn: DependencyListenerFunction;
33
+ }
34
+
29
35
  /** @Ignore */
30
36
  function _supportsFetch(): (input: RequestInfo, init?: RequestInit) => Promise<Response> {
31
37
  let _global = getGlobal();
@@ -132,11 +138,47 @@ function _indexOf(value:string, match:string):number {
132
138
  return -1;
133
139
  }
134
140
 
141
+ function _processDependencyListeners(listeners: _IInternalDependencyListenerHandler[], core: IAppInsightsCore, ajaxData: ajaxRecord, xhr: XMLHttpRequest, input?: Request | string, init?: RequestInit): void {
142
+ var initializersCount = listeners.length;
143
+ if (initializersCount > 0) {
144
+ let details: IDependencyListenerDetails = {
145
+ core: core,
146
+ xhr: xhr,
147
+ input: input,
148
+ init: init,
149
+ traceId: ajaxData.traceID,
150
+ spanId: ajaxData.spanID,
151
+ traceFlags: ajaxData.traceFlags
152
+ };
153
+
154
+ for (var i = 0; i < initializersCount; ++i) {
155
+ var dependencyListener = listeners[i];
156
+ if (dependencyListener && dependencyListener.fn) {
157
+ try {
158
+ dependencyListener.fn.call(null, details);
159
+ } catch (e) {
160
+ let core = details.core;
161
+ _throwInternal(
162
+ core && core.logger,
163
+ eLoggingSeverity.CRITICAL,
164
+ _eInternalMessageId.TelemetryInitializerFailed,
165
+ "Dependency listener [#" + i + "] failed: " + getExceptionName(e),
166
+ { exception: dumpObj(e) }, true);
167
+ }
168
+ }
169
+ }
170
+
171
+ ajaxData.traceID = details.traceId;
172
+ ajaxData.spanID = details.spanId;
173
+ ajaxData.traceFlags = details.traceFlags;
174
+ }
175
+ }
176
+
135
177
  export interface XMLHttpRequestInstrumented extends XMLHttpRequest {
136
178
  ajaxData: ajaxRecord;
137
179
  }
138
180
 
139
- export interface IDependenciesPlugin {
181
+ export interface IDependenciesPlugin extends IDependencyListenerContainer {
140
182
  /**
141
183
  * Logs dependency call
142
184
  * @param dependencyData dependency data object
@@ -219,6 +261,8 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
219
261
  let _excludeRequestFromAutoTrackingPatterns: string[] | RegExp[];
220
262
  let _addRequestContext: (requestContext?: IRequestContext) => ICustomProperties;
221
263
  let _evtNamespace: string | string[];
264
+ let _dependencyListenerId: number;
265
+ let _dependencyListeners: _IInternalDependencyListenerHandler[];
222
266
 
223
267
  dynamicProto(AjaxMonitor, this, (_self, _base) => {
224
268
  let _addHook = _base._addHook;
@@ -250,6 +294,9 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
250
294
  _self.includeCorrelationHeaders = (ajaxData: ajaxRecord, input?: Request | string, init?: RequestInit, xhr?: XMLHttpRequestInstrumented): any => {
251
295
  // Test Hook to allow the overriding of the location host
252
296
  let currentWindowHost = _self["_currentWindowHost"] || _currentWindowHost;
297
+
298
+ _processDependencyListeners(_dependencyListeners, _self.core, ajaxData, xhr, input, init);
299
+
253
300
  if (input) { // Fetch
254
301
  if (CorrelationIdHelper.canIncludeCorrelationHeader(_config, ajaxData.getAbsoluteUrl(), currentWindowHost)) {
255
302
  if (!init) {
@@ -274,7 +321,12 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
274
321
  }
275
322
  }
276
323
  if (_isUsingW3CHeaders) {
277
- const traceParent = formatTraceParent(createTraceParent(ajaxData.traceID, ajaxData.spanID, 0x01));
324
+ let traceFlags = ajaxData.traceFlags;
325
+ if (isNullOrUndefined(traceFlags)) {
326
+ traceFlags = 0x01;
327
+ }
328
+
329
+ const traceParent = formatTraceParent(createTraceParent(ajaxData.traceID, ajaxData.spanID, traceFlags));
278
330
  init.headers.set(RequestHeaders[eRequestHeaders.traceParentHeader], traceParent);
279
331
  if (_enableRequestHeaderTracking) {
280
332
  ajaxData.requestHeaders[RequestHeaders[eRequestHeaders.traceParentHeader]] = traceParent;
@@ -300,7 +352,12 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
300
352
  }
301
353
  }
302
354
  if (_isUsingW3CHeaders) {
303
- const traceParent = formatTraceParent(createTraceParent(ajaxData.traceID, ajaxData.spanID, 0x01));
355
+ let traceFlags = ajaxData.traceFlags;
356
+ if (isNullOrUndefined(traceFlags)) {
357
+ traceFlags = 0x01;
358
+ }
359
+
360
+ const traceParent = formatTraceParent(createTraceParent(ajaxData.traceID, ajaxData.spanID, traceFlags));
304
361
  xhr.setRequestHeader(RequestHeaders[eRequestHeaders.traceParentHeader], traceParent);
305
362
  if (_enableRequestHeaderTracking) {
306
363
  ajaxData.requestHeaders[RequestHeaders[eRequestHeaders.traceParentHeader]] = traceParent;
@@ -347,6 +404,28 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
347
404
  ++_trackAjaxAttempts;
348
405
  }
349
406
 
407
+ _self.addDependencyListener = (dependencyListener: DependencyListenerFunction): IDependencyListenerHandler => {
408
+ let theInitializer = {
409
+ id: _dependencyListenerId++,
410
+ fn: dependencyListener
411
+ };
412
+
413
+ _dependencyListeners.push(theInitializer);
414
+
415
+ let handler: IDependencyListenerHandler = {
416
+ remove: () => {
417
+ arrForEach(_dependencyListeners, (initializer, idx) => {
418
+ if (initializer.id === theInitializer.id) {
419
+ _dependencyListeners.splice(idx, 1);
420
+ return -1;
421
+ }
422
+ });
423
+ }
424
+ }
425
+
426
+ return handler;
427
+ };
428
+
350
429
  function _initDefaults() {
351
430
  let location = getLocation();
352
431
  _fetchInitialized = false; // fetch monitoring initialized
@@ -367,9 +446,11 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
367
446
  _disableAjaxTracking = false;
368
447
  _disableFetchTracking = false;
369
448
 
370
- _excludeRequestFromAutoTrackingPatterns = null
449
+ _excludeRequestFromAutoTrackingPatterns = null;
371
450
  _addRequestContext = null;
372
451
  _evtNamespace = null;
452
+ _dependencyListenerId = 0;
453
+ _dependencyListeners = [];
373
454
  }
374
455
 
375
456
  function _populateDefaults(config: IConfiguration) {
@@ -681,11 +762,28 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
681
762
  && ajaxValidation;
682
763
  }
683
764
 
765
+ function _getDistributedTraceCtx(): IDistributedTraceContext {
766
+ let distributedTraceCtx: IDistributedTraceContext = null;
767
+ if (_self.core && _self.core.getTraceCtx) {
768
+ distributedTraceCtx = _self.core.getTraceCtx(false);
769
+ }
770
+
771
+ // Fall back
772
+ if (!distributedTraceCtx && _context && _context.telemetryTrace) {
773
+ distributedTraceCtx = createDistributedTraceContextFromTrace(_context.telemetryTrace);
774
+ }
775
+
776
+ return distributedTraceCtx;
777
+ }
778
+
684
779
  function _openHandler(xhr: XMLHttpRequestInstrumented, method: string, url: string, async: boolean) {
685
- const traceID = (_context && _context.telemetryTrace && _context.telemetryTrace.traceID) || generateW3CId();
780
+ let distributedTraceCtx: IDistributedTraceContext = _getDistributedTraceCtx();
781
+
782
+ const traceID = (distributedTraceCtx && distributedTraceCtx.getTraceId()) || generateW3CId();
686
783
  const spanID = generateW3CId().substr(0, 16);
687
784
 
688
785
  const ajaxData = new ajaxRecord(traceID, spanID, _self[strDiagLog]());
786
+ ajaxData.traceFlags = distributedTraceCtx && distributedTraceCtx.getTraceFlags();
689
787
  ajaxData.method = method;
690
788
  ajaxData.requestUrl = url;
691
789
  ajaxData.xhrMonitoringState.openDone = true;
@@ -921,10 +1019,13 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
921
1019
  }
922
1020
 
923
1021
  function _createFetchRecord(input?: Request | string, init?: RequestInit): ajaxRecord {
924
- const traceID = (_context && _context.telemetryTrace && _context.telemetryTrace.traceID) || generateW3CId();
1022
+ let distributedTraceCtx: IDistributedTraceContext = _getDistributedTraceCtx();
1023
+
1024
+ const traceID = (distributedTraceCtx && distributedTraceCtx.getTraceId()) || generateW3CId();
925
1025
  const spanID = generateW3CId().substr(0, 16);
926
1026
 
927
- const ajaxData = new ajaxRecord(traceID, spanID, _self[strDiagLog]());
1027
+ let ajaxData = new ajaxRecord(traceID, spanID, _self[strDiagLog]());
1028
+ ajaxData.traceFlags = distributedTraceCtx && distributedTraceCtx.getTraceFlags();
928
1029
  ajaxData.requestSentTime = dateTimeUtilsNow();
929
1030
  ajaxData.errorStatusText = _enableAjaxErrorStatusText;
930
1031
 
@@ -1070,6 +1171,17 @@ export class AjaxMonitor extends BaseTelemetryPlugin implements IDependenciesPlu
1070
1171
  // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1071
1172
  }
1072
1173
 
1174
+ /**
1175
+ * Add an ajax listener which is called just prior to the request being sent and before the correlation headers are added, to allow you
1176
+ * to access the headers and modify the values used to generate the distributed tracing correlation headers.
1177
+ * @param dependencyListener - The Telemetry Initializer function
1178
+ * @returns - A IDependencyListenerHandler to enable the initializer to be removed
1179
+ */
1180
+ public addDependencyListener(dependencyListener: DependencyListenerFunction): IDependencyListenerHandler {
1181
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1182
+ return null;
1183
+ }
1184
+
1073
1185
  /**
1074
1186
  * Protected function to allow sub classes the chance to add additional properties to the dependency event
1075
1187
  * before it's sent. This function calls track, so sub-classes must call this function after they have
package/src/ajaxRecord.ts CHANGED
@@ -237,6 +237,7 @@ export class ajaxRecord {
237
237
 
238
238
  public traceID: string;
239
239
  public spanID: string;
240
+ public traceFlags?: number;
240
241
 
241
242
  constructor(traceID: string, spanID: string, logger: IDiagnosticLogger) {
242
243
  let self = this;
@@ -0,0 +1,52 @@
1
+ import { IAppInsightsCore } from "@microsoft/applicationinsights-core-js";
2
+ export interface IDependencyListenerDetails {
3
+ /**
4
+ * The current core instance
5
+ */
6
+ core: IAppInsightsCore;
7
+ /**
8
+ * Provided only if the dependency request is an XHR call
9
+ */
10
+ xhr?: XMLHttpRequest;
11
+ /**
12
+ * Provided only if the dependency request is a fetch call, this is the input argument being used,
13
+ * re-assigning this value has not affect on the value used for the request, however, when this is a Request
14
+ * object changing the value of the Request will be used for the outbound request.
15
+ */
16
+ input?: Request | string;
17
+ /**
18
+ * Provided only if the dependency request is a fetch call, this is the init argument being used,
19
+ * re-assigning this value does not change the value used for the request, however, changing properties
20
+ * of this object will be used.
21
+ */
22
+ init?: RequestInit;
23
+ /**
24
+ * Returns the unique identifier for a trace. All requests / spans from the same trace share the same traceId.
25
+ * Must be read from incoming headers or generated according to the W3C TraceContext specification,
26
+ * in a hex representation of 16-byte array. A.k.a. trace-id, TraceID or Distributed TraceID
27
+ */
28
+ traceId?: string;
29
+ /**
30
+ * Self-generated 8-bytes identifier of the incoming request. Must be a hex representation of 8-byte array.
31
+ * Also know as the parentId, used to link requests together
32
+ */
33
+ spanId?: string;
34
+ /**
35
+ * An integer representation of the W3C TraceContext trace-flags.
36
+ * https://www.w3.org/TR/trace-context/#trace-flags
37
+ */
38
+ traceFlags?: number;
39
+ }
40
+ export declare type DependencyListenerFunction = (dependencyDetails: IDependencyListenerDetails) => void;
41
+ export interface IDependencyListenerHandler {
42
+ remove(): void;
43
+ }
44
+ export interface IDependencyListenerContainer {
45
+ /**
46
+ * Add an ajax listener which is called just prior to the request being sent and before the correlation headers are added, to allow you
47
+ * to access the headers and modify the values used to generate the distributed tracing correlation headers. (added in v2.8.4)
48
+ * @param dependencyListener - The Telemetry Initializer function
49
+ * @returns - A IDependencyListenerHandler to enable the initializer to be removed
50
+ */
51
+ addDependencyListener(dependencyListener: DependencyListenerFunction): IDependencyListenerHandler;
52
+ }
package/types/ajax.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { ICorrelationConfig, IDependencyTelemetry, IConfig } from "@microsoft/applicationinsights-common";
2
2
  import { IAppInsightsCore, BaseTelemetryPlugin, ITelemetryPluginChain, IConfiguration, IPlugin, ITelemetryItem, IProcessTelemetryContext } from "@microsoft/applicationinsights-core-js";
3
3
  import { ajaxRecord } from "./ajaxRecord";
4
+ import { DependencyListenerFunction, IDependencyListenerContainer, IDependencyListenerHandler } from "./DependencyListener";
4
5
  export interface XMLHttpRequestInstrumented extends XMLHttpRequest {
5
6
  ajaxData: ajaxRecord;
6
7
  }
7
- export interface IDependenciesPlugin {
8
+ export interface IDependenciesPlugin extends IDependencyListenerContainer {
8
9
  /**
9
10
  * Logs dependency call
10
11
  * @param dependencyData dependency data object
@@ -31,6 +32,13 @@ export declare class AjaxMonitor extends BaseTelemetryPlugin implements IDepende
31
32
  [key: string]: any;
32
33
  }): void;
33
34
  includeCorrelationHeaders(ajaxData: ajaxRecord, input?: Request | string, init?: RequestInit, xhr?: XMLHttpRequestInstrumented): any;
35
+ /**
36
+ * Add an ajax listener which is called just prior to the request being sent and before the correlation headers are added, to allow you
37
+ * to access the headers and modify the values used to generate the distributed tracing correlation headers.
38
+ * @param dependencyListener - The Telemetry Initializer function
39
+ * @returns - A IDependencyListenerHandler to enable the initializer to be removed
40
+ */
41
+ addDependencyListener(dependencyListener: DependencyListenerFunction): IDependencyListenerHandler;
34
42
  /**
35
43
  * Protected function to allow sub classes the chance to add additional properties to the dependency event
36
44
  * before it's sent. This function calls track, so sub-classes must call this function after they have
@@ -43,6 +43,7 @@ export declare class ajaxRecord {
43
43
  clientFailure: number;
44
44
  traceID: string;
45
45
  spanID: string;
46
+ traceFlags?: number;
46
47
  constructor(traceID: string, spanID: string, logger: IDiagnosticLogger);
47
48
  getAbsoluteUrl(): string;
48
49
  getPathName(): string;
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.24.0"
8
+ "packageVersion": "7.24.2"
9
9
  }
10
10
  ]
11
11
  }