[main] (type change!) enhance exception telemetry with customer log Information (#2391)

This commit is contained in:
siyuniu-ms 2024-08-19 17:36:20 -07:00 коммит произвёл GitHub
Родитель 54ea6d7eb4
Коммит 3f8434ac85
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
13 изменённых файлов: 143 добавлений и 38 удалений

Просмотреть файл

@ -5,8 +5,8 @@ import { Snippet } from "../../../src/Snippet";
import { utlRemoveSessionStorage } from "@microsoft/applicationinsights-common";
export class AISKUSizeCheck extends AITestClass {
private readonly MAX_RAW_SIZE = 143;
private readonly MAX_BUNDLE_SIZE = 143;
private readonly MAX_RAW_SIZE = 144;
private readonly MAX_BUNDLE_SIZE = 144;
private readonly MAX_RAW_DEFLATE_SIZE = 58;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 58;
private readonly rawFilePath = "../dist/es5/applicationinsights-web.min.js";

Просмотреть файл

@ -6,24 +6,33 @@
<!-- import Application Insights JS SDK from CDN -->
<script type="text/javascript">!function(T,l,y){var S=T.location,k="script",D="instrumentationKey",C="ingestionendpoint",I="disableExceptionTracking",E="ai.device.",b="toLowerCase",w="crossOrigin",N="POST",e="appInsightsSDK",t=y.name||"appInsights";(y.name||T[e])&&(T[e]=t);var n=T[t]||function(d){var g=!1,f=!1,m={initialize:!0,queue:[],sv:"5",version:2,config:d};function v(e,t){var n={},a="Browser";return n[E+"id"]=a[b](),n[E+"type"]=a,n["ai.operation.name"]=S&&S.pathname||"_unknown_",n["ai.internal.sdkVersion"]="javascript:snippet_"+(m.sv||m.version),{time:function(){var e=new Date;function t(e){var t=""+e;return 1===t.length&&(t="0"+t),t}return e.getUTCFullYear()+"-"+t(1+e.getUTCMonth())+"-"+t(e.getUTCDate())+"T"+t(e.getUTCHours())+":"+t(e.getUTCMinutes())+":"+t(e.getUTCSeconds())+"."+((e.getUTCMilliseconds()/1e3).toFixed(3)+"").slice(2,5)+"Z"}(),iKey:e,name:"Microsoft.ApplicationInsights."+e.replace(/-/g,"")+"."+t,sampleRate:100,tags:n,data:{baseData:{ver:2}}}}var h=d.url||y.src;if(h){function a(e){var t,n,a,i,r,o,s,c,u,p,l;g=!0,m.queue=[],f||(f=!0,t=h,s=function(){var e={},t=d.connectionString;if(t)for(var n=t.split(";"),a=0;a<n.length;a++){var i=n[a].split("=");2===i.length&&(e[i[0][b]()]=i[1])}if(!e[C]){var r=e.endpointsuffix,o=r?e.location:null;e[C]="https://"+(o?o+".":"")+"dc."+(r||"services.visualstudio.com")}return e}(),c=s[D]||d[D]||"",u=s[C],p=u?u+"/v2/track":d.endpointUrl,(l=[]).push((n="SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details)",a=t,i=p,(o=(r=v(c,"Exception")).data).baseType="ExceptionData",o.baseData.exceptions=[{typeName:"SDKLoadFailed",message:n.replace(/\./g,"-"),hasFullStack:!1,stack:n+"\nSnippet failed to load ["+a+"] -- Telemetry is disabled\nHelp Link: https://go.microsoft.com/fwlink/?linkid=2128109\nHost: "+(S&&S.pathname||"_unknown_")+"\nEndpoint: "+i,parsedStack:[]}],r)),l.push(function(e,t,n,a){var i=v(c,"Message"),r=i.data;r.baseType="MessageData";var o=r.baseData;return o.message='AI (Internal): 99 message:"'+("SDK LOAD Failure: Failed to load Application Insights SDK script (See stack for details) ("+n+")").replace(/\"/g,"")+'"',o.properties={endpoint:a},i}(0,0,t,p)),function(e,t){if(JSON){var n=T.fetch;if(n&&!y.useXhr)n(t,{method:N,body:JSON.stringify(e),mode:"cors"});else if(XMLHttpRequest){var a=new XMLHttpRequest;a.open(N,t),a.setRequestHeader("Content-type","application/json"),a.send(JSON.stringify(e))}}}(l,p))}function i(e,t){f||setTimeout(function(){!t&&m.core||a()},500)}var e=function(){var n=l.createElement(k);n.src=h;var e=y[w];return!e&&""!==e||"undefined"==n[w]||(n[w]=e),n.onload=i,n.onerror=a,n.onreadystatechange=function(e,t){"loaded"!==n.readyState&&"complete"!==n.readyState||i(0,t)},n}();y.ld<0?l.getElementsByTagName("head")[0].appendChild(e):setTimeout(function(){l.getElementsByTagName(k)[0].parentNode.appendChild(e)},y.ld||0)}try{m.cookie=l.cookie}catch(p){}function t(e){for(;e.length;)!function(t){m[t]=function(){var e=arguments;g||m.queue.push(function(){m[t].apply(m,e)})}}(e.pop())}var n="track",r="TrackPage",o="TrackEvent";t([n+"Event",n+"PageView",n+"Exception",n+"Trace",n+"DependencyData",n+"Metric",n+"PageViewPerformance","start"+r,"stop"+r,"start"+o,"stop"+o,"addTelemetryInitializer","setAuthenticatedUserContext","clearAuthenticatedUserContext","flush"]),m.SeverityLevel={Verbose:0,Information:1,Warning:2,Error:3,Critical:4};var s=(d.extensionConfig||{}).ApplicationInsightsAnalytics||{};if(!0!==d[I]&&!0!==s[I]){var c="onerror";t(["_"+c]);var u=T[c];T[c]=function(e,t,n,a,i){var r=u&&u(e,t,n,a,i);return!0!==r&&m["_"+c]({message:e,url:t,lineNumber:n,columnNumber:a,error:i}),r},d.autoExceptionInstrumented=!0}return m}(y.cfg);function a(){y.onInit&&y.onInit(n)}(T[t]=n).queue&&0===n.queue.length?(n.queue.push(a),n.trackPageView({})):a()}(window,document,{
src: "https://js.monitor.azure.com/scripts/b/ai.2.min.js", // The SDK URL Source for the CDN
//src: "http://localhost:9001/AISKU/browser/es5/ai.2.min.js", // The URL Source for the local build
<!-- src: "http://localhost:9001/AISKU/browser/es5/ai.3.3.1.js", // The URL Source for the local build -->
crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
cfg: { // Application Insights Configuration
instrumentationKey: "INSTRUMENTATION_KEY",
connectionString: "InstrumentationKey=YOUR_INSTRUMENTATION_KEY",
expCfg: {
inclScripts: true,
expLog : () => {
return {logs: ["log info 1", "log info 2"]};
},
maxLogs: 1
}
//disableIKeyValidation: true
}});
// getExceptionScriptsInfo: true
}
});
</script>
</head>
<body>
<h1>Hello World!</h1>
<!-- trackException manual tests
trackException manual tests
<button onclick="javascript: throw 'String Error'">Throw String Exception</button>
<button onclick="javascript: appInsights.trackException({ exception: 'String Error' })">trackException with String as the exception</button>
<button onclick="javascript: try { throw 'String Error'; } catch(e) { appInsights.trackException({exception: e})}">trackException with try / catch</button>
<button onclick="javascript: appInsights.trackException('String Error')">trackException with String</button>
<button onclick="javascript: try { throw 'String Error'; } catch(e) { appInsights.trackException(null)}">trackException with null</button>
-->
</body>
</html>

Просмотреть файл

@ -18,7 +18,7 @@
[![GitHub Workflow Status (main)](https://img.shields.io/github/actions/workflow/status/microsoft/ApplicationInsights-JS/ci.yml?branch=main)](https://github.com/microsoft/ApplicationInsights-JS/tree/main)
[![Build Status](https://dev.azure.com/mseng/AppInsights/_apis/build/status%2FAppInsights%20-%20DevTools%2F1DS%20JavaScript%20SDK%20web%20SKU%20(main%3B%20master)?branchName=main)](https://dev.azure.com/mseng/AppInsights/_build/latest?definitionId=8184&branchName=main)
[![npm version](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-web.svg)](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-web)
[![minified size size](https://js.monitor.azure.com/scripts/b/3.min.js.svg)](https://js.monitor.azure.com/scripts/b/ai.3.min.js)
[![minified size size](https://js.monitor.azure.com/scripts/b/ai.3.min.js.svg)](https://js.monitor.azure.com/scripts/b/ai.3.min.js)
[![gzip size](https://js.monitor.azure.com/scripts/b/ai.3.min.js.gzip.svg)](https://js.monitor.azure.com/scripts/b/ai.3.min.js)
# Menu
@ -633,7 +633,7 @@ While the script downloads from the CDN, all tracking of your page is queued. On
> Summary:
>
> - ![current npm version](https://badge.fury.io/js/%40microsoft%2Fapplicationinsights-web.svg)
> - ![gzip compressed size](https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js.gzip.svg)
> - ![gzip compressed size](https://js.monitor.azure.com/scripts/b/ai.3.min.js.gzip.svg)
> - **~15 ms** overall initialization time
> - **Zero** tracking missed during life cycle of page

Просмотреть файл

@ -14,9 +14,20 @@ const appInsights = new ApplicationInsights({
config: {
connectionString: 'InstrumentationKey=YOUR_INSTRUMENTATION_KEY_GOES_HERE',
expCfg: {
inclScripts: true
inclScripts: true,
expLog : () => {
return {logs: ["log info 1", "log info 2"]};
},
maxLogs : 100
}
}
});
appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
```
### Where could I find those extra information?
The extra info is added as properties into exception Telemetry.
For script information, it would be stored under properties[exceptionScripts].
For log information, it would be stored under properties[exceptionLog].
You could find the info as shown in the pic:
![alt text](./img/exceptionTelemetry.png)

Двоичные данные
docs/img/exceptionTelemetry.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 83 KiB

Просмотреть файл

@ -476,6 +476,64 @@ export class AnalyticsPluginTests extends AITestClass {
});
this.testCase({
name: "AppInsightsTests: trackException would contain log info when config turns on",
useFakeTimers: true,
test: () => {
const appInsights = new AnalyticsPlugin();
const core = new AppInsightsCore();
const channel = new ChannelPlugin();
const properties = new PropertiesPlugin();
// Configuration
const config = {
instrumentationKey: 'ikey',
};
this.onDone(() => {
core.unload(false);
});
// Initialize Application Insights core with plugins
core.initialize(config, [appInsights, channel, properties]);
const trackStub = this.sandbox.stub(appInsights.core, "track");
appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
Assert.ok(trackStub.calledOnce, "single exception is tracked");
const baseData = (trackStub.args[0][0] as ITelemetryItem).baseData as IExceptionInternal;
const prop = baseData.properties;
Assert.equal(-1, JSON.stringify(prop).indexOf("test message"), "log info is not included");
let applelist = new Array(49).fill("apple");
// check maxLength default value
appInsights.config.expCfg.expLog = () => {
return {logs: applelist.concat(['pear', 'banana'])};
};;
this.clock.tick(1);
appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
Assert.ok(trackStub.calledTwice, "second exception is tracked");
const baseData2 = (trackStub.args[1][0] as ITelemetryItem).baseData as IExceptionInternal;
const prop2 = baseData2.properties;
Assert.deepEqual(true, prop2["exceptionLog"].includes('apple'), "log info before max length is included");
Assert.deepEqual(true, prop2["exceptionLog"].includes('pear'), "log info before max length is included");
Assert.equal(-1, prop2["exceptionLog"].indexOf("banana"), "text after max length should not be included");
// check maxLength would truncate the log info
let myLogFunction = () => {
return {logs: ['test message', 'check message', 'banana']};
};
appInsights.config.expCfg.expLog = myLogFunction;
appInsights.config.expCfg.maxLogs = 2;
this.clock.tick(1);
appInsights.trackException({error: new Error(), severityLevel: SeverityLevel.Critical});
this.clock.tick(1);
Assert.ok(trackStub.calledThrice, "third exception is tracked");
const baseData3 = (trackStub.args[2][0] as ITelemetryItem).baseData as IExceptionInternal;
const prop3 = baseData3.properties;
Assert.deepEqual(true, prop3["exceptionLog"].includes('test'), "log info is included");
Assert.equal(false, prop3["exceptionLog"].includes("banana"), "text after max length should not be included");
}
});
}
private addGenericTests(): void {

Просмотреть файл

@ -6,7 +6,7 @@
import dynamicProto from "@microsoft/dynamicproto-js";
import {
AnalyticsPluginIdentifier, Event as EventTelemetry, Exception, IAppInsights, IAutoExceptionTelemetry, IConfig, IDependencyTelemetry,
IEventTelemetry, IExceptionConfig, IExceptionInternal, IExceptionTelemetry, IMetricTelemetry, IPageViewPerformanceTelemetry,
IEventTelemetry, IExceptionInternal, IExceptionTelemetry, IMetricTelemetry, IPageViewPerformanceTelemetry,
IPageViewPerformanceTelemetryInternal, IPageViewTelemetry, IPageViewTelemetryInternal, ITraceTelemetry, Metric, PageView,
PageViewPerformance, PropertiesPluginIdentifier, RemoteDependencyData, Trace, createDistributedTraceContextFromTrace, createDomEvent,
createTelemetryItem, dataSanitizeString, eSeverityLevel, isCrossOriginError, strNotSpecified, utlDisableStorage, utlEnableStorage,
@ -14,15 +14,15 @@ import {
} from "@microsoft/applicationinsights-common";
import {
BaseTelemetryPlugin, IAppInsightsCore, IConfigDefaults, IConfiguration, ICookieMgr, ICustomProperties, IDistributedTraceContext,
IInstrumentCallDetails, IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext, ITelemetryInitializerHandler, ITelemetryItem,
ITelemetryPluginChain, ITelemetryUnloadState, InstrumentEvent, TelemetryInitializerFunction, _eInternalMessageId, arrForEach,
cfgDfBoolean, cfgDfMerge, cfgDfSet, cfgDfString, cfgDfValidate, createProcessTelemetryContext, createUniqueNamespace, dumpObj,
eLoggingSeverity, eventOff, eventOn, findAllScripts, generateW3CId, getDocument, getExceptionName, getHistory, getLocation, getWindow,
hasHistory, hasWindow, isFunction, isNullOrUndefined, isString, isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr,
strUndefined, throwError
IExceptionConfig, IInstrumentCallDetails, IPlugin, IProcessTelemetryContext, IProcessTelemetryUnloadContext,
ITelemetryInitializerHandler, ITelemetryItem, ITelemetryPluginChain, ITelemetryUnloadState, InstrumentEvent,
TelemetryInitializerFunction, _eInternalMessageId, arrForEach, cfgDfBoolean, cfgDfMerge, cfgDfSet, cfgDfString, cfgDfValidate,
createProcessTelemetryContext, createUniqueNamespace, dumpObj, eLoggingSeverity, eventOff, eventOn, findAllScripts, generateW3CId,
getDocument, getExceptionName, getHistory, getLocation, getWindow, hasHistory, hasWindow, isFunction, isNullOrUndefined, isString,
isUndefined, mergeEvtNamespace, onConfigChange, safeGetCookieMgr, strUndefined, throwError
} from "@microsoft/applicationinsights-core-js";
import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js";
import { isError, objDeepFreeze, objDefine, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils";
import { isArray, isError, objDeepFreeze, objDefine, scheduleTimeout, strIndexOf } from "@nevware21/ts-utils";
import { IAppInsightsInternal, PageViewManager } from "./Telemetry/PageViewManager";
import { PageViewPerformanceManager } from "./Telemetry/PageViewPerformanceManager";
import { PageVisitTimeManager } from "./Telemetry/PageVisitTimeManager";
@ -52,7 +52,7 @@ function _getReason(error: any) {
const MinMilliSeconds = 60000;
const defaultValues: IConfigDefaults<IConfig> = objDeepFreeze({
const defaultValues: IConfigDefaults<IConfig&IConfiguration> = objDeepFreeze({
sessionRenewalMs: cfgDfSet(_chkConfigMilliseconds, 30 * 60 * 1000),
sessionExpirationMs: cfgDfSet(_chkConfigMilliseconds, 24 * 60 * 60 * 1000),
disableExceptionTracking: cfgDfBoolean(),
@ -68,7 +68,7 @@ const defaultValues: IConfigDefaults<IConfig> = objDeepFreeze({
enableDebug: cfgDfBoolean(),
disableFlushOnBeforeUnload: cfgDfBoolean(),
disableFlushOnUnload: cfgDfBoolean(false, "disableFlushOnBeforeUnload"),
expCfg: cfgDfMerge<IExceptionConfig>({inclScripts: false})
expCfg: cfgDfMerge<IExceptionConfig>({inclScripts: false, expLog: undefined, maxLogs: 50})
});
function _chkConfigMilliseconds(value: number, defValue: number): number {
@ -101,7 +101,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
public identifier: string = AnalyticsPluginIdentifier; // do not change name or priority
public priority: number = 180; // take from reserved priority range 100- 200
public readonly config: IConfig;
public readonly config: IConfig & IConfiguration;
public queue: Array<() => void>;
public autoRoutePVDelay = 500; // ms; Time to wait after a route change before triggering a pageview to allow DOM changes to take place
@ -121,8 +121,9 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
let _autoExceptionInstrumented: boolean;
let _enableUnhandledPromiseRejectionTracking: boolean;
let _autoUnhandledPromiseInstrumented: boolean;
let _extConfig: IConfig;
let _extConfig: IConfig & IConfiguration;
let _autoTrackPageVisitTime: boolean;
let _expCfg: IExceptionConfig;
// Counts number of trackAjax invocations.
// By default we only monitor X ajax call per view to avoid too much load.
@ -425,10 +426,16 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
exception.id
).toInterface();
var doc = getDocument();
if (doc && _self.config.expCfg?.inclScripts) {
if (doc && _expCfg?.inclScripts) {
var scriptsInfo = findAllScripts(doc);
exceptionPartB.properties["exceptionScripts"] = JSON.stringify(scriptsInfo);
}
if (_expCfg?.expLog) {
let logs = _expCfg.expLog();
if (logs && logs.logs && isArray(logs.logs)) {
exceptionPartB.properties["exceptionLog"] = logs.logs.slice(0, _expCfg.maxLogs).join("\n");
}
}
let telemetryItem: ITelemetryItem = createTelemetryItem<IExceptionInternal>(
exceptionPartB,
Exception.dataType,
@ -625,6 +632,7 @@ export class AnalyticsPlugin extends BaseTelemetryPlugin implements IAppInsights
let ctx = createProcessTelemetryContext(null, config, core);
_extConfig = ctx.getExtCfg(identifier, defaultValues);
_expCfg = _extConfig.expCfg;
_autoTrackPageVisitTime = _extConfig.autoTrackPageVisitTime;
if (config.storagePrefix){

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT License.
import { IConfiguration, ICustomProperties, isNullOrUndefined } from "@microsoft/applicationinsights-core-js";
import { DistributedTracingModes } from "../Enums";
import { IExceptionConfig } from "./IExceptionTelemetry";
import { IRequestContext } from "./IRequestContext";
import { IStorageBuffer } from "./IStorageBuffer";
import { IThrottleMgrConfig } from "./IThrottleMgr";
@ -391,10 +390,6 @@ export interface IConfig {
*/
userOverrideEndpointUrl?: string;
/**
* [Optional] Set additional configuration for exceptions, such as more scripts to include in the exception telemetry.
*/
expCfg?: IExceptionConfig;
}
export class ConfigurationManager {

Просмотреть файл

@ -4,14 +4,6 @@
import { SeverityLevel } from "./Contracts/SeverityLevel";
import { IPartC } from "./IPartC";
export interface IExceptionConfig{
/**
* If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page.
* Notice: This would increase the size of the exception telemetry.
*/
inclScripts?: boolean;
}
/**
* @export
* @interface IExceptionTelemetry

Просмотреть файл

@ -26,7 +26,7 @@ export { IEventTelemetry } from "./Interfaces/IEventTelemetry";
export { ITraceTelemetry } from "./Interfaces/ITraceTelemetry";
export { IMetricTelemetry } from "./Interfaces/IMetricTelemetry";
export { IDependencyTelemetry } from "./Interfaces/IDependencyTelemetry";
export { IExceptionTelemetry, IAutoExceptionTelemetry, IExceptionInternal, IExceptionConfig } from "./Interfaces/IExceptionTelemetry";
export { IExceptionTelemetry, IAutoExceptionTelemetry, IExceptionInternal } from "./Interfaces/IExceptionTelemetry";
export { IPageViewTelemetry, IPageViewTelemetryInternal } from "./Interfaces/IPageViewTelemetry";
export { IPageViewPerformanceTelemetry, IPageViewPerformanceTelemetryInternal } from "./Interfaces/IPageViewPerformanceTelemetry";
export { Trace } from "./Telemetry/Trace";

Просмотреть файл

@ -4,6 +4,7 @@ import { IPromise } from "@nevware21/ts-async";
import { IAppInsightsCore } from "./IAppInsightsCore";
import { IChannelControls } from "./IChannelControls";
import { ICookieMgrConfig } from "./ICookieMgr";
import { IExceptionConfig } from "./IExceptionConfig";
import { IFeatureOptIn } from "./IFeatureOptIn";
import { INotificationManager } from "./INotificationManager";
import { IPerfManager } from "./IPerfManager";
@ -208,4 +209,9 @@ export interface IConfiguration {
*/
initInMemoMaxSize?: number;
/**
* [Optional] Set additional configuration for exceptions, such as more scripts to include in the exception telemetry.
* @since 3.3.2
*/
expCfg?: IExceptionConfig;
}

Просмотреть файл

@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
export interface IExceptionConfig{
/**
* If set to true, when exception is sent out, the SDK will also send out all scripts basic info that are loaded on the page.
* Notice: This would increase the size of the exception telemetry.
*/
inclScripts?: boolean;
/**
* Callback function for collecting logs to be included in telemetry data.
*
* The length of logs to generate is controlled by the `maxLogs` parameter.
*
* This callback is called before telemetry data is sent, allowing for dynamic customization of the logs.
*
* @returns {Object} An object with the following property:
* - logs: An array of strings, where each string represents a log entry to be included in the telemetry.
*
* @property {number} maxLogs - Specifies the maximum number of logs that can be generated. If not explicitly set, it defaults to 50.
*/
expLog: () => { logs: string[] },
maxLogs: number
}

Просмотреть файл

@ -4,6 +4,7 @@ export { IConfiguration } from "./JavaScriptSDK.Interfaces/IConfiguration";
export { IChannelControls, MinChannelPriorty, IInternalOfflineSupport } from "./JavaScriptSDK.Interfaces/IChannelControls";
export { IChannelControlsHost } from "./JavaScriptSDK.Interfaces/IChannelControlsHost";
export { ITelemetryPlugin, IPlugin } from "./JavaScriptSDK.Interfaces/ITelemetryPlugin";
export { IExceptionConfig } from "./JavaScriptSDK.Interfaces/IExceptionConfig";
export { IAppInsightsCore, ILoadedPlugin } from "./JavaScriptSDK.Interfaces/IAppInsightsCore";
export { ITelemetryItem, ICustomProperties, Tags } from "./JavaScriptSDK.Interfaces/ITelemetryItem";
export { IBaseProcessingContext, IProcessTelemetryContext, IProcessTelemetryUnloadContext, IProcessTelemetryUpdateContext } from "./JavaScriptSDK.Interfaces/IProcessTelemetryContext";