Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tools/chrome-debug-extension/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Application Insights Debug Viewer

## Breaking Changes from v0 to v1
With Chrome discontinuing support for Manifest v2, we’ve updated our extension from version v0 to v1 to align with Manifest v3. This update introduces several changes:

- Migration to Chrome Storage API: Manifest V3 no longer supports localStorage; instead, it uses the Chrome Storage API. Consequently, your existing configuration will not be automatically transferred to the new version.

- New Extension Name: To ensure a smooth update experience, we’ve changed the extension’s name from Telemetry Viewer to Telemetry Viewer M3. This allows you to run both versions simultaneously and manually copy your settings from the old extension to the new one.


## What the tool does

This tool runs in your browser, either Chrome or Edge, and provides you real time visualization of events flowing through Application Insights. You can use it to monitor the telemetry that your web application is emitting as part of your dev inner loop or bug investigations, or you can use it to monitor the internal calls within Application Insights to debug your integration of Application Insights into your web application.
Expand Down
34 changes: 22 additions & 12 deletions tools/chrome-debug-extension/manifest.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
{
"name": "Telemetry Viewer",
"short_name": "Telemetry Viewer",
"name": "Telemetry Viewer - M3",
"short_name": "Telemetry Viewer M3",
"description": "A browser extension that provides a real time view of what's happening in Application Insights including what telemetry is being logged by the web application",
"version": "0.7.4",
"version_name": "0.7.4",
"manifest_version": 2,
"manifest_version": 3,
"icons": {
"16": "images/icon-16.png",
"128": "images/icon-128.png"
},
"permissions": [
"<all_urls>",
"system.display",
"storage",
"activeTab",
"webRequest"
"webRequest",
"scripting"
],
"background": {
"scripts": [
"scripts/background.js"
]
"service_worker": "./scripts/background.js"
},
"browser_action": {
"action": {
"default_icon": {
"19": "images/icon-19.png",
"38": "images/icon-38.png"
},
"default_title": "Telemetry Viewer"
},
"web_accessible_resources": [
"scripts/pageHelper.js",
"scripts/pageHelper.min.js",
"scripts/pageHelper.min.js.map"
{
"resources": [
"scripts/pageHelper.js",
"scripts/pageHelper.min.js",
"scripts/pageHelper.min.js.map"
],
"matches": [
"<all_urls>"
]
}
],
"content_scripts": [
{
Expand All @@ -40,5 +47,8 @@
"scripts/contentLoad.min.js"
]
}
],
"host_permissions": [
"<all_urls>"
]
}
1 change: 1 addition & 0 deletions tools/chrome-debug-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@microsoft/applicationinsights-common": "3.3.4",
"@microsoft/applicationinsights-shims": "3.0.1",
"@microsoft/dynamicproto-js": "^2.0.3",
"@nevware21/ts-async": ">= 0.5.2 < 2.x",
"@nevware21/ts-utils": ">= 0.11.3 < 2.x",
"file-saver": "^2.0.0",
"react": "^17.0.2",
Expand Down
165 changes: 86 additions & 79 deletions tools/chrome-debug-extension/src/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,24 @@ function getTabWindow(tabId?: number): chrome.windows.Window {
return null as any;
}

function injectScript(url: string) {
const d = document;
const s = d.createElement("script");
s.src = encodeURI(url);
const el = d.head || d.documentElement;
el.appendChild(s);
}

function injectPageHelper(tabId?: number) {
if (tabId) {
let url = chrome.runtime.getURL("scripts/pageHelper.min.js");
let theScript =
"var d=document,s=d.createElement('script');" +
"s.src='" + encodeURI(url) + "';" +
"var el=d.head||d.documentElement;" +
"el.appendChild(s);";

chrome.tabs.executeScript(tabId, {
code: theScript
}, _=>{
let e = chrome.runtime.lastError;
if(e !== undefined){
console.log(tabId, _, e);
chrome.scripting.executeScript({
target: { tabId },
func: injectScript,
args: [url]
}, (result) => {
if (chrome.runtime.lastError) {
console.log(`Error injecting script into tab ${tabId}:`, chrome.runtime.lastError);
}
});
}
Expand All @@ -49,78 +52,82 @@ function injectPageHelper(tabId?: number) {
function openPopup(tab: chrome.tabs.Tab) {
let settings = getPopupSettings();

chrome.windows.create({
url: "pages/popup.html?tabId=" + tab.id,
type: "popup",
focused: true,
width: Math.min(Math.max(settings.width || 0, 200), screen.width),
height: Math.min(Math.max(settings.height || 0, 320), screen.height)
}, (value) => {
setTabWindow(tab.id, value);
if (value) {
let popupId = value.id;

let _onResize = (win: chrome.windows.Window) => {
if (win.id === popupId) {
setPopupSize(win.width, win.height);
chrome.system.display.getInfo((displays) => {
const primaryDisplay = displays[0]; // Typically, the primary display is the first in the list
const screenWidth = primaryDisplay.workArea.width;
const screenHeight = primaryDisplay.workArea.height;
chrome.windows.create({
url: "pages/popup.html?tabId=" + tab.id,
type: "popup",
focused: true,
width: Math.min(Math.max(settings.width || 0, 200), screenWidth),
height: Math.min(Math.max(settings.height || 0, 320), screenHeight)
}, (value) => {
setTabWindow(tab.id, value);
if (value) {
let popupId = value.id;

let _onResize = (win: chrome.windows.Window) => {
if (win.id === popupId) {
setPopupSize(win.width, win.height);
}
}
}

let _onRemove = (windowId: number) => {
if (popupId === windowId) {
setTabWindow(tab.id);
chrome.windows.onRemoved.removeListener(_onRemove);
chrome.windows.onBoundsChanged.removeListener(_onResize);

let _onRemove = (windowId: number) => {
if (popupId === windowId) {
setTabWindow(tab.id);
chrome.windows.onRemoved.removeListener(_onRemove);
chrome.windows.onBoundsChanged.removeListener(_onResize);
}
}

// Track popup window size
chrome.windows.onBoundsChanged.addListener(_onResize);

// track popup window
chrome.windows.onRemoved.addListener(_onRemove);
}

// Track popup window size
chrome.windows.onBoundsChanged.addListener(_onResize);

// track popup window
chrome.windows.onRemoved.addListener(_onRemove);
}
});
});
}

// Self running code
(() => {
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
let msg = message as IMessage;
if (msg.id === MessageType.ContentLoad && sender && sender.tab) {
if (objKeys(openTabs).length > 0) {
injectPageHelper(sender.tab.id);
}

}

sendResponse();
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
let msg = message as IMessage;
if (msg.id === MessageType.ContentLoad && sender && sender.tab) {
if (objKeys(openTabs).length > 0) {
injectPageHelper(sender.tab.id);
}
});

// Configure the browser action (the button next to the address bar registered in manifest.json) to
// open the popup when clicked.
chrome.browserAction.onClicked.addListener((tab) => {
if (tab && tab.id) {
// Inject the helper hook function
injectPageHelper(tab.id);

// Launch the popup
let w = getTabWindow(tab.id);
if (!w || !w.id) {
openPopup(tab);
} else {
chrome.windows.get(w.id, () => {
if (chrome.runtime.lastError) {
setTabWindow(tab.id);
openPopup(tab);
} else {
chrome.windows.update(w.id as number, { focused: true }, () => {
if (chrome.runtime.lastError) {
openPopup(tab);
}
});
}
});
}
sendResponse();
}
});

// Configure the browser action (the button next to the address bar registered in manifest.json) to
// open the popup when clicked.
chrome.action.onClicked.addListener((tab) => {
if (tab && tab.id) {
// Inject the helper hook function
injectPageHelper(tab.id);

// Launch the popup
let w = getTabWindow(tab.id);
if (!w || !w.id) {
openPopup(tab);
} else {
chrome.windows.get(w.id, () => {
if (chrome.runtime.lastError) {
setTabWindow(tab.id);
openPopup(tab);
} else {
chrome.windows.update(w.id as number, { focused: true }, () => {
if (chrome.runtime.lastError) {
openPopup(tab);
}
});
}
});
}
});
})();
}
});

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from "react";
import { getConfiguration } from "../configuration/configuration";
import { ConfigurationType, ConfigurationURLs } from "../configuration/Configuration.types";
import { IConfiguration } from "../configuration/IConfiguration";
import { doAwait } from "@nevware21/ts-async";

export const customConfigurationStorageKey = "customConfiguration";
export interface IConfigurationSelectionProps {
Expand Down Expand Up @@ -45,7 +46,8 @@ export const ConfigurationSelection = (
function updateCustomConfiguration(newCustomConfiguration: string): void {
setCustomConfigurationDirty(true);
setCustomConfiguration(newCustomConfiguration);
localStorage.setItem(customConfigurationStorageKey, newCustomConfiguration);
chrome.storage.local.set({ customConfigurationStorageKey: newCustomConfiguration });

}

function onCopyToCustomConfiguration(): void {
Expand All @@ -64,16 +66,19 @@ export const ConfigurationSelection = (

React.useEffect(() => {
try {
const savedValue = localStorage.getItem(customConfigurationStorageKey);
if (savedValue) {
setCustomConfiguration(savedValue);
}
doAwait(chrome.storage.local.get(customConfigurationStorageKey), (savedValue: any) => {
if (savedValue) {
setCustomConfiguration(savedValue);
}
if (textAreaRef.current) {
textAreaRef.current.setAttribute("aria-labelledby", "customConfigurationLabel");
}
});

} catch {
// That's OK
}
if (textAreaRef.current) {
textAreaRef.current.setAttribute("aria-labelledby", "customConfigurationLabel");
}

}, []);

const isCustomConfigurationTextareaReadonly = unsavedConfigurationType !== "Custom";
Expand Down
24 changes: 13 additions & 11 deletions tools/chrome-debug-extension/src/components/telemetryViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { EventTable } from "./eventTable";
import { IFilterSettings } from "./IFilterSettings";
import { OptionsBar } from "./optionsBar";
import { SplitPanel } from "./splitPanel";
import { doAwait } from "@nevware21/ts-async";

interface ITelemetryViewerProps {
session: Session;
Expand Down Expand Up @@ -38,7 +39,7 @@ export const TelemetryViewer = (props: ITelemetryViewerProps): React.ReactElemen

const handleNewFilterSettings = (newFilterSettings: IFilterSettings): void => {
try {
localStorage.setItem(filterSettingsCacheKey, JSON.stringify(newFilterSettings));
chrome.storage.local.set({ filterSettingsCacheKey: JSON.stringify(newFilterSettings) });
} catch {
// Default is OK
}
Expand Down Expand Up @@ -110,16 +111,17 @@ export const TelemetryViewer = (props: ITelemetryViewerProps): React.ReactElemen

React.useEffect(() => {
try {
const json = localStorage.getItem(filterSettingsCacheKey);
if (json) {
// Make sure we have any defaults set
let settings: IFilterSettings = {
...getDefaultFilterSettings(props.session.configuration),
...(JSON.parse(json))
};

setFilterSettings(settings);
}
doAwait(chrome.storage.local.get(filterSettingsCacheKey), (json: any) => {
if (json) {
// Make sure we have any defaults set
let settings: IFilterSettings = {
...getDefaultFilterSettings(props.session.configuration),
...(JSON.parse(json))
};

setFilterSettings(settings);
}
});
} catch {
// Default is OK
}
Expand Down
Loading
Loading