Refactor Telemetry to include account name and experience (#452)

This commit is contained in:
Steve Faulkner
2021-02-28 15:56:09 -06:00
committed by GitHub
parent cf01ffa957
commit 10664162c7
45 changed files with 149 additions and 396 deletions

View File

@@ -4,13 +4,55 @@ import { MessageTypes } from "../../Contracts/ExplorerContracts";
import { appInsights } from "../appInsights";
import { configContext } from "../../ConfigContext";
import { userContext } from "../../UserContext";
import { getDataExplorerWindow } from "../../Utils/WindowUtils";
/**
* Class that persists telemetry data to the portal tables.
*/
// TODO: Remove this. It is perfectly find to pass any data to telemtry methods.
// This was added only to maintain stability while removing dependencies on explorer.databaseAccount and explorer.defaultExperience
type allowedKeys =
| "notebookId"
| "collectionId"
| "collectionName"
| "error"
| "isSample"
| "downloadCount"
| "baseUrl"
| "source"
| "description"
| "dataExplorerArea"
| "databaseName"
| "downloadCount"
| "favoriteCount"
| "abuseCategory"
| "errorStack"
| "tabTitle"
| "tabId"
| "conflictResourceType"
| "conflictOperationType"
| "conflictResourceId"
| "message"
| "files"
| "notebooks"
| "directories"
| "tabName"
| "databaseId"
| "queryName"
| "isPublishPending"
| "label"
| "scopesSelected"
| "title"
| "level"
| "changedSelectedValueTo"
| "area"
| "area"
| "paneTitle"
| "notebookUrl"
| "isNotebookEnabled"
| "commandButtonClicked"
| "count"
| "publishedCount"
| "underReviewCount"
| "removedCount";
type TelemetryData = { [key: string]: unknown };
type TelemetryData = { [key in allowedKeys]?: unknown };
export function trace(action: Action, actionModifier: string = ActionModifiers.Mark, data: TelemetryData = {}): void {
sendMessage({
@@ -18,11 +60,11 @@ export function trace(action: Action, actionModifier: string = ActionModifiers.M
data: {
action: Action[action],
actionModifier: actionModifier,
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
appInsights.trackEvent({ name: Action[action] }, getData(actionModifier, data));
appInsights.trackEvent({ name: Action[action] }, decorateData(data, actionModifier));
}
export function traceStart(action: Action, data?: TelemetryData): number {
@@ -33,7 +75,7 @@ export function traceStart(action: Action, data?: TelemetryData): number {
action: Action[action],
actionModifier: ActionModifiers.Start,
timestamp: timestamp,
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
@@ -48,11 +90,11 @@ export function traceSuccess(action: Action, data?: TelemetryData, timestamp?: n
action: Action[action],
actionModifier: ActionModifiers.Success,
timestamp: timestamp || Date.now(),
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
appInsights.stopTrackEvent(Action[action], getData(ActionModifiers.Success, data));
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Success));
}
export function traceFailure(action: Action, data?: TelemetryData, timestamp?: number): void {
@@ -62,11 +104,11 @@ export function traceFailure(action: Action, data?: TelemetryData, timestamp?: n
action: Action[action],
actionModifier: ActionModifiers.Failed,
timestamp: timestamp || Date.now(),
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
appInsights.stopTrackEvent(Action[action], getData(ActionModifiers.Failed, data));
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Failed));
}
export function traceCancel(action: Action, data?: TelemetryData, timestamp?: number): void {
@@ -76,11 +118,11 @@ export function traceCancel(action: Action, data?: TelemetryData, timestamp?: nu
action: Action[action],
actionModifier: ActionModifiers.Cancel,
timestamp: timestamp || Date.now(),
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
appInsights.stopTrackEvent(Action[action], getData(ActionModifiers.Cancel, data));
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Cancel));
}
export function traceOpen(action: Action, data?: TelemetryData, timestamp?: number): number {
@@ -91,7 +133,7 @@ export function traceOpen(action: Action, data?: TelemetryData, timestamp?: numb
action: Action[action],
actionModifier: ActionModifiers.Open,
timestamp: validTimestamp,
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
@@ -107,7 +149,7 @@ export function traceMark(action: Action, data?: TelemetryData, timestamp?: numb
action: Action[action],
actionModifier: ActionModifiers.Mark,
timestamp: validTimestamp,
data: JSON.stringify(data),
data: JSON.stringify(decorateData(data)),
},
});
@@ -115,16 +157,15 @@ export function traceMark(action: Action, data?: TelemetryData, timestamp?: numb
return validTimestamp;
}
function getData(actionModifier: string, data: TelemetryData = {}): { [key: string]: string } {
const dataExplorerWindow = getDataExplorerWindow(window);
function decorateData(data: TelemetryData = {}, actionModifier?: string) {
return {
// TODO: Need to `any` here since the window imports Explorer which can't be in strict mode yet
// eslint-disable-next-line @typescript-eslint/no-explicit-any
authType: dataExplorerWindow && (dataExplorerWindow as any).authType,
subscriptionId: userContext.subscriptionId as string,
databaseAccountName: userContext.databaseAccount?.name,
defaultExperience: userContext.defaultExperience,
authType: userContext.authType,
subscriptionId: userContext.subscriptionId,
platform: configContext.platform,
env: process.env.NODE_ENV as string,
env: process.env.NODE_ENV,
actionModifier,
...data,
};
} as { [key: string]: string };
}