Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/performance/browser/startupTimings.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js';
7
import { ILifecycleService, StartupKind, StartupKindToString } from '../../../services/lifecycle/common/lifecycle.js';
8
import { IUpdateService } from '../../../../platform/update/common/update.js';
9
import * as files from '../../files/common/files.js';
10
import { IEditorService } from '../../../services/editor/common/editorService.js';
11
import { IWorkspaceTrustManagementService } from '../../../../platform/workspace/common/workspaceTrust.js';
12
import { IPaneCompositePartService } from '../../../services/panecomposite/browser/panecomposite.js';
13
import { ViewContainerLocation } from '../../../common/views.js';
14
import { ILogService } from '../../../../platform/log/common/log.js';
15
import { IProductService } from '../../../../platform/product/common/productService.js';
16
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
17
import { IBrowserWorkbenchEnvironmentService } from '../../../services/environment/browser/environmentService.js';
18
import { ITimerService } from '../../../services/timer/browser/timerService.js';
19
import { IWorkbenchContribution } from '../../../common/contributions.js';
20
import { posix } from '../../../../base/common/path.js';
21
import { hash } from '../../../../base/common/hash.js';
22
23
export abstract class StartupTimings {
24
25
constructor(
26
@IEditorService private readonly _editorService: IEditorService,
27
@IPaneCompositePartService private readonly _paneCompositeService: IPaneCompositePartService,
28
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
29
@IUpdateService private readonly _updateService: IUpdateService,
30
@IWorkspaceTrustManagementService private readonly _workspaceTrustService: IWorkspaceTrustManagementService
31
) {
32
}
33
34
protected async _isStandardStartup(): Promise<string | undefined> {
35
// check for standard startup:
36
// * new window (no reload)
37
// * workspace is trusted
38
// * just one window
39
// * explorer viewlet visible
40
// * one text editor (not multiple, not webview, welcome etc...)
41
// * cached data present (not rejected, not created)
42
if (this._lifecycleService.startupKind !== StartupKind.NewWindow) {
43
return StartupKindToString(this._lifecycleService.startupKind);
44
}
45
if (!this._workspaceTrustService.isWorkspaceTrusted()) {
46
return 'Workspace not trusted';
47
}
48
const activeViewlet = this._paneCompositeService.getActivePaneComposite(ViewContainerLocation.Sidebar);
49
if (!activeViewlet || activeViewlet.getId() !== files.VIEWLET_ID) {
50
return 'Explorer viewlet not visible';
51
}
52
const visibleEditorPanes = this._editorService.visibleEditorPanes;
53
if (visibleEditorPanes.length !== 1) {
54
return `Expected text editor count : 1, Actual : ${visibleEditorPanes.length}`;
55
}
56
if (!isCodeEditor(visibleEditorPanes[0].getControl())) {
57
return 'Active editor is not a text editor';
58
}
59
const activePanel = this._paneCompositeService.getActivePaneComposite(ViewContainerLocation.Panel);
60
if (activePanel) {
61
return `Current active panel : ${this._paneCompositeService.getPaneComposite(activePanel.getId(), ViewContainerLocation.Panel)?.name}`;
62
}
63
const isLatestVersion = await this._updateService.isLatestVersion();
64
if (isLatestVersion === false) {
65
return 'Not on latest version, updates available';
66
}
67
return undefined;
68
}
69
}
70
71
export class BrowserStartupTimings extends StartupTimings implements IWorkbenchContribution {
72
73
constructor(
74
@IEditorService editorService: IEditorService,
75
@IPaneCompositePartService paneCompositeService: IPaneCompositePartService,
76
@ILifecycleService lifecycleService: ILifecycleService,
77
@IUpdateService updateService: IUpdateService,
78
@IWorkspaceTrustManagementService workspaceTrustService: IWorkspaceTrustManagementService,
79
@ITimerService private readonly timerService: ITimerService,
80
@ILogService private readonly logService: ILogService,
81
@IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
82
@ITelemetryService private readonly telemetryService: ITelemetryService,
83
@IProductService private readonly productService: IProductService
84
) {
85
super(editorService, paneCompositeService, lifecycleService, updateService, workspaceTrustService);
86
87
this.logPerfMarks();
88
}
89
90
private async logPerfMarks(): Promise<void> {
91
if (!this.environmentService.profDurationMarkers) {
92
return;
93
}
94
95
await this.timerService.whenReady();
96
97
const standardStartupError = await this._isStandardStartup();
98
const perfBaseline = await this.timerService.perfBaseline;
99
const [from, to] = this.environmentService.profDurationMarkers;
100
const content = `${this.timerService.getDuration(from, to)}\t${this.productService.nameShort}\t${(this.productService.commit || '').slice(0, 10) || '0000000000'}\t${this.telemetryService.sessionId}\t${standardStartupError === undefined ? 'standard_start' : 'NO_standard_start : ' + standardStartupError}\t${String(perfBaseline).padStart(4, '0')}ms\n`;
101
102
this.logService.info(`[prof-timers] ${content}`);
103
}
104
}
105
106
export class BrowserResourcePerformanceMarks {
107
108
constructor(
109
@ITelemetryService telemetryService: ITelemetryService
110
) {
111
112
type Entry = {
113
hosthash: string;
114
name: string;
115
duration: number;
116
};
117
type EntryClassifify = {
118
owner: 'jrieken';
119
comment: 'Resource performance numbers';
120
hosthash: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Hash of the hostname' };
121
name: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Resource basename' };
122
duration: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Resource duration' };
123
};
124
for (const item of performance.getEntriesByType('resource')) {
125
126
try {
127
const url = new URL(item.name);
128
const name = posix.basename(url.pathname);
129
130
telemetryService.publicLog2<Entry, EntryClassifify>('startup.resource.perf', {
131
hosthash: `H${hash(url.host).toString(16)}`,
132
name,
133
duration: item.duration
134
});
135
} catch {
136
// ignore
137
}
138
}
139
}
140
}
141
142