Add telemetry for OpenTerminal (#200)

This commit is contained in:
Tanuj Mittal 2020-09-16 17:04:34 -07:00 committed by GitHub
parent 03b19fc875
commit 34c41e1557
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 19 deletions

View File

@ -1,6 +1,5 @@
import Q from "q"; import Q from "q";
import * as MessageHandler from "./MessageHandler"; import * as MessageHandler from "./MessageHandler";
import { MessageTypes } from "../Contracts/ExplorerContracts";
describe("Message Handler", () => { describe("Message Handler", () => {
it("should handle cached message", async () => { it("should handle cached message", async () => {
@ -26,4 +25,34 @@ describe("Message Handler", () => {
MessageHandler.runGarbageCollector(); MessageHandler.runGarbageCollector();
expect(MessageHandler.RequestMap["123"]).toBeUndefined(); expect(MessageHandler.RequestMap["123"]).toBeUndefined();
}); });
describe("getDataExplorerWindow", () => {
it("should return current window if current window has dataExplorerPlatform property", () => {
const currentWindow: Window = { dataExplorerPlatform: 0 } as any;
expect(MessageHandler.getDataExplorerWindow(currentWindow)).toEqual(currentWindow);
});
it("should return current window's parent if current window's parent has dataExplorerPlatform property", () => {
const parentWindow: Window = { dataExplorerPlatform: 0 } as any;
const currentWindow: Window = { parent: parentWindow } as any;
expect(MessageHandler.getDataExplorerWindow(currentWindow)).toEqual(parentWindow);
});
it("should return undefined if none of the windows in the hierarchy have dataExplorerPlatform property and window's parent is reference to itself", () => {
const parentWindow: Window = {} as any;
(parentWindow as any).parent = parentWindow; // If a window does not have a parent, its parent property is a reference to itself.
const currentWindow: Window = { parent: parentWindow } as any;
expect(MessageHandler.getDataExplorerWindow(currentWindow)).toBeUndefined();
});
it("should return undefined if none of the windows in the hierarchy have dataExplorerPlatform property and window's parent is not defined", () => {
const parentWindow: Window = {} as any;
const currentWindow: Window = { parent: parentWindow } as any;
expect(MessageHandler.getDataExplorerWindow(currentWindow)).toBeUndefined();
});
});
}); });

View File

@ -48,16 +48,38 @@ export function sendCachedDataMessage<TResponseDataModel>(
export function sendMessage(data: any): void { export function sendMessage(data: any): void {
if (canSendMessage()) { if (canSendMessage()) {
window.parent.postMessage( const dataExplorerWindow = getDataExplorerWindow(window);
{ if (dataExplorerWindow) {
signature: "pcIframe", dataExplorerWindow.parent.postMessage(
data: data {
}, signature: "pcIframe",
window.document.referrer data: data
); },
dataExplorerWindow.document.referrer
);
}
} }
} }
// Only exported for unit tests
export const getDataExplorerWindow = (currentWindow: Window): Window | undefined => {
// Start with the current window and traverse up the parent hierarchy to find a window
// with `dataExplorerPlatform` property
let dataExplorerWindow: Window | undefined = currentWindow;
// 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
while (dataExplorerWindow && (dataExplorerWindow as any).dataExplorerPlatform == undefined) {
// If a window does not have a parent, its parent property is a reference to itself.
if (dataExplorerWindow.parent == dataExplorerWindow) {
dataExplorerWindow = undefined;
} else {
dataExplorerWindow = dataExplorerWindow.parent;
}
}
return dataExplorerWindow;
};
export function canSendMessage(): boolean { export function canSendMessage(): boolean {
return window.parent !== window; return window.parent !== window;
} }

View File

@ -70,7 +70,8 @@ export enum Action {
NotebooksGitHubManualRepoAdd, NotebooksGitHubManualRepoAdd,
NotebooksGitHubManageRepo, NotebooksGitHubManageRepo,
NotebooksGitHubCommit, NotebooksGitHubCommit,
NotebooksGitHubDisconnect NotebooksGitHubDisconnect,
OpenTerminal
} }
export const ActionModifiers = { export const ActionModifiers = {

View File

@ -4,6 +4,8 @@ import "@jupyterlab/terminal/style/index.css";
import "./index.css"; import "./index.css";
import { ServerConnection } from "@jupyterlab/services"; import { ServerConnection } from "@jupyterlab/services";
import { JupyterLabAppFactory } from "./JupyterLabAppFactory"; import { JupyterLabAppFactory } from "./JupyterLabAppFactory";
import { Action } from "../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
const getUrlVars = (): { [key: string]: string } => { const getUrlVars = (): { [key: string]: string } => {
const vars: { [key: string]: string } = {}; const vars: { [key: string]: string } = {};
@ -14,10 +16,7 @@ const getUrlVars = (): { [key: string]: string } => {
return vars; return vars;
}; };
const main = (): void => { const createServerSettings = (urlVars: { [key: string]: string }): ServerConnection.ISettings => {
const urlVars = getUrlVars();
console.log("URL parameters", urlVars);
let body: BodyInit; let body: BodyInit;
if (urlVars.hasOwnProperty("terminalEndpoint")) { if (urlVars.hasOwnProperty("terminalEndpoint")) {
body = JSON.stringify({ body = JSON.stringify({
@ -39,14 +38,29 @@ const main = (): void => {
fetch: window.parent.fetch fetch: window.parent.fetch
}; };
} }
const serverSettings = ServerConnection.makeSettings(options);
if (urlVars.hasOwnProperty("terminal")) { return ServerConnection.makeSettings(options);
JupyterLabAppFactory.createTerminalApp(serverSettings); };
return;
const main = async (): Promise<void> => {
const urlVars = getUrlVars();
const serverSettings = createServerSettings(urlVars);
const startTime = TelemetryProcessor.traceStart(Action.OpenTerminal, {
baseUrl: serverSettings.baseUrl
});
try {
if (urlVars.hasOwnProperty("terminal")) {
await JupyterLabAppFactory.createTerminalApp(serverSettings);
} else {
throw new Error("Only terminal is supported");
}
TelemetryProcessor.traceSuccess(Action.OpenTerminal, startTime);
} catch (error) {
TelemetryProcessor.traceFailure(Action.OpenTerminal, startTime);
} }
throw new Error("Only terminal is supported");
}; };
window.addEventListener("load", main); window.addEventListener("load", main);