@microsoft/applicationinsights-core-js 3.0.0-beta.2210-01 → 3.0.0-beta.2210-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.
Files changed (178) hide show
  1. package/browser/applicationinsights-core-js.integrity.json +9 -9
  2. package/browser/applicationinsights-core-js.js +1249 -675
  3. package/browser/applicationinsights-core-js.js.map +1 -1
  4. package/browser/applicationinsights-core-js.min.js +2 -2
  5. package/browser/applicationinsights-core-js.min.js.map +1 -1
  6. package/dist/applicationinsights-core-js.api.json +3668 -1712
  7. package/dist/applicationinsights-core-js.api.md +131 -54
  8. package/dist/applicationinsights-core-js.d.ts +332 -131
  9. package/dist/applicationinsights-core-js.js +1249 -675
  10. package/dist/applicationinsights-core-js.js.map +1 -1
  11. package/dist/applicationinsights-core-js.min.js +2 -2
  12. package/dist/applicationinsights-core-js.min.js.map +1 -1
  13. package/dist/applicationinsights-core-js.rollup.d.ts +332 -131
  14. package/dist-esm/Config/ConfigDefaults.js +114 -0
  15. package/dist-esm/Config/ConfigDefaults.js.map +1 -0
  16. package/dist-esm/Config/DynamicConfig.js +129 -0
  17. package/dist-esm/Config/DynamicConfig.js.map +1 -0
  18. package/dist-esm/Config/DynamicProperty.js +139 -0
  19. package/dist-esm/Config/DynamicProperty.js.map +1 -0
  20. package/dist-esm/Config/DynamicState.js +109 -0
  21. package/dist-esm/Config/DynamicState.js.map +1 -0
  22. package/dist-esm/Config/DynamicSupport.js +57 -0
  23. package/dist-esm/Config/DynamicSupport.js.map +1 -0
  24. package/dist-esm/Config/IConfigDefaults.js +8 -0
  25. package/dist-esm/Config/IConfigDefaults.js.map +1 -0
  26. package/dist-esm/Config/IDynamicConfigHandler.js +8 -0
  27. package/dist-esm/Config/IDynamicConfigHandler.js.map +1 -0
  28. package/dist-esm/Config/IDynamicPropertyHandler.js +8 -0
  29. package/dist-esm/Config/IDynamicPropertyHandler.js.map +1 -0
  30. package/dist-esm/Config/IDynamicWatcher.js +8 -0
  31. package/dist-esm/Config/IDynamicWatcher.js.map +1 -0
  32. package/dist-esm/Config/_IDynamicConfigHandlerState.js +6 -0
  33. package/dist-esm/Config/_IDynamicConfigHandlerState.js.map +1 -0
  34. package/dist-esm/JavaScriptSDK/AppInsightsCore.js +808 -23
  35. package/dist-esm/JavaScriptSDK/AppInsightsCore.js.map +1 -1
  36. package/dist-esm/JavaScriptSDK/BaseTelemetryPlugin.js +22 -18
  37. package/dist-esm/JavaScriptSDK/BaseTelemetryPlugin.js.map +1 -1
  38. package/dist-esm/JavaScriptSDK/ChannelController.js +1 -1
  39. package/dist-esm/JavaScriptSDK/CookieMgr.js +78 -38
  40. package/dist-esm/JavaScriptSDK/CookieMgr.js.map +1 -1
  41. package/dist-esm/JavaScriptSDK/CoreUtils.js +6 -5
  42. package/dist-esm/JavaScriptSDK/CoreUtils.js.map +1 -1
  43. package/dist-esm/JavaScriptSDK/DataCacheHelper.js +10 -8
  44. package/dist-esm/JavaScriptSDK/DataCacheHelper.js.map +1 -1
  45. package/dist-esm/JavaScriptSDK/DbgExtensionUtils.js +1 -1
  46. package/dist-esm/JavaScriptSDK/DiagnosticLogger.js +40 -23
  47. package/dist-esm/JavaScriptSDK/DiagnosticLogger.js.map +1 -1
  48. package/dist-esm/JavaScriptSDK/EnvUtils.js +1 -115
  49. package/dist-esm/JavaScriptSDK/EnvUtils.js.map +1 -1
  50. package/dist-esm/JavaScriptSDK/EventHelpers.js +30 -29
  51. package/dist-esm/JavaScriptSDK/EventHelpers.js.map +1 -1
  52. package/dist-esm/JavaScriptSDK/HelperFuncs.js +19 -34
  53. package/dist-esm/JavaScriptSDK/HelperFuncs.js.map +1 -1
  54. package/dist-esm/JavaScriptSDK/InstrumentHooks.js +1 -1
  55. package/dist-esm/JavaScriptSDK/InternalConstants.js +5 -1
  56. package/dist-esm/JavaScriptSDK/InternalConstants.js.map +1 -1
  57. package/dist-esm/JavaScriptSDK/NotificationManager.js +18 -11
  58. package/dist-esm/JavaScriptSDK/NotificationManager.js.map +1 -1
  59. package/dist-esm/JavaScriptSDK/PerfManager.js +2 -3
  60. package/dist-esm/JavaScriptSDK/PerfManager.js.map +1 -1
  61. package/dist-esm/JavaScriptSDK/ProcessTelemetryContext.js +62 -53
  62. package/dist-esm/JavaScriptSDK/ProcessTelemetryContext.js.map +1 -1
  63. package/dist-esm/JavaScriptSDK/RandomHelper.js +1 -1
  64. package/dist-esm/JavaScriptSDK/TelemetryHelpers.js +8 -10
  65. package/dist-esm/JavaScriptSDK/TelemetryHelpers.js.map +1 -1
  66. package/dist-esm/JavaScriptSDK/TelemetryInitializerPlugin.js +3 -4
  67. package/dist-esm/JavaScriptSDK/TelemetryInitializerPlugin.js.map +1 -1
  68. package/dist-esm/JavaScriptSDK/UnloadHandlerContainer.js +1 -1
  69. package/dist-esm/JavaScriptSDK/W3cTraceParent.js +12 -10
  70. package/dist-esm/JavaScriptSDK/W3cTraceParent.js.map +1 -1
  71. package/dist-esm/JavaScriptSDK.Enums/EnumHelperFuncs.js +1 -2
  72. package/dist-esm/JavaScriptSDK.Enums/EnumHelperFuncs.js.map +1 -1
  73. package/dist-esm/JavaScriptSDK.Enums/EventsDiscardedReason.js +1 -1
  74. package/dist-esm/JavaScriptSDK.Enums/LoggingEnums.js +2 -107
  75. package/dist-esm/JavaScriptSDK.Enums/LoggingEnums.js.map +1 -1
  76. package/dist-esm/JavaScriptSDK.Enums/SendRequestReason.js +1 -1
  77. package/dist-esm/JavaScriptSDK.Enums/TelemetryUnloadReason.js +1 -1
  78. package/dist-esm/JavaScriptSDK.Enums/TelemetryUpdateReason.js +1 -1
  79. package/dist-esm/JavaScriptSDK.Interfaces/IAppInsightsCore.js +1 -1
  80. package/dist-esm/JavaScriptSDK.Interfaces/IChannelControls.js +1 -1
  81. package/dist-esm/JavaScriptSDK.Interfaces/IConfiguration.js +1 -1
  82. package/dist-esm/JavaScriptSDK.Interfaces/ICookieMgr.js +1 -1
  83. package/dist-esm/JavaScriptSDK.Interfaces/IDbgExtension.js +1 -1
  84. package/dist-esm/JavaScriptSDK.Interfaces/IDiagnosticLogger.js +1 -1
  85. package/dist-esm/JavaScriptSDK.Interfaces/IDistributedTraceContext.js +1 -1
  86. package/dist-esm/JavaScriptSDK.Interfaces/IInstrumentHooks.js +1 -1
  87. package/dist-esm/JavaScriptSDK.Interfaces/INotificationListener.js +1 -1
  88. package/dist-esm/JavaScriptSDK.Interfaces/INotificationManager.js +1 -1
  89. package/dist-esm/JavaScriptSDK.Interfaces/IPerfEvent.js +1 -1
  90. package/dist-esm/JavaScriptSDK.Interfaces/IPerfManager.js +1 -1
  91. package/dist-esm/JavaScriptSDK.Interfaces/IProcessTelemetryContext.js +1 -1
  92. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryInitializers.js +1 -1
  93. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryItem.js +1 -1
  94. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryPlugin.js +1 -1
  95. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryPluginChain.js +1 -1
  96. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryUnloadState.js +1 -1
  97. package/dist-esm/JavaScriptSDK.Interfaces/ITelemetryUpdateState.js +1 -1
  98. package/dist-esm/JavaScriptSDK.Interfaces/ITraceParent.js +1 -1
  99. package/dist-esm/JavaScriptSDK.Interfaces/IUnloadHook.js +8 -0
  100. package/dist-esm/JavaScriptSDK.Interfaces/IUnloadHook.js.map +1 -0
  101. package/dist-esm/JavaScriptSDK.Interfaces/IUnloadableComponent.js +3 -1
  102. package/dist-esm/JavaScriptSDK.Interfaces/IUnloadableComponent.js.map +1 -1
  103. package/dist-esm/__DynamicConstants.js +26 -23
  104. package/dist-esm/__DynamicConstants.js.map +1 -1
  105. package/dist-esm/applicationinsights-core-js.js +6 -4
  106. package/dist-esm/applicationinsights-core-js.js.map +1 -1
  107. package/package.json +2 -2
  108. package/src/JavaScriptSDK/AppInsightsCore.ts +1156 -16
  109. package/src/JavaScriptSDK/BaseTelemetryPlugin.ts +25 -17
  110. package/src/JavaScriptSDK/CookieMgr.ts +88 -41
  111. package/src/JavaScriptSDK/CoreUtils.ts +4 -3
  112. package/src/JavaScriptSDK/DiagnosticLogger.ts +51 -29
  113. package/src/JavaScriptSDK/EnvUtils.ts +0 -133
  114. package/src/JavaScriptSDK/EventHelpers.ts +29 -28
  115. package/src/JavaScriptSDK/HelperFuncs.ts +22 -39
  116. package/src/JavaScriptSDK/InternalConstants.ts +5 -0
  117. package/src/JavaScriptSDK/NotificationManager.ts +25 -14
  118. package/src/JavaScriptSDK/PerfManager.ts +2 -2
  119. package/src/JavaScriptSDK/ProcessTelemetryContext.ts +73 -56
  120. package/src/JavaScriptSDK/TelemetryHelpers.ts +8 -9
  121. package/src/JavaScriptSDK/TelemetryInitializerPlugin.ts +2 -2
  122. package/src/JavaScriptSDK/W3cTraceParent.ts +7 -6
  123. package/src/JavaScriptSDK.Enums/EnumHelperFuncs.ts +0 -1
  124. package/src/JavaScriptSDK.Enums/LoggingEnums.ts +9 -108
  125. package/src/JavaScriptSDK.Enums/TelemetryUpdateReason.ts +1 -1
  126. package/src/JavaScriptSDK.Interfaces/IAppInsightsCore.ts +28 -3
  127. package/src/JavaScriptSDK.Interfaces/ICookieMgr.ts +8 -0
  128. package/src/JavaScriptSDK.Interfaces/IDiagnosticLogger.ts +15 -8
  129. package/src/JavaScriptSDK.Interfaces/IInstrumentHooks.ts +3 -1
  130. package/src/JavaScriptSDK.Interfaces/INotificationListener.ts +5 -5
  131. package/src/JavaScriptSDK.Interfaces/INotificationManager.ts +8 -8
  132. package/src/JavaScriptSDK.Interfaces/IPerfManager.ts +3 -3
  133. package/src/JavaScriptSDK.Interfaces/IProcessTelemetryContext.ts +10 -9
  134. package/src/JavaScriptSDK.Interfaces/ITelemetryInitializers.ts +2 -1
  135. package/src/JavaScriptSDK.Interfaces/ITelemetryUpdateState.ts +15 -5
  136. package/src/JavaScriptSDK.Interfaces/IUnloadHook.ts +22 -0
  137. package/src/JavaScriptSDK.Interfaces/IUnloadableComponent.ts +3 -3
  138. package/tsconfig.json +3 -2
  139. package/types/Config/ConfigDefaults.d.ts +10 -0
  140. package/types/Config/DynamicConfig.d.ts +23 -0
  141. package/types/Config/DynamicProperty.d.ts +3 -0
  142. package/types/Config/DynamicState.d.ts +3 -0
  143. package/types/Config/DynamicSupport.d.ts +15 -0
  144. package/types/Config/IConfigDefaults.d.ts +42 -0
  145. package/types/Config/IDynamicConfigHandler.d.ts +46 -0
  146. package/types/Config/IDynamicPropertyHandler.d.ts +11 -0
  147. package/types/Config/IDynamicWatcher.d.ts +28 -0
  148. package/types/Config/_IDynamicConfigHandlerState.d.ts +35 -0
  149. package/types/JavaScriptSDK/AppInsightsCore.d.ts +136 -4
  150. package/types/JavaScriptSDK/BaseTelemetryPlugin.d.ts +2 -2
  151. package/types/JavaScriptSDK/CookieMgr.d.ts +0 -10
  152. package/types/JavaScriptSDK/DiagnosticLogger.d.ts +18 -16
  153. package/types/JavaScriptSDK/EventHelpers.d.ts +24 -24
  154. package/types/JavaScriptSDK/HelperFuncs.d.ts +13 -11
  155. package/types/JavaScriptSDK/InternalConstants.d.ts +4 -0
  156. package/types/JavaScriptSDK/NotificationManager.d.ts +7 -7
  157. package/types/JavaScriptSDK/PerfManager.d.ts +2 -2
  158. package/types/JavaScriptSDK/ProcessTelemetryContext.d.ts +3 -2
  159. package/types/JavaScriptSDK/TelemetryHelpers.d.ts +3 -3
  160. package/types/JavaScriptSDK.Enums/LoggingEnums.d.ts +7 -5
  161. package/types/JavaScriptSDK.Enums/TelemetryUpdateReason.d.ts +1 -0
  162. package/types/JavaScriptSDK.Interfaces/IAppInsightsCore.d.ts +25 -3
  163. package/types/JavaScriptSDK.Interfaces/ICookieMgr.d.ts +6 -0
  164. package/types/JavaScriptSDK.Interfaces/IDiagnosticLogger.d.ts +14 -8
  165. package/types/JavaScriptSDK.Interfaces/IInstrumentHooks.d.ts +2 -1
  166. package/types/JavaScriptSDK.Interfaces/INotificationListener.d.ts +5 -5
  167. package/types/JavaScriptSDK.Interfaces/INotificationManager.d.ts +8 -8
  168. package/types/JavaScriptSDK.Interfaces/IPerfManager.d.ts +3 -3
  169. package/types/JavaScriptSDK.Interfaces/IProcessTelemetryContext.d.ts +5 -9
  170. package/types/JavaScriptSDK.Interfaces/ITelemetryInitializers.d.ts +2 -1
  171. package/types/JavaScriptSDK.Interfaces/ITelemetryUpdateState.d.ts +13 -2
  172. package/types/JavaScriptSDK.Interfaces/IUnloadHook.d.ts +18 -0
  173. package/types/__DynamicConstants.d.ts +18 -15
  174. package/types/applicationinsights-core-js.d.ts +11 -4
  175. package/dist-esm/JavaScriptSDK/BaseCore.js +0 -654
  176. package/dist-esm/JavaScriptSDK/BaseCore.js.map +0 -1
  177. package/src/JavaScriptSDK/BaseCore.ts +0 -948
  178. package/types/JavaScriptSDK/BaseCore.d.ts +0 -124
@@ -1,27 +1,321 @@
1
1
  // Copyright (c) Microsoft Corporation. All rights reserved.
2
2
  // Licensed under the MIT License.
3
+ "use strict";
4
+
3
5
  import dynamicProto from "@microsoft/dynamicproto-js";
4
- import { isNullOrUndefined, throwError } from "@nevware21/ts-utils";
6
+ import {
7
+ arrAppend, arrForEach, arrIndexOf, deepExtend, dumpObj, isFunction, isNullOrUndefined, objDeepFreeze, objDefineProp, objFreeze,
8
+ objHasOwn, throwError
9
+ } from "@nevware21/ts-utils";
10
+ import { applyDefaults } from "../Config/ConfigDefaults";
11
+ import { createDynamicConfig, onConfigChange } from "../Config/DynamicConfig";
12
+ import { IConfigDefaults } from "../Config/IConfigDefaults";
13
+ import { IDynamicConfigHandler, _IInternalDynamicConfigHandler } from "../Config/IDynamicConfigHandler";
14
+ import { IWatchDetails, WatcherFunction } from "../Config/IDynamicWatcher";
5
15
  import { eEventsDiscardedReason } from "../JavaScriptSDK.Enums/EventsDiscardedReason";
6
- import { IAppInsightsCore } from "../JavaScriptSDK.Interfaces/IAppInsightsCore";
16
+ import { _eInternalMessageId, eLoggingSeverity } from "../JavaScriptSDK.Enums/LoggingEnums";
17
+ import { SendRequestReason } from "../JavaScriptSDK.Enums/SendRequestReason";
18
+ import { TelemetryUnloadReason } from "../JavaScriptSDK.Enums/TelemetryUnloadReason";
19
+ import { TelemetryUpdateReason } from "../JavaScriptSDK.Enums/TelemetryUpdateReason";
20
+ import { IAppInsightsCore, ILoadedPlugin } from "../JavaScriptSDK.Interfaces/IAppInsightsCore";
21
+ import { IChannelControls } from "../JavaScriptSDK.Interfaces/IChannelControls";
7
22
  import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
23
+ import { ICookieMgr } from "../JavaScriptSDK.Interfaces/ICookieMgr";
8
24
  import { IDiagnosticLogger } from "../JavaScriptSDK.Interfaces/IDiagnosticLogger";
25
+ import { IDistributedTraceContext } from "../JavaScriptSDK.Interfaces/IDistributedTraceContext";
26
+ import { INotificationListener } from "../JavaScriptSDK.Interfaces/INotificationListener";
9
27
  import { INotificationManager } from "../JavaScriptSDK.Interfaces/INotificationManager";
28
+ import { IPerfManager } from "../JavaScriptSDK.Interfaces/IPerfManager";
29
+ import { IProcessTelemetryContext, IProcessTelemetryUpdateContext } from "../JavaScriptSDK.Interfaces/IProcessTelemetryContext";
30
+ import { ITelemetryInitializerHandler, TelemetryInitializerFunction } from "../JavaScriptSDK.Interfaces/ITelemetryInitializers";
10
31
  import { ITelemetryItem } from "../JavaScriptSDK.Interfaces/ITelemetryItem";
11
- import { IPlugin } from "../JavaScriptSDK.Interfaces/ITelemetryPlugin";
12
- import { BaseCore } from "./BaseCore";
13
- import { DiagnosticLogger } from "./DiagnosticLogger";
32
+ import { IPlugin, ITelemetryPlugin } from "../JavaScriptSDK.Interfaces/ITelemetryPlugin";
33
+ import { ITelemetryPluginChain } from "../JavaScriptSDK.Interfaces/ITelemetryPluginChain";
34
+ import { ITelemetryUnloadState } from "../JavaScriptSDK.Interfaces/ITelemetryUnloadState";
35
+ import { ITelemetryUpdateState } from "../JavaScriptSDK.Interfaces/ITelemetryUpdateState";
36
+ import { ILegacyUnloadHook, IUnloadHook } from "../JavaScriptSDK.Interfaces/IUnloadHook";
37
+ import {
38
+ ChannelControllerPriority, IChannelController, IInternalChannelController, _IInternalChannels, createChannelControllerPlugin,
39
+ createChannelQueues
40
+ } from "./ChannelController";
41
+ import { createCookieMgr } from "./CookieMgr";
42
+ import { createUniqueNamespace } from "./DataCacheHelper";
43
+ import { getDebugListener } from "./DbgExtensionUtils";
44
+ import { DiagnosticLogger, _InternalLogMessage, _throwInternal, _warnToConsole } from "./DiagnosticLogger";
45
+ import { getSetValue, isPlainObject, objForEachKey, proxyFunctionAs, proxyFunctions, toISOString } from "./HelperFuncs";
46
+ import {
47
+ STR_CHANNELS, STR_CREATE_PERF_MGR, STR_DISABLED, STR_EXTENSIONS, STR_EXTENSION_CONFIG, UNDEFINED_VALUE
48
+ } from "./InternalConstants";
14
49
  import { NotificationManager } from "./NotificationManager";
15
- import { doPerf } from "./PerfManager";
50
+ import { PerfManager, doPerf, getGblPerfMgr } from "./PerfManager";
51
+ import {
52
+ createProcessTelemetryContext, createProcessTelemetryUnloadContext, createProcessTelemetryUpdateContext, createTelemetryProxyChain
53
+ } from "./ProcessTelemetryContext";
54
+ import { _getPluginState, createDistributedTraceContext, initializePlugins, sortPlugins } from "./TelemetryHelpers";
55
+ import { TelemetryInitializerPlugin } from "./TelemetryInitializerPlugin";
56
+ import { IUnloadHandlerContainer, UnloadHandler, createUnloadHandlerContainer } from "./UnloadHandlerContainer";
16
57
 
17
- export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
58
+ const strValidationError = "Plugins must provide initialize method";
59
+ const strNotificationManager = "_notificationManager";
60
+ const strSdkUnloadingError = "SDK is still unloading...";
61
+ const strSdkNotInitialized = "SDK is not initialized";
62
+ // const strPluginUnloadFailed = "Failed to unload plugin";
63
+
64
+ /**
65
+ * The default settings for the config.
66
+ * WE MUST include all defaults here to ensure that the config is created with all of the properties
67
+ * defined as dynamic.
68
+ */
69
+ const defaultConfig: IConfigDefaults<IConfiguration> = objDeepFreeze({
70
+ cookieCfg: {},
71
+ [STR_EXTENSIONS]: [],
72
+ [STR_CHANNELS]: [],
73
+ [STR_EXTENSION_CONFIG]: {},
74
+ [STR_CREATE_PERF_MGR]: UNDEFINED_VALUE,
75
+ loggingLevelConsole: eLoggingSeverity.DISABLED,
76
+ diagnosticLogInterval: UNDEFINED_VALUE
77
+ });
78
+
79
+ /**
80
+ * Helper to create the default performance manager
81
+ * @param core
82
+ * @param notificationMgr
83
+ */
84
+ function _createPerfManager (core: IAppInsightsCore, notificationMgr: INotificationManager) {
85
+ return new PerfManager(notificationMgr);
86
+ }
87
+
88
+ function _validateExtensions(logger: IDiagnosticLogger, channelPriority: number, allExtensions: IPlugin[]): { all: IPlugin[]; core: ITelemetryPlugin[] } {
89
+ // Concat all available extensions
90
+ let coreExtensions: ITelemetryPlugin[] = [];
91
+
92
+ // Check if any two extensions have the same priority, then warn to console
93
+ // And extract the local extensions from the
94
+ let extPriorities = {};
95
+
96
+ // Extension validation
97
+ arrForEach(allExtensions, (ext: ITelemetryPlugin) => {
98
+ // Check for ext.initialize
99
+ if (isNullOrUndefined(ext) || isNullOrUndefined(ext.initialize)) {
100
+ throwError(strValidationError);
101
+ }
102
+
103
+ const extPriority = ext.priority;
104
+ const identifier = ext.identifier;
105
+
106
+ if (ext && extPriority) {
107
+ if (!isNullOrUndefined(extPriorities[extPriority])) {
108
+ _warnToConsole(logger, "Two extensions have same priority #" + extPriority + " - " + extPriorities[extPriority] + ", " + identifier);
109
+ } else {
110
+ // set a value
111
+ extPriorities[extPriority] = identifier;
112
+ }
113
+ }
114
+
115
+ // Split extensions to core and channelController
116
+ if (!extPriority || extPriority < channelPriority) {
117
+ // Add to core extension that will be managed by AppInsightsCore
118
+ coreExtensions.push(ext);
119
+ }
120
+ });
121
+
122
+ return {
123
+ all: allExtensions,
124
+ core: coreExtensions
125
+ };
126
+ }
127
+
128
+ function _isPluginPresent(thePlugin: IPlugin, plugins: IPlugin[]) {
129
+ let exists = false;
130
+
131
+ arrForEach(plugins, (plugin) => {
132
+ if (plugin === thePlugin) {
133
+ exists = true;
134
+ return -1;
135
+ }
136
+ });
137
+
138
+ return exists;
139
+ }
140
+
141
+ function _deepMergeConfig(details: IWatchDetails<IConfiguration>, target: any, newValues: any, merge: boolean) {
142
+ // Lets assign the new values to the existing config
143
+ if (newValues) {
144
+ objForEachKey(newValues, (key, value) => {
145
+ if (merge) {
146
+ if (isPlainObject(value) && isPlainObject(target[key])) {
147
+ // The target is an object and it has a value
148
+ _deepMergeConfig(details, target[key], value, merge);
149
+ }
150
+ }
151
+
152
+ if (merge && isPlainObject(value) && isPlainObject(target[key])) {
153
+ // The target is an object and it has a value
154
+ _deepMergeConfig(details, target[key], value, merge);
155
+ } else {
156
+ // Just Assign (replace) and/or make the property dynamic
157
+ details.hdlr.set(target, key, value);
158
+ }
159
+ });
160
+ }
161
+ }
162
+
163
+ function _findWatcher(listeners: { rm: () => void, w: WatcherFunction<IConfiguration>}[], newWatcher: WatcherFunction<IConfiguration>) {
164
+ let theListener: { rm: () => void, w: WatcherFunction<IConfiguration>} = null;
165
+ let idx: number = -1;
166
+ arrForEach(listeners, (listener, lp) => {
167
+ if (listener.w === newWatcher) {
168
+ theListener = listener;
169
+ idx = lp;
170
+ return -1;
171
+ }
172
+ });
173
+
174
+ return { i: idx, l: theListener };
175
+ }
176
+ function _addDelayedCfgListener(listeners: { rm: () => void, w: WatcherFunction<IConfiguration>}[], newWatcher: WatcherFunction<IConfiguration>) {
177
+ let theListener = _findWatcher(listeners, newWatcher).l;
178
+
179
+ if (!theListener) {
180
+ theListener ={
181
+ w: newWatcher,
182
+ rm: () => {
183
+ let fnd = _findWatcher(listeners, newWatcher);
184
+ if (fnd.i !== -1) {
185
+ listeners.splice(fnd.i, 1);
186
+ }
187
+ }
188
+ };
189
+ listeners.push(theListener);
190
+ }
191
+
192
+ return theListener;
193
+ }
194
+
195
+ function _registerDelayedCfgListener(config: IConfiguration, listeners: { rm: () => void, w: WatcherFunction<IConfiguration>}[], logger: IDiagnosticLogger) {
196
+ arrForEach(listeners, (listener) => {
197
+ let unloadHdl = onConfigChange(config, listener.w, logger);
198
+ delete listener.w; // Clear the listener reference so it will get garbage collected.
199
+ // replace the remove function
200
+ listener.rm = () => {
201
+ unloadHdl.rm();
202
+ };
203
+ });
204
+ }
205
+
206
+ export class AppInsightsCore implements IAppInsightsCore {
207
+ public static defaultConfig: IConfiguration;
208
+ public config: IConfiguration;
209
+ public logger: IDiagnosticLogger;
210
+
211
+ public _extensions: IPlugin[];
212
+ public isInitialized: () => boolean;
213
+
18
214
  constructor() {
19
- super();
215
+ // NOTE!: DON'T set default values here, instead set them in the _initDefaults() function as it is also called during teardown()
216
+ let _configHandler: IDynamicConfigHandler<IConfiguration>;
217
+ let _isInitialized: boolean;
218
+ let _eventQueue: ITelemetryItem[];
219
+ let _notificationManager: INotificationManager | null | undefined;
220
+ let _perfManager: IPerfManager | null;
221
+ let _cfgPerfManager: IPerfManager | null;
222
+ let _cookieManager: ICookieMgr | null;
223
+ let _pluginChain: ITelemetryPluginChain | null;
224
+ let _configExtensions: IPlugin[];
225
+ let _coreExtensions: ITelemetryPlugin[] | null;
226
+ let _channelControl: IChannelController | null;
227
+ let _channelConfig: IChannelControls[][] | null | undefined;
228
+ let _channelQueue: _IInternalChannels[] | null;
229
+ let _isUnloading: boolean;
230
+ let _telemetryInitializerPlugin: TelemetryInitializerPlugin;
231
+ let _internalLogsEventName: string | null;
232
+ let _evtNamespace: string;
233
+ let _unloadHandlers: IUnloadHandlerContainer;
234
+ let _hooks: Array<ILegacyUnloadHook | IUnloadHook>;
235
+ let _debugListener: INotificationListener | null;
236
+ let _traceCtx: IDistributedTraceContext | null;
237
+ let _instrumentationKey: string | null;
238
+ let _cfgListeners: { rm: () => void, w: WatcherFunction<IConfiguration>}[];
20
239
 
21
- dynamicProto(AppInsightsCore, this, (_self, _base) => {
240
+ /**
241
+ * Internal log poller
242
+ */
243
+ let _internalLogPoller: number = 0;
22
244
 
245
+ dynamicProto(AppInsightsCore, this, (_self) => {
246
+
247
+ // Set the default values (also called during teardown)
248
+ _initDefaults();
249
+
250
+ _self.isInitialized = () => _isInitialized;
251
+
252
+ // Creating the self.initialize = ()
23
253
  _self.initialize = (config: IConfiguration, extensions: IPlugin[], logger?: IDiagnosticLogger, notificationManager?: INotificationManager): void => {
24
- _base.initialize(config, extensions, logger || new DiagnosticLogger(config), notificationManager || new NotificationManager(config));
254
+ if (_isUnloading) {
255
+ throwError(strSdkUnloadingError);
256
+ }
257
+
258
+ // Make sure core is only initialized once
259
+ if (_self.isInitialized()) {
260
+ throwError("Core cannot be initialized more than once");
261
+ }
262
+
263
+ // Re-assigning the local config property so we don't have any references to the passed value and it can be garbage collected
264
+ _configHandler = createDynamicConfig(config, defaultConfig, logger || _self.logger, false);
265
+ config = _configHandler.cfg;
266
+
267
+ // This will be "re-run" if the referenced config properties are changed
268
+ _addUnloadHook(_configHandler.watch((details) => {
269
+ _instrumentationKey = details.cfg.instrumentationKey;
270
+
271
+ if (isNullOrUndefined(_instrumentationKey)) {
272
+ throwError("Please provide instrumentation key");
273
+ }
274
+ }));
275
+
276
+ _notificationManager = notificationManager;
277
+
278
+ // For backward compatibility only
279
+ _self[strNotificationManager] = notificationManager;
280
+
281
+ _initDebugListener();
282
+ _initPerfManager();
283
+
284
+ // add notification to the extensions in the config so other plugins can access it
285
+ _initExtConfig();
286
+
287
+ _self.logger = logger || new DiagnosticLogger(config);
288
+ _configHandler.logger = _self.logger;
289
+
290
+ let cfgExtensions = config.extensions;
291
+
292
+ // Extension validation
293
+ _configExtensions = [];
294
+ _configExtensions.push(...extensions, ...cfgExtensions);
295
+ _channelConfig = config.channels;
296
+
297
+ _initPluginChain(null);
298
+
299
+ if (!_channelQueue || _channelQueue.length === 0) {
300
+ throwError("No " + STR_CHANNELS + " available");
301
+ }
302
+
303
+ _registerDelayedCfgListener(config, _cfgListeners, _self.logger);
304
+ _cfgListeners = null;
305
+
306
+ _isInitialized = true;
307
+ _self.releaseQueue();
308
+ };
309
+
310
+ _self.getTransmissionControls = (): IChannelControls[][] => {
311
+ let controls: IChannelControls[][] = [];
312
+ if (_channelQueue) {
313
+ arrForEach(_channelQueue, (channels) => {
314
+ controls.push(channels.queue);
315
+ });
316
+ }
317
+
318
+ return objFreeze(controls);
25
319
  };
26
320
 
27
321
  _self.track = (telemetryItem: ITelemetryItem) => {
@@ -33,25 +327,665 @@ export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
33
327
  }
34
328
 
35
329
  // do basic validation before sending it through the pipeline
36
- _validateTelemetryItem(telemetryItem);
330
+ if (!telemetryItem.name && isNullOrUndefined(telemetryItem.name)) {
331
+ _notifyInvalidEvent(telemetryItem);
332
+ throwError("telemetry name required");
333
+ }
37
334
 
38
- _base.track(telemetryItem);
335
+ // setup default iKey if not passed in
336
+ telemetryItem.iKey = telemetryItem.iKey || _instrumentationKey;
337
+
338
+ // add default timestamp if not passed in
339
+ telemetryItem.time = telemetryItem.time || toISOString(new Date());
340
+
341
+ // Common Schema 4.0
342
+ telemetryItem.ver = telemetryItem.ver || "4.0";
343
+
344
+ if (!_isUnloading && _self.isInitialized()) {
345
+ // Process the telemetry plugin chain
346
+ _createTelCtx().processNext(telemetryItem);
347
+ } else {
348
+ // Queue events until all extensions are initialized
349
+ _eventQueue.push(telemetryItem);
350
+ }
39
351
  }, () => ({ item: telemetryItem }), !((telemetryItem as any).sync));
40
352
  };
41
353
 
42
- function _validateTelemetryItem(telemetryItem: ITelemetryItem) {
43
- if (isNullOrUndefined(telemetryItem.name)) {
44
- _notifyInvalidEvent(telemetryItem);
45
- throwError("telemetry name required");
354
+ _self.getProcessTelContext = _createTelCtx;
355
+
356
+ _self.getNotifyMgr = (): INotificationManager => {
357
+ if (!_notificationManager) {
358
+ _addUnloadHook(_configHandler.watch((details) => {
359
+ _notificationManager = new NotificationManager(details.cfg);
360
+ // For backward compatibility only
361
+ _self[strNotificationManager] = _notificationManager;
362
+ }));
363
+ }
364
+
365
+ return _notificationManager;
366
+ };
367
+
368
+ /**
369
+ * Adds a notification listener. The SDK calls methods on the listener when an appropriate notification is raised.
370
+ * The added plugins must raise notifications. If the plugins do not implement the notifications, then no methods will be
371
+ * called.
372
+ * @param listener - An INotificationListener object.
373
+ */
374
+ _self.addNotificationListener = (listener: INotificationListener): void => {
375
+ if (_notificationManager) {
376
+ _notificationManager.addNotificationListener(listener);
377
+ }
378
+ };
379
+
380
+ /**
381
+ * Removes all instances of the listener.
382
+ * @param listener - INotificationListener to remove.
383
+ */
384
+ _self.removeNotificationListener = (listener: INotificationListener): void => {
385
+ if (_notificationManager) {
386
+ _notificationManager.removeNotificationListener(listener);
387
+ }
388
+ }
389
+
390
+ _self.getCookieMgr = (): ICookieMgr => {
391
+ if (!_cookieManager) {
392
+ _addUnloadHook(_configHandler.watch((details) => {
393
+ _cookieManager = createCookieMgr(details.cfg, _self.logger);
394
+ }));
395
+ }
396
+
397
+ return _cookieManager;
398
+ };
399
+
400
+ _self.setCookieMgr = (cookieMgr: ICookieMgr) => {
401
+ _cookieManager = cookieMgr;
402
+ };
403
+
404
+ _self.getPerfMgr = (): IPerfManager => {
405
+ if (!_perfManager && !_cfgPerfManager) {
406
+ _addUnloadHook(_configHandler.watch((details) => {
407
+ if (details.cfg.enablePerfMgr) {
408
+ let createPerfMgr = details.cfg.createPerfMgr;
409
+ if (isFunction(createPerfMgr)) {
410
+ _cfgPerfManager = createPerfMgr(_self, _self.getNotifyMgr());
411
+ }
412
+ }
413
+ }));
414
+ }
415
+
416
+ return _perfManager || _cfgPerfManager || getGblPerfMgr();
417
+ };
418
+
419
+ _self.setPerfMgr = (perfMgr: IPerfManager) => {
420
+ _perfManager = perfMgr;
421
+ };
422
+
423
+ _self.eventCnt = (): number => {
424
+ return _eventQueue.length;
425
+ };
426
+
427
+ _self.releaseQueue = () => {
428
+ if (_isInitialized && _eventQueue.length > 0) {
429
+ let eventQueue = _eventQueue;
430
+ _eventQueue = [];
431
+
432
+ arrForEach(eventQueue, (event: ITelemetryItem) => {
433
+ _createTelCtx().processNext(event);
434
+ });
435
+ }
436
+ };
437
+
438
+ /**
439
+ * Periodically check logger.queue for log messages to be flushed
440
+ */
441
+ _self.pollInternalLogs = (eventName?: string): number => {
442
+ _internalLogsEventName = eventName || null;
443
+
444
+ _addUnloadHook(_configHandler.watch((details) => {
445
+ let interval: number = details.cfg.diagnosticLogInterval;
446
+ if (!interval || !(interval > 0)) {
447
+ interval = 10000;
448
+ }
449
+
450
+ if(_internalLogPoller) {
451
+ clearInterval(_internalLogPoller);
452
+ }
453
+ _internalLogPoller = setInterval(() => {
454
+ _flushInternalLogs();
455
+ }, interval) as any;
456
+ }));
457
+
458
+ return _internalLogPoller;
459
+ }
460
+
461
+ /**
462
+ * Stop polling log messages from logger.queue
463
+ */
464
+ _self.stopPollingInternalLogs = (): void => {
465
+ if(_internalLogPoller) {
466
+ clearInterval(_internalLogPoller);
467
+ _internalLogPoller = 0;
468
+ _flushInternalLogs();
46
469
  }
47
470
  }
471
+
472
+ // Add addTelemetryInitializer
473
+ proxyFunctions(_self, () => _telemetryInitializerPlugin, [ "addTelemetryInitializer" ]);
474
+
475
+ _self.unload = (isAsync: boolean = true, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void => {
476
+ if (!_isInitialized) {
477
+ // The SDK is not initialized
478
+ throwError(strSdkNotInitialized);
479
+ }
480
+
481
+ // Check if the SDK still unloading so throw
482
+ if (_isUnloading) {
483
+ // The SDK is already unloading
484
+ throwError(strSdkUnloadingError);
485
+ }
486
+
487
+ let unloadState: ITelemetryUnloadState = {
488
+ reason: TelemetryUnloadReason.SdkUnload,
489
+ isAsync: isAsync,
490
+ flushComplete: false
491
+ }
492
+
493
+ let processUnloadCtx = createProcessTelemetryUnloadContext(_getPluginChain(), _self);
494
+ processUnloadCtx.onComplete(() => {
495
+ let oldHooks = _hooks;
496
+ _hooks = [];
497
+
498
+ // Remove all registered unload hooks
499
+ arrForEach(oldHooks, (fn) => {
500
+ // allow either rm or remove callback function
501
+ try{
502
+ ((fn as IUnloadHook).rm || (fn as ILegacyUnloadHook).remove).call(fn);
503
+ } catch (e) {
504
+ _throwInternal(_self.logger, eLoggingSeverity.WARNING, _eInternalMessageId.PluginException, "Unloading:" + dumpObj(e));
505
+ }
506
+ });
507
+
508
+ _initDefaults();
509
+ unloadComplete && unloadComplete(unloadState);
510
+ }, _self);
511
+
512
+ function _doUnload(flushComplete: boolean) {
513
+ unloadState.flushComplete = flushComplete;
514
+ _isUnloading = true;
515
+
516
+ // Run all of the unload handlers first (before unloading the plugins)
517
+ _unloadHandlers.run(processUnloadCtx, unloadState);
518
+
519
+ // Stop polling the internal logs
520
+ _self.stopPollingInternalLogs();
521
+
522
+ // Start unloading the components, from this point onwards the SDK should be considered to be in an unstable state
523
+ processUnloadCtx.processNext(unloadState);
524
+ }
525
+
526
+ if (!_flushChannels(isAsync, _doUnload, SendRequestReason.SdkUnload, cbTimeout)) {
527
+ _doUnload(false);
528
+ }
529
+ };
530
+
531
+ _self.getPlugin = _getPlugin;
532
+
533
+ _self.addPlugin = <T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, isAsync?: boolean, addCb?: (added?: boolean) => void): void => {
534
+ if (!plugin) {
535
+ addCb && addCb(false);
536
+ _logOrThrowError(strValidationError);
537
+ return;
538
+ }
539
+
540
+ let existingPlugin = _getPlugin(plugin.identifier);
541
+ if (existingPlugin && !replaceExisting) {
542
+ addCb && addCb(false);
543
+
544
+ _logOrThrowError("Plugin [" + plugin.identifier + "] is already loaded!");
545
+ return;
546
+ }
547
+
548
+ let updateState: ITelemetryUpdateState = {
549
+ reason: TelemetryUpdateReason.PluginAdded
550
+ };
551
+
552
+ function _addPlugin(removed: boolean) {
553
+ _configExtensions.push(plugin);
554
+ updateState.added = [plugin];
555
+
556
+ // Re-Initialize the plugin chain
557
+ _initPluginChain(updateState);
558
+ addCb && addCb(true);
559
+ }
560
+
561
+ if (existingPlugin) {
562
+ let removedPlugins: IPlugin[] = [existingPlugin.plugin];
563
+ let unloadState: ITelemetryUnloadState = {
564
+ reason: TelemetryUnloadReason.PluginReplace,
565
+ isAsync: !!isAsync
566
+ };
567
+
568
+ _removePlugins(removedPlugins, unloadState, (removed) => {
569
+ if (!removed) {
570
+ // Previous plugin was successfully removed or was not installed
571
+ addCb && addCb(false);
572
+ } else {
573
+ updateState.removed = removedPlugins
574
+ updateState.reason |= TelemetryUpdateReason.PluginRemoved;
575
+ _addPlugin(true);
576
+ }
577
+ });
578
+ } else {
579
+ _addPlugin(false);
580
+ }
581
+ };
582
+
583
+ _self.updateCfg = <T extends IConfiguration = IConfiguration>(newConfig: T, mergeExisting: boolean = true) => {
584
+ let updateState: ITelemetryUpdateState = {
585
+ reason: TelemetryUpdateReason.ConfigurationChanged,
586
+ cfg: _configHandler.cfg,
587
+ oldCfg: deepExtend({}, _configHandler.cfg),
588
+ newConfig: deepExtend({}, newConfig),
589
+ merge: mergeExisting
590
+ };
591
+
592
+ newConfig = updateState.newConfig as T;
593
+
594
+ let cfg = _configHandler.cfg;
595
+
596
+ // replace the immutable values
597
+ newConfig.extensions = cfg.extensions;
598
+ newConfig.channels = cfg.channels;
599
+
600
+ // We don't currently allow updating the extensions and channels via the update config
601
+ // So overwriting any user provided values to reuse the existing values
602
+ // Explicitly blocking any previous config watchers so that they don't get called because
603
+ // of this bulk update (Probably not necessary)
604
+ (_configHandler as _IInternalDynamicConfigHandler<IConfiguration>)._block((details) => {
605
+
606
+ // Lets assign the new values to the existing config either overwriting or re-assigning
607
+ let theConfig = details.cfg;
608
+ _deepMergeConfig(details, theConfig, newConfig, mergeExisting);
609
+
610
+ if (!mergeExisting) {
611
+ // Remove (unassign) the values "missing" from the newConfig and also not in the default config
612
+ objForEachKey(theConfig, (key) => {
613
+ if (!objHasOwn(newConfig, key)) {
614
+ // Set the value to undefined
615
+ details.hdlr.set(theConfig, key, UNDEFINED_VALUE);
616
+ }
617
+ });
618
+ }
619
+
620
+ // Apply defaults to the new config
621
+ applyDefaults(theConfig, defaultConfig as any);
622
+
623
+ // Reapply the notification manager
624
+ _initExtConfig();
625
+ });
626
+
627
+ // Now execute all of the listeners (synchronously) so they update their values immediately
628
+ _configHandler.notify();
629
+
630
+ _doUpdate(updateState);
631
+
632
+ };
633
+
634
+ _self.evtNamespace = (): string => {
635
+ return _evtNamespace;
636
+ };
637
+
638
+ _self.flush = _flushChannels;
48
639
 
640
+ _self.getTraceCtx = (createNew?: boolean): IDistributedTraceContext | null => {
641
+ if (!_traceCtx) {
642
+ _traceCtx = createDistributedTraceContext();
643
+ }
644
+
645
+ return _traceCtx;
646
+ };
647
+
648
+ _self.setTraceCtx = (traceCtx: IDistributedTraceContext): void => {
649
+ _traceCtx = traceCtx || null;
650
+ };
651
+
652
+ _self.addUnloadHook = _addUnloadHook;
653
+
654
+ // Create the addUnloadCb
655
+ proxyFunctionAs(_self, "addUnloadCb", () => _unloadHandlers, "add");
656
+
657
+ _self.onCfgChange = <T extends IConfiguration = IConfiguration>(handler: WatcherFunction<T>): IUnloadHook => {
658
+ let unloadHook: IUnloadHook;
659
+ if (!_isInitialized) {
660
+ unloadHook = _addDelayedCfgListener(_cfgListeners, handler);
661
+ } else {
662
+ unloadHook = onConfigChange(_configHandler.cfg, handler, _self.logger);
663
+ }
664
+
665
+ return {
666
+ rm: () => {
667
+ unloadHook.rm();
668
+ }
669
+ }
670
+ };
671
+
672
+ function _initDefaults() {
673
+ _isInitialized = false;
674
+
675
+ // Use a default logger so initialization errors are not dropped on the floor with full logging
676
+ _configHandler = createDynamicConfig({}, defaultConfig, _self.logger);
677
+
678
+ // Set the logging level to critical so that any critical initialization failures are displayed on the console
679
+ _configHandler.cfg.loggingLevelConsole = eLoggingSeverity.CRITICAL;
680
+
681
+ // Define _self.config
682
+ objDefineProp(_self, "config", {
683
+ configurable: true,
684
+ enumerable: true,
685
+ get: () => _configHandler.cfg,
686
+ set: (newValue) => {
687
+ if (_self.isInitialized()) {
688
+ _self.updateCfg(newValue, false);
689
+ }
690
+ }
691
+ });
692
+
693
+
694
+
695
+ _self.logger = new DiagnosticLogger(_configHandler.cfg);
696
+ _self._extensions = [];
697
+
698
+ _telemetryInitializerPlugin = new TelemetryInitializerPlugin();
699
+ _eventQueue = [];
700
+ _notificationManager = null;
701
+ _perfManager = null;
702
+ _cfgPerfManager = null;
703
+ _cookieManager = null;
704
+ _pluginChain = null;
705
+ _coreExtensions = null;
706
+ _configExtensions = [];
707
+ _channelControl = null;
708
+ _channelConfig = null;
709
+ _channelQueue = null;
710
+ _isUnloading = false;
711
+ _internalLogsEventName = null;
712
+ _evtNamespace = createUniqueNamespace("AIBaseCore", true);
713
+ _unloadHandlers = createUnloadHandlerContainer();
714
+ _traceCtx = null;
715
+ _instrumentationKey = null;
716
+ _hooks = [];
717
+ _cfgListeners = [];
718
+ }
719
+
720
+ function _createTelCtx(): IProcessTelemetryContext {
721
+ return createProcessTelemetryContext(_getPluginChain(), _configHandler.cfg, _self);
722
+ }
723
+
724
+ // Initialize or Re-initialize the plugins
725
+ function _initPluginChain(updateState: ITelemetryUpdateState | null) {
726
+ // Extension validation
727
+ let theExtensions = _validateExtensions(_self.logger, ChannelControllerPriority, _configExtensions);
728
+
729
+ _coreExtensions = theExtensions.core;
730
+ _pluginChain = null;
731
+
732
+ // Sort the complete set of extensions by priority
733
+ let allExtensions = theExtensions.all;
734
+
735
+ // Initialize the Channel Queues and the channel plugins first
736
+ _channelQueue = objFreeze(createChannelQueues(_channelConfig, allExtensions, _self));
737
+ if (_channelControl) {
738
+ // During add / remove of a plugin this may get called again, so don't re-add if already present
739
+ // But we also want the controller as the last, so remove if already present
740
+ // And reusing the existing instance, just in case an installed plugin has a reference and
741
+ // is using it.
742
+ let idx = arrIndexOf(allExtensions, _channelControl);
743
+ if (idx !== -1) {
744
+ allExtensions.splice(idx, 1);
745
+ }
746
+
747
+ idx = arrIndexOf(_coreExtensions, _channelControl);
748
+ if (idx !== -1) {
749
+ _coreExtensions.splice(idx, 1);
750
+ }
751
+
752
+ (_channelControl as IInternalChannelController)._setQueue(_channelQueue);
753
+ } else {
754
+ _channelControl = createChannelControllerPlugin(_channelQueue, _self);
755
+ }
756
+
757
+ // Add on "channelController" as the last "plugin"
758
+ allExtensions.push(_channelControl);
759
+ _coreExtensions.push(_channelControl);
760
+
761
+ // Required to allow plugins to call core.getPlugin() during their own initialization
762
+ _self._extensions = sortPlugins(allExtensions);
763
+
764
+ // Initialize the controls
765
+ _channelControl.initialize(_configHandler.cfg, _self, allExtensions);
766
+
767
+ initializePlugins(_createTelCtx(), allExtensions);
768
+
769
+ // Now reset the extensions to just those being managed by AppInsightsCore
770
+ _self._extensions = objFreeze(sortPlugins(_coreExtensions || [])).slice();
771
+
772
+ if (updateState) {
773
+ _doUpdate(updateState);
774
+ }
775
+ }
776
+
777
+ function _getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T> {
778
+ let theExt: ILoadedPlugin<T> = null;
779
+ let thePlugin: IPlugin = null;
780
+
781
+ arrForEach(_self._extensions, (ext: any) => {
782
+ if (ext.identifier === pluginIdentifier && ext !== _channelControl && ext !== _telemetryInitializerPlugin) {
783
+ thePlugin = ext;
784
+ return -1;
785
+ }
786
+ });
787
+
788
+ if (!thePlugin && _channelControl) {
789
+ // Check the channel Controller
790
+ thePlugin = _channelControl.getChannel(pluginIdentifier);
791
+ }
792
+
793
+ if (thePlugin) {
794
+ theExt = {
795
+ plugin: thePlugin as T,
796
+ setEnabled: (enabled: boolean) => {
797
+ _getPluginState(thePlugin)[STR_DISABLED] = !enabled;
798
+ },
799
+ isEnabled: () => {
800
+ let pluginState = _getPluginState(thePlugin);
801
+ return !pluginState.teardown && !pluginState[STR_DISABLED];
802
+ },
803
+ remove: (isAsync: boolean = true, removeCb?: (removed?: boolean) => void): void => {
804
+ let pluginsToRemove: IPlugin[] = [thePlugin];
805
+ let unloadState: ITelemetryUnloadState = {
806
+ reason: TelemetryUnloadReason.PluginUnload,
807
+ isAsync: isAsync
808
+ };
809
+
810
+ _removePlugins(pluginsToRemove, unloadState, (removed) => {
811
+ if (removed) {
812
+ // Re-Initialize the plugin chain
813
+ _initPluginChain({
814
+ reason: TelemetryUpdateReason.PluginRemoved,
815
+ removed: pluginsToRemove
816
+ });
817
+ }
818
+
819
+ removeCb && removeCb(removed);
820
+ });
821
+ }
822
+ }
823
+ }
824
+
825
+ return theExt;
826
+ }
827
+
828
+ function _getPluginChain() {
829
+ if (!_pluginChain) {
830
+ // copy the collection of extensions
831
+ let extensions = (_coreExtensions || []).slice();
832
+
833
+ // During add / remove this may get called again, so don't readd if already present
834
+ if (arrIndexOf(extensions, _telemetryInitializerPlugin) === -1) {
835
+ extensions.push(_telemetryInitializerPlugin);
836
+ }
837
+
838
+ _pluginChain = createTelemetryProxyChain(sortPlugins(extensions), _configHandler.cfg, _self);
839
+ }
840
+
841
+ return _pluginChain;
842
+ }
843
+
844
+ function _removePlugins(thePlugins: IPlugin[], unloadState: ITelemetryUnloadState, removeComplete: (removed: boolean) => void) {
845
+
846
+ if (thePlugins && thePlugins.length > 0) {
847
+ let unloadChain = createTelemetryProxyChain(thePlugins, _configHandler.cfg, _self);
848
+ let unloadCtx = createProcessTelemetryUnloadContext(unloadChain, _self);
849
+
850
+ unloadCtx.onComplete(() => {
851
+ let removed = false;
852
+
853
+ // Remove the listed config extensions
854
+ let newConfigExtensions: IPlugin[] = [];
855
+ arrForEach(_configExtensions, (plugin, idx) => {
856
+ if (!_isPluginPresent(plugin, thePlugins)) {
857
+ newConfigExtensions.push(plugin);
858
+ } else {
859
+ removed = true;
860
+ }
861
+ });
862
+
863
+ _configExtensions = newConfigExtensions;
864
+
865
+ // Re-Create the channel config
866
+ let newChannelConfig: IChannelControls[][] = [];
867
+ if (_channelConfig) {
868
+ arrForEach(_channelConfig, (queue, idx) => {
869
+ let newQueue: IChannelControls[] = [];
870
+ arrForEach(queue, (channel) => {
871
+ if (!_isPluginPresent(channel, thePlugins)) {
872
+ newQueue.push(channel);
873
+ } else {
874
+ removed = true;
875
+ }
876
+ });
877
+
878
+ newChannelConfig.push(newQueue);
879
+ });
880
+
881
+ _channelConfig = newChannelConfig;
882
+ }
883
+
884
+ removeComplete && removeComplete(removed);
885
+ });
886
+
887
+ unloadCtx.processNext(unloadState);
888
+ } else {
889
+ removeComplete(false);
890
+ }
891
+ }
892
+
893
+ function _flushInternalLogs() {
894
+ let queue: _InternalLogMessage[] = _self.logger ? _self.logger.queue : [];
895
+ if (queue) {
896
+ arrForEach(queue, (logMessage: _InternalLogMessage) => {
897
+ const item: ITelemetryItem = {
898
+ name: _internalLogsEventName ? _internalLogsEventName : "InternalMessageId: " + logMessage.messageId,
899
+ iKey: _instrumentationKey,
900
+ time: toISOString(new Date()),
901
+ baseType: _InternalLogMessage.dataType,
902
+ baseData: { message: logMessage.message }
903
+ };
904
+ _self.track(item);
905
+ });
906
+
907
+ queue.length = 0;
908
+ }
909
+ }
910
+
911
+ function _flushChannels(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason, cbTimeout?: number) {
912
+ if (_channelControl) {
913
+ return _channelControl.flush(isAsync, callBack, sendReason || SendRequestReason.SdkUnload, cbTimeout);
914
+ }
915
+
916
+ callBack && callBack(false);
917
+ return true;
918
+ }
919
+
920
+ function _initDebugListener() {
921
+ // Will get recalled if any referenced config values are changed
922
+ _addUnloadHook(_configHandler.watch((details) => {
923
+ let disableDbgExt = details.cfg.disableDbgExt;
924
+
925
+ if (disableDbgExt === true && _debugListener) {
926
+ // Remove any previously loaded debug listener
927
+ _notificationManager.removeNotificationListener(_debugListener);
928
+ _debugListener = null;
929
+ }
930
+
931
+ if (_notificationManager && !_debugListener && disableDbgExt !== true) {
932
+ _debugListener = getDebugListener(details.cfg);
933
+ _notificationManager.addNotificationListener(_debugListener);
934
+ }
935
+ }));
936
+ }
937
+
938
+ function _initPerfManager() {
939
+ // Will get recalled if any referenced config values are changed
940
+ _addUnloadHook(_configHandler.watch((details) => {
941
+ let enablePerfMgr = details.cfg.enablePerfMgr;
942
+
943
+ if (!enablePerfMgr && _cfgPerfManager) {
944
+ // Remove any existing config based performance manager
945
+ _cfgPerfManager = null;
946
+ }
947
+
948
+ if (enablePerfMgr) {
949
+ // Set the performance manager creation function if not defined
950
+ getSetValue(details.cfg, STR_CREATE_PERF_MGR, _createPerfManager);
951
+ }
952
+ }));
953
+ }
954
+
955
+ function _initExtConfig() {
956
+ _configHandler.cfg.extensionConfig.NotificationManager = _notificationManager;
957
+ }
958
+
959
+ function _doUpdate(updateState: ITelemetryUpdateState): void {
960
+ let updateCtx = createProcessTelemetryUpdateContext(_getPluginChain(), _self);
961
+
962
+ if (!_self._updateHook || _self._updateHook(updateCtx, updateState) !== true) {
963
+ updateCtx.processNext(updateState);
964
+ }
965
+ }
966
+
967
+ function _logOrThrowError(message: string) {
968
+ let logger = _self.logger;
969
+ if (logger) {
970
+ // there should always be a logger
971
+ _throwInternal(logger, eLoggingSeverity.WARNING, _eInternalMessageId.PluginException, message);
972
+ } else {
973
+ throwError(message);
974
+ }
975
+ }
976
+
49
977
  function _notifyInvalidEvent(telemetryItem: ITelemetryItem): void {
50
978
  let manager = _self.getNotifyMgr();
51
979
  if (manager) {
52
980
  manager.eventsDiscarded([telemetryItem], eEventsDiscardedReason.InvalidEvent);
53
981
  }
54
982
  }
983
+
984
+ function _addUnloadHook(hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>) {
985
+ if (hooks) {
986
+ arrAppend(_hooks, hooks);
987
+ }
988
+ }
55
989
  });
56
990
  }
57
991
 
@@ -59,7 +993,213 @@ export class AppInsightsCore extends BaseCore implements IAppInsightsCore {
59
993
  // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
60
994
  }
61
995
 
996
+ public getTransmissionControls(): IChannelControls[][] {
997
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
998
+ return null;
999
+ }
1000
+
62
1001
  public track(telemetryItem: ITelemetryItem) {
63
1002
  // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
64
1003
  }
1004
+
1005
+ public getProcessTelContext(): IProcessTelemetryContext {
1006
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1007
+ return null;
1008
+ }
1009
+
1010
+ public getNotifyMgr(): INotificationManager {
1011
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1012
+ return null;
1013
+ }
1014
+
1015
+ /**
1016
+ * Adds a notification listener. The SDK calls methods on the listener when an appropriate notification is raised.
1017
+ * The added plugins must raise notifications. If the plugins do not implement the notifications, then no methods will be
1018
+ * called.
1019
+ * @param listener - An INotificationListener object.
1020
+ */
1021
+ public addNotificationListener(listener: INotificationListener): void {
1022
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1023
+ }
1024
+
1025
+ /**
1026
+ * Removes all instances of the listener.
1027
+ * @param listener - INotificationListener to remove.
1028
+ */
1029
+ public removeNotificationListener(listener: INotificationListener): void {
1030
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1031
+ }
1032
+
1033
+ /**
1034
+ * Get the current cookie manager for this instance
1035
+ */
1036
+ public getCookieMgr(): ICookieMgr {
1037
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1038
+ return null;
1039
+ }
1040
+
1041
+ /**
1042
+ * Set the current cookie manager for this instance
1043
+ * @param cookieMgr - The manager, if set to null/undefined will cause the default to be created
1044
+ */
1045
+ public setCookieMgr(cookieMgr: ICookieMgr) {
1046
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1047
+ }
1048
+
1049
+ public getPerfMgr(): IPerfManager {
1050
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1051
+ return null;
1052
+ }
1053
+
1054
+ public setPerfMgr(perfMgr: IPerfManager) {
1055
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1056
+ }
1057
+
1058
+ public eventCnt(): number {
1059
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1060
+ return 0;
1061
+ }
1062
+
1063
+ /**
1064
+ * Periodically check logger.queue for
1065
+ */
1066
+ public pollInternalLogs(eventName?: string): number {
1067
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1068
+ return 0;
1069
+ }
1070
+
1071
+ /**
1072
+ * Periodically check logger.queue for
1073
+ */
1074
+ public stopPollingInternalLogs(): void {
1075
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1076
+ }
1077
+
1078
+ /**
1079
+ * Add a telemetry processor to decorate or drop telemetry events.
1080
+ * @param telemetryInitializer - The Telemetry Initializer function
1081
+ * @returns - A ITelemetryInitializerHandler to enable the initializer to be removed
1082
+ */
1083
+ public addTelemetryInitializer(telemetryInitializer: TelemetryInitializerFunction): ITelemetryInitializerHandler {
1084
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1085
+ return null;
1086
+ }
1087
+
1088
+ /**
1089
+ * Unload and Tear down the SDK and any initialized plugins, after calling this the SDK will be considered
1090
+ * to be un-initialized and non-operational, re-initializing the SDK should only be attempted if the previous
1091
+ * unload call return `true` stating that all plugins reported that they also unloaded, the recommended
1092
+ * approach is to create a new instance and initialize that instance.
1093
+ * This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
1094
+ * to successfully remove any global references or they may just be completing the unload process asynchronously.
1095
+ * @param isAsync - Can the unload be performed asynchronously (default)
1096
+ * @param unloadComplete - An optional callback that will be called once the unload has completed
1097
+ * @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the unload. Defaults to 5 seconds.
1098
+ */
1099
+ public unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void {
1100
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1101
+ }
1102
+
1103
+ public getPlugin<T extends IPlugin = IPlugin>(pluginIdentifier: string): ILoadedPlugin<T> {
1104
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1105
+ return null;
1106
+ }
1107
+
1108
+ /**
1109
+ * Add a new plugin to the installation
1110
+ * @param plugin - The new plugin to add
1111
+ * @param replaceExisting - should any existing plugin be replaced, default is false
1112
+ * @param doAsync - Should the add be performed asynchronously
1113
+ * @param addCb - [Optional] callback to call after the plugin has been added
1114
+ */
1115
+ public addPlugin<T extends IPlugin = ITelemetryPlugin>(plugin: T, replaceExisting?: boolean, doAsync?: boolean, addCb?: (added?: boolean) => void): void {
1116
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1117
+ }
1118
+
1119
+ /**
1120
+ * Update the configuration used and broadcast the changes to all loaded plugins
1121
+ * @param newConfig - The new configuration is apply
1122
+ * @param mergeExisting - Should the new configuration merge with the existing or just replace it. Default is to true.
1123
+ */
1124
+ public updateCfg<T extends IConfiguration = IConfiguration>(newConfig: T, mergeExisting?: boolean): void {
1125
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1126
+ }
1127
+
1128
+ /**
1129
+ * Returns the unique event namespace that should be used
1130
+ */
1131
+ public evtNamespace(): string {
1132
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1133
+ return null;
1134
+ }
1135
+
1136
+ /**
1137
+ * Add an unload handler that will be called when the SDK is being unloaded
1138
+ * @param handler - the handler
1139
+ */
1140
+ public addUnloadCb(handler: UnloadHandler): void {
1141
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1142
+ }
1143
+
1144
+ /**
1145
+ * Flush and send any batched / cached data immediately
1146
+ * @param async - send data asynchronously when true (defaults to true)
1147
+ * @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
1148
+ * If the caller doesn't return true the caller should assume that it may never be called.
1149
+ * @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
1150
+ * @returns - true if the callback will be return after the flush is complete otherwise the caller should assume that any provided callback will never be called
1151
+ */
1152
+ public flush(isAsync?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason): void {
1153
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1154
+ }
1155
+
1156
+ /**
1157
+ * Gets the current distributed trace context for this instance if available
1158
+ * @param createNew - Optional flag to create a new instance if one doesn't currently exist, defaults to true
1159
+ */
1160
+ public getTraceCtx(createNew?: boolean): IDistributedTraceContext | null {
1161
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1162
+ return null;
1163
+ }
1164
+
1165
+ /**
1166
+ * Sets the current distributed trace context for this instance if available
1167
+ */
1168
+ public setTraceCtx(newTracectx: IDistributedTraceContext): void {
1169
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1170
+ }
1171
+
1172
+ /**
1173
+ * Add this hook so that it is automatically removed during unloading
1174
+ * @param hooks - The single hook or an array of IInstrumentHook objects
1175
+ */
1176
+ public addUnloadHook(hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>): void {
1177
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1178
+ }
1179
+
1180
+ /**
1181
+ * Watches and tracks changes for accesses to the current config, and if the accessed config changes the
1182
+ * handler will be recalled.
1183
+ * @param handler
1184
+ * @returns A watcher handler instance that can be used to remove itself when being unloaded
1185
+ */
1186
+ public onCfgChange<T extends IConfiguration = IConfiguration>(handler: WatcherFunction<T>): IUnloadHook {
1187
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1188
+ return null;
1189
+ }
1190
+
1191
+ protected releaseQueue() {
1192
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1193
+ }
1194
+
1195
+ /**
1196
+ * Hook for Core extensions to allow them to update their own configuration before updating all of the plugins.
1197
+ * @param updateCtx - The plugin update context
1198
+ * @param updateState - The Update State
1199
+ * @returns boolean - True means the extension class will call updateState otherwise the Core will
1200
+ */
1201
+ protected _updateHook?(updateCtx: IProcessTelemetryUpdateContext, updateState: ITelemetryUpdateState): void | boolean {
1202
+ // @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
1203
+ return false;
1204
+ }
65
1205
  }