[MM-60086][MM-60610] Implement performanceMonitor, collect CPU/memory usage data and send via API (#3165)

* [MM-60086][MM-60610] Implement performanceMonitor, collect CPU/memory usage data and send via API

* Translations

* PR feedback

* Update api-types package
This commit is contained in:
Devin Binnie
2024-10-18 10:13:39 -04:00
committed by GitHub
parent 9d52ee7f41
commit 10295162e0
38 changed files with 590 additions and 6 deletions

View File

@@ -62,6 +62,11 @@ jest.mock('../utils', () => ({
jest.mock('main/developerMode', () => ({
get: jest.fn(),
}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
registerServerView: jest.fn(),
unregisterView: jest.fn(),
}));
const server = new MattermostServer({name: 'server_name', url: 'http://server-1.com'});
const view = new MessagingView(server, true);

View File

@@ -23,8 +23,9 @@ import type {Logger} from 'common/log';
import ServerManager from 'common/servers/serverManager';
import {RELOAD_INTERVAL, MAX_SERVER_RETRIES, SECOND, MAX_LOADING_SCREEN_SECONDS} from 'common/utils/constants';
import {isInternalURL, parseURL} from 'common/utils/url';
import type {MattermostView} from 'common/views/View';
import {TAB_MESSAGING, type MattermostView} from 'common/views/View';
import DeveloperMode from 'main/developerMode';
import performanceMonitor from 'main/performanceMonitor';
import {getServerAPI} from 'main/server/serverAPI';
import MainWindow from 'main/windows/mainWindow';
@@ -196,6 +197,11 @@ export class MattermostBrowserView extends EventEmitter {
loadURL = this.view.url.toString();
}
this.log.verbose(`Loading ${loadURL}`);
if (this.view.type === TAB_MESSAGING) {
performanceMonitor.registerServerView(`Server ${this.browserView.webContents.id}`, this.browserView.webContents, this.view.server.id);
} else {
performanceMonitor.registerView(`Server ${this.browserView.webContents.id}`, this.browserView.webContents, this.view.server.id);
}
const loading = this.browserView.webContents.loadURL(loadURL, {userAgent: composeUserAgent(DeveloperMode.get('browserOnly'))});
loading.then(this.loadSuccess(loadURL)).catch((err) => {
if (err.code && err.code.startsWith('ERR_CERT')) {
@@ -262,6 +268,7 @@ export class MattermostBrowserView extends EventEmitter {
WebContentsEventManager.removeWebContentsListeners(this.webContentsId);
AppState.clear(this.id);
MainWindow.get()?.removeBrowserView(this.browserView);
performanceMonitor.unregisterView(this.browserView.webContents.id);
this.browserView.webContents.close();
this.isVisible = false;

View File

@@ -52,6 +52,9 @@ jest.mock('macos-notification-state', () => ({
getDoNotDisturb: jest.fn(),
}));
jest.mock('main/downloadsManager', () => ({}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
}));
jest.mock('main/windows/mainWindow', () => ({
on: jest.fn(),
get: jest.fn(),

View File

@@ -27,6 +27,7 @@ import {
TAB_BAR_HEIGHT,
} from 'common/utils/constants';
import downloadsManager from 'main/downloadsManager';
import performanceMonitor from 'main/performanceMonitor';
import {getLocalPreload} from 'main/utils';
import MainWindow from 'main/windows/mainWindow';
@@ -75,6 +76,7 @@ export class DownloadsDropdownMenuView {
// @ts-ignore
transparent: true,
}});
performanceMonitor.registerView('DownloadsDropdownMenuView', this.view.webContents);
this.view.webContents.loadURL('mattermost-desktop://renderer/downloadsDropdownMenu.html');
MainWindow.get()?.addBrowserView(this.view);
};

View File

@@ -65,6 +65,9 @@ jest.mock('main/downloadsManager', () => ({
onOpen: jest.fn(),
onClose: jest.fn(),
}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
}));
jest.mock('main/windows/mainWindow', () => ({
on: jest.fn(),
get: jest.fn(),

View File

@@ -21,6 +21,7 @@ import Config from 'common/config';
import {Logger} from 'common/log';
import {TAB_BAR_HEIGHT, DOWNLOADS_DROPDOWN_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT, DOWNLOADS_DROPDOWN_FULL_WIDTH} from 'common/utils/constants';
import downloadsManager from 'main/downloadsManager';
import performanceMonitor from 'main/performanceMonitor';
import {getLocalPreload} from 'main/utils';
import MainWindow from 'main/windows/mainWindow';
@@ -65,6 +66,7 @@ export class DownloadsDropdownView {
transparent: true,
}});
performanceMonitor.registerView('DownloadsDropdownView', this.view.webContents);
this.view.webContents.loadURL('mattermost-desktop://renderer/downloadsDropdown.html');
MainWindow.get()?.addBrowserView(this.view);
};

View File

@@ -10,7 +10,9 @@ jest.mock('electron', () => ({
on: jest.fn(),
},
}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
}));
jest.mock('main/windows/mainWindow', () => ({
get: jest.fn(),
on: jest.fn(),

View File

@@ -5,6 +5,7 @@ import {BrowserView, app, ipcMain} from 'electron';
import {DARK_MODE_CHANGE, LOADING_SCREEN_ANIMATION_FINISHED, MAIN_WINDOW_RESIZED, TOGGLE_LOADING_SCREEN_VISIBILITY} from 'common/communication';
import {Logger} from 'common/log';
import performanceMonitor from 'main/performanceMonitor';
import {getLocalPreload, getWindowBoundaries} from 'main/utils';
import MainWindow from 'main/windows/mainWindow';
@@ -86,6 +87,8 @@ export class LoadingScreen {
transparent: true,
}});
const localURL = 'mattermost-desktop://renderer/loadingScreen.html';
performanceMonitor.registerView('LoadingScreen', this.view.webContents);
this.view.webContents.loadURL(localURL);
};

View File

@@ -27,6 +27,10 @@ jest.mock('../contextMenu', () => jest.fn());
jest.mock('../utils', () => ({
getWindowBoundaries: jest.fn(),
}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
unregisterView: jest.fn(),
}));
describe('main/views/modalView', () => {
describe('show', () => {

View File

@@ -5,6 +5,7 @@ import type {BrowserWindow} from 'electron';
import {BrowserView} from 'electron';
import {Logger} from 'common/log';
import performanceMonitor from 'main/performanceMonitor';
import ContextMenu from '../contextMenu';
import {getWindowBoundaries} from '../utils';
@@ -50,6 +51,7 @@ export class ModalView<T, T2> {
this.status = Status.ACTIVE;
try {
performanceMonitor.registerView(`Modal-${key}`, this.view.webContents);
this.view.webContents.loadURL(this.html);
} catch (e) {
this.log.error('there was an error loading the modal:');
@@ -99,6 +101,7 @@ export class ModalView<T, T2> {
this.view.webContents.closeDevTools();
}
this.windowAttached.removeBrowserView(this.view);
performanceMonitor.unregisterView(this.view.webContents.id);
this.view.webContents.close();
delete this.windowAttached;

View File

@@ -29,6 +29,9 @@ jest.mock('electron', () => ({
getPath: jest.fn(() => '/valid/downloads/path'),
},
}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
}));
jest.mock('main/windows/mainWindow', () => ({
on: jest.fn(),
get: jest.fn(),

View File

@@ -22,6 +22,7 @@ import Config from 'common/config';
import {Logger} from 'common/log';
import ServerManager from 'common/servers/serverManager';
import {TAB_BAR_HEIGHT, THREE_DOT_MENU_WIDTH, THREE_DOT_MENU_WIDTH_MAC, MENU_SHADOW_WIDTH} from 'common/utils/constants';
import performanceMonitor from 'main/performanceMonitor';
import {getLocalPreload} from 'main/utils';
import type {UniqueServer} from 'types/config';
@@ -83,6 +84,7 @@ export class ServerDropdownView {
// @ts-ignore
transparent: true,
}});
performanceMonitor.registerView('ServerDropdownView', this.view.webContents);
this.view.webContents.loadURL('mattermost-desktop://renderer/dropdown.html');
this.setOrderedServers();

View File

@@ -82,6 +82,9 @@ jest.mock('main/windows/mainWindow', () => ({
get: jest.fn(),
on: jest.fn(),
}));
jest.mock('main/performanceMonitor', () => ({
registerView: jest.fn(),
}));
jest.mock('common/servers/serverManager', () => ({
getOrderedTabsForServer: jest.fn(),
getAllServers: jest.fn(),

View File

@@ -48,6 +48,7 @@ import {TAB_MESSAGING} from 'common/views/View';
import {flushCookiesStore} from 'main/app/utils';
import DeveloperMode from 'main/developerMode';
import {localizeMessage} from 'main/i18nManager';
import performanceMonitor from 'main/performanceMonitor';
import PermissionsManager from 'main/permissionsManager';
import MainWindow from 'main/windows/mainWindow';
@@ -373,6 +374,7 @@ export class ViewManager {
transparent: true,
}});
const localURL = `mattermost-desktop://renderer/urlView.html?url=${encodeURIComponent(urlString)}`;
performanceMonitor.registerView('URLView', urlView.webContents);
urlView.webContents.loadURL(localURL);
MainWindow.get()?.addBrowserView(urlView);
const boundaries = this.views.get(this.currentView || '')?.getBounds() ?? MainWindow.getBounds();
@@ -385,6 +387,7 @@ export class ViewManager {
log.error('Failed to remove URL view', e);
}
performanceMonitor.unregisterView(urlView.webContents.id);
urlView.webContents.close();
};