in extensions/applicationinsights-debugplugin-js/src/DebugPlugin.ts [83:380]
constructor() {
super();
let dashboard: Dashboard;
/**
* the style that will be permanently embedded in the webpage
* TODO: manage style conflicts (prepend unique ID to relevant class names?)
*/
let permStyleEl: HTMLStyleElement;
/**
* an object containing the individual debug bin items
*/
let debugBins: {
[key: string]: DebugBin;
};
/**
* the parent containing all the individual debugBins
*/
let debugBinParent: DebugBinParent;
/**
* the different telemetry functions that will be tracked
*/
let trackers: string[];
/**
* timestamp used to track number of seconds since webpage was loaded
*/
let startTime: number = +new Date();
/**
* the config for this plugin
*/
let _theConfig: IDebugConfig = getDefaultConfig();
dynamicProto(DebugPlugin, this, (_self, base) => {
_self.initialize = (config: IConfiguration | IDebugPluginConfig, core: IAppInsightsCore, extensions: IPlugin[], pluginChain?: ITelemetryPluginChain) => {
if (!_self.isInitialized()) {
base.initialize(config, core, extensions, pluginChain);
const defaultConfig = getDefaultConfig();
const ctx = _self._getTelCtx();
const identifier = _self.identifier;
objForEachKey(defaultConfig, (field, value) => {
_theConfig[field] = () => ctx.getConfig(identifier, field, value());
});
let foundTrackers: string[] = [];
trackers = _theConfig.trackers();
let prefix = _theConfig.cssPrefix();
// 1. Listen to Notifications
if (!_theConfig.disableNotifications()) {
let notifyMgr = (isFunction(core.getNotifyMgr) && core.getNotifyMgr()) || core["_notificationManager"];
if (notifyMgr) {
notifyMgr.addNotificationListener({
eventsSent: (events: ITelemetryItem[]) => {
dashboard.newLogEntry(events, dateNow() - startTime, "Notification:eventsSent", 0, "eventsSent");
},
eventsDiscarded: (events: ITelemetryItem[], reason: number) => {
dashboard.newLogEntry({
events,
reason
}, dateNow() - startTime, "Notification:eventsDiscarded", 0, "eventsDiscarded");
},
eventsSendRequest: (sendReason: number, isAsync: boolean): void => {
dashboard.newLogEntry({
sendReason,
isAsync
}, dateNow() - startTime, "Notification:eventsSendRequest", 0, "eventsSendRequest");
},
perfEvent: (perfEvent: IPerfEvent): void => {
let evtName = `Notification:perfEvent[${perfEvent.name}]`;
dashboard.newLogEntry(
perfEvent,
dateNow() - startTime, evtName, 0, "perfEvent");
}
});
if (trackers.indexOf("eventsSent") !== -1) {
foundTrackers.push("eventsSent");
}
if (trackers.indexOf("eventsSendRequest") !== -1) {
foundTrackers.push("eventsSendRequest");
}
if (trackers.indexOf("eventsDiscarded") !== -1) {
foundTrackers.push("eventsDiscarded");
}
if (trackers.indexOf("perfEvent") !== -1) {
foundTrackers.push("perfEvent");
}
}
}
// 2. Get all of the extensions and channels
debugBins = {};
let targetObjects: any[] = [core, _self.diagLog()];
// Get all of the config extensions
if (config.extensions) {
arrForEach(config.extensions, (ext) => {
_addTargets(targetObjects, ext);
});
}
// Get all of the passed extensions
if (extensions) {
arrForEach(extensions, (ext) => {
_addTargets(targetObjects, ext);
});
}
if (isFunction(core.getTransmissionControls)) {
let channelControls: IChannelControls[][] = core.getTransmissionControls();
if (channelControls) {
arrForEach(channelControls, (channel) => {
if (isArray(channel)) {
arrForEach(channel, (theChannel) => {
_addTargets(targetObjects, theChannel);
});
}
});
}
}
// 3. Instrument the functions
arrForEach(trackers, (tracker: string) => {
arrForEach(targetObjects, (target, idx) => {
let val = InstrumentFunc(target, tracker, {
req: _handleInstPreHook() as any as () => InstrumentorHooksCallback,
rsp: _handleInstPostHook() as any as () => InstrumentorHooksCallback
}, true);
if (val) {
if (foundTrackers.indexOf(tracker) === -1) {
foundTrackers.push(tracker);
}
}
});
});
// Sort the items
foundTrackers = foundTrackers.sort();
// 4. Create the Dashboard
dashboard = new Dashboard({
prefix,
trackers: foundTrackers,
excludeKeys: _theConfig.excludeKeys(),
maxMessages: _theConfig.maxMessages(),
includeFunctions: _theConfig.showFunctions()
});
// 5. setup debugBin
const debugBinContainer = document.createElement("div");
debugBinContainer.className = `${prefix}-debug-bin-container`;
debugBinParent = new DebugBinParent(debugBinContainer, [], 0, prefix);
arrForEach(foundTrackers, (tracker, idx) => {
debugBins[tracker] = new DebugBin(tracker, 0, debugBinParent, (idx + 1) * 50);
});
// 6. append permanent style
permStyleEl = document.createElement("style");
permStyleEl.innerHTML = permStyle(prefix);
document.head.appendChild(permStyleEl);
// 7. add button to debugBinParent
debugBinParent.addButton((evt: MouseEvent) => {
evt.stopPropagation();
if (dashboard.isDisplayed()) {
dashboard.hide();
} else {
dashboard.show();
}
}, "show dashboard");
document.body.appendChild(
debugBinContainer
);
// 8. Log the config as "keep" so it won't be dropped or cleared
dashboard.newLogEntry(config, 0, "config", 0, "config", true);
}
}
function _addTarget(targetObjects: any[], ext:any) {
if (ext && targetObjects.indexOf(ext) === -1) {
targetObjects.push(ext);
return true;
}
return false;
}
function _addTargets(targetObjects: any[], ext:any) {
if (_addTarget(targetObjects, ext)) {
if (isFunction(ext["_getDbgPlgTargets"])) {
let extra = ext["_getDbgPlgTargets"]();
if (isArray(extra)) {
arrForEach(extra, (tgt) => {
_addTargets(targetObjects, tgt);
});
}
}
}
}
function _createInstrumentObject(funcArgs: IInstrumentCallDetails, orgArgs: any[]) {
let result: any = {
funcName: funcArgs.name,
inst: funcArgs.inst
};
if (orgArgs && orgArgs.length) {
result.args = orgArgs;
}
if (!isUndefined(funcArgs.err)) {
result.err = funcArgs.err;
}
if (!isUndefined(funcArgs.rslt)) {
result.rslt = funcArgs.rslt;
}
return result;
}
function _getEvtPrefix(funcArgs: IInstrumentCallDetails) {
let identifier = getTargetName(funcArgs.inst);
let evtPrefix = funcArgs.name;
if (identifier) {
evtPrefix += ":" + identifier;
}
return evtPrefix;
}
function _logEntry(theEvent: any, evtName: string, kind: string) {
dashboard.newLogEntry(theEvent, dateNow() - startTime, evtName, 0, kind);
let dbgExt = getDebugExt(_self.core.config);
if (dbgExt && dbgExt.debugMsg) {
dbgExt.debugMsg(evtName, theEvent);
}
}
function _handleInstPreHook() {
return (funcArgs: IInstrumentCallDetails, ...orgArgs: any[]) => {
(debugBins[funcArgs.name] || debugBins.default).increment();
if (funcArgs.name === "trackException" && !debugBinParent.showChildren) {
debugBinParent.addClassToEl("notify");
}
let evtPrefix = _getEvtPrefix(funcArgs);
_logEntry(_createInstrumentObject(funcArgs, orgArgs), evtPrefix, funcArgs.name);
if (_theConfig.dumpToConsole() && console && console.log) {
console.log(`[${evtPrefix}] preProcess - funcArgs: `, funcArgs);
console.log(`[${evtPrefix}] preProcess - orgArgs: `, orgArgs);
}
}
}
function _handleInstPostHook() {
return (funcArgs: IInstrumentCallDetails, ...orgArgs: any[]) => {
if (!isUndefined(funcArgs.err)) {
let evtPrefix = _getEvtPrefix(funcArgs);
if (!debugBinParent.showChildren) {
debugBinParent.addClassToEl("notify");
}
// The called function threw an exception
_logEntry(_createInstrumentObject(funcArgs, orgArgs), evtPrefix, funcArgs.name);
if (_theConfig.dumpToConsole() && console && console.log) {
console.log(`[${evtPrefix}] complete`);
}
}
}
}
_self.processTelemetry = (event: ITelemetryItem, itemCtx?: IProcessTelemetryContext) => {
if (_theConfig.dumpToConsole() && console && console.log) {
console.log(`[${_self.identifier}:processTelemetry] complete`);
}
if (!debugBins["processTelemetry"] && _theConfig.logProcessTelemetry() === true) {
_logEntry(event, `[${_self.identifier}:processTelemetry[${event.baseType}]`, "processTelemetry");
}
_self.processNext(event, itemCtx);
}
});
}