Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add instrumentation support to the typescript code #12991

Merged
merged 31 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2c3dcd4
add instrumentation support to the typescript code
fearthecowboy Nov 22, 2024
8db9949
fix linter
fearthecowboy Nov 22, 2024
ad614bf
missed file
fearthecowboy Nov 25, 2024
1b3c84e
update to a newer image?
fearthecowboy Nov 25, 2024
73abb77
Merge branch 'main' into dev/garretts/instrumentation
fearthecowboy Nov 25, 2024
47f172e
merged from main
fearthecowboy Dec 3, 2024
8c6e727
merged
fearthecowboy Dec 3, 2024
ad53e59
Merge branch 'dev/garretts/instrumentation' of https://github.com/mic…
fearthecowboy Dec 3, 2024
53dd899
work around webpack
fearthecowboy Jan 3, 2025
c5d8af4
webpack! Arg!
fearthecowboy Jan 3, 2025
35172cb
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy Jan 14, 2025
fbb07e6
cleanup
fearthecowboy Jan 15, 2025
d272d97
cleanups
fearthecowboy Jan 15, 2025
9a22dc2
remove spaces
fearthecowboy Jan 15, 2025
b147b2b
must use eval to work around webpack
fearthecowboy Jan 15, 2025
86c26c1
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy Jan 17, 2025
2b87424
need vscode in here
fearthecowboy Feb 6, 2025
9270034
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy Feb 6, 2025
30044a4
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy Feb 10, 2025
b016317
fix line endings?
fearthecowboy Feb 10, 2025
4c206b2
fix line endings?
fearthecowboy Feb 10, 2025
d71e4fb
Add comment
fearthecowboy Feb 10, 2025
9d09405
Merge branch 'main' of https://github.com/microsoft/vscode-cpptools i…
fearthecowboy Feb 12, 2025
0a2c368
Merge branch 'dev/garretts/instrumentation' of https://github.com/mic…
fearthecowboy Feb 12, 2025
fe6a369
Added instrumentation to copilothoverprovider
fearthecowboy Feb 14, 2025
249f93e
Merge branch 'main' into dev/garretts/instrumentation
fearthecowboy Feb 14, 2025
0823147
inject instrumentation code via perfecto instead
fearthecowboy Feb 15, 2025
20749be
Merge branch 'dev/garretts/instrumentation' of https://github.com/mic…
fearthecowboy Feb 15, 2025
d2adad4
Merge branch 'main' into dev/garretts/instrumentation
fearthecowboy Feb 26, 2025
b0a4968
Ensure that everything is instrumented where we can.
fearthecowboy Feb 26, 2025
a4d3760
extra comma
fearthecowboy Feb 26, 2025
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
9 changes: 5 additions & 4 deletions Extension/src/Debugger/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { TargetLeafNode, setActiveSshTarget } from '../SSH/TargetsView/targetNod
import { sshCommandToConfig } from '../SSH/sshCommandToConfig';
import { getSshConfiguration, getSshConfigurationFiles, parseFailures, writeSshConfiguration } from '../SSH/sshHosts';
import { pathAccessible } from '../common';
import { instrument } from '../instrumentation';
import { getSshChannel } from '../logger';
import { AttachItemsProvider, AttachPicker, RemoteAttachPicker } from './attachToProcess';
import { ConfigurationAssetProviderFactory, ConfigurationSnippetProvider, DebugConfigurationProvider, IConfigurationAssetProvider } from './configurationProvider';
Expand Down Expand Up @@ -46,10 +47,10 @@ export async function initialize(context: vscode.ExtensionContext): Promise<void
let cppVsDebugProvider: DebugConfigurationProvider | null = null;
if (os.platform() === 'win32') {
cppVsDebugProvider = new DebugConfigurationProvider(assetProvider, DebuggerType.cppvsdbg);
disposables.push(vscode.debug.registerDebugConfigurationProvider(DebuggerType.cppvsdbg, cppVsDebugProvider, vscode.DebugConfigurationProviderTriggerKind.Dynamic));
disposables.push(vscode.debug.registerDebugConfigurationProvider(DebuggerType.cppvsdbg, instrument(cppVsDebugProvider), vscode.DebugConfigurationProviderTriggerKind.Dynamic));
}
const cppDebugProvider: DebugConfigurationProvider = new DebugConfigurationProvider(assetProvider, DebuggerType.cppdbg);
disposables.push(vscode.debug.registerDebugConfigurationProvider(DebuggerType.cppdbg, cppDebugProvider, vscode.DebugConfigurationProviderTriggerKind.Dynamic));
disposables.push(vscode.debug.registerDebugConfigurationProvider(DebuggerType.cppdbg, instrument(cppDebugProvider), vscode.DebugConfigurationProviderTriggerKind.Dynamic));

// Register DebugConfigurationProviders for "Run and Debug" play button.
const debugProvider: DebugConfigurationProvider = new DebugConfigurationProvider(assetProvider, DebuggerType.all);
Expand All @@ -75,7 +76,7 @@ export async function initialize(context: vscode.ExtensionContext): Promise<void
}];

// ConfigurationSnippetProvider needs to be initiallized after configurationProvider calls getConfigurationSnippets.
disposables.push(vscode.languages.registerCompletionItemProvider(launchJsonDocumentSelector, new ConfigurationSnippetProvider(assetProvider)));
disposables.push(vscode.languages.registerCompletionItemProvider(launchJsonDocumentSelector, instrument(new ConfigurationSnippetProvider(assetProvider))));

// Register Debug Adapters
disposables.push(vscode.debug.registerDebugAdapterDescriptorFactory(DebuggerType.cppvsdbg, new CppvsdbgDebugAdapterDescriptorFactory(context)));
Expand All @@ -84,7 +85,7 @@ export async function initialize(context: vscode.ExtensionContext): Promise<void
// SSH Targets View
await initializeSshTargets();
const sshTargetsProvider: SshTargetsProvider = new SshTargetsProvider();
disposables.push(vscode.window.registerTreeDataProvider('CppSshTargetsView', sshTargetsProvider));
disposables.push(vscode.window.registerTreeDataProvider('CppSshTargetsView', instrument(sshTargetsProvider)));
disposables.push(vscode.commands.registerCommand(addSshTargetCmd, () => enableSshTargetsViewAndRun(addSshTargetImpl)));
disposables.push(vscode.commands.registerCommand('C_Cpp.removeSshTarget', (node?: BaseNode) => enableSshTargetsViewAndRun(removeSshTargetImpl, node)));
disposables.push(vscode.commands.registerCommand(refreshCppSshTargetsViewCmd, (node?: BaseNode) => enableSshTargetsViewAndRun((node?: BaseNode) => sshTargetsProvider.refresh(node), node)));
Expand Down
68 changes: 33 additions & 35 deletions Extension/src/LanguageServer/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { logAndReturn } from '../Utility/Async/returns';
import { is } from '../Utility/System/guards';
import * as util from '../common';
import { isWindows } from '../constants';
import { instrument, isInstrumentationEnabled } from '../instrumentation';
import { DebugProtocolParams, Logger, ShowWarningParams, getDiagnosticsChannel, getOutputChannelLogger, logDebugProtocol, logLocalized, showWarning } from '../logger';
import { localizedStringCount, lookupString } from '../nativeStrings';
import { SessionState } from '../sessionState';
Expand Down Expand Up @@ -840,6 +841,16 @@ export interface Client {
}

export function createClient(workspaceFolder?: vscode.WorkspaceFolder): Client {
if (isInstrumentationEnabled) {
instrument(vscode.languages, { name: "languages" });
instrument(vscode.window, { name: "window" });
instrument(vscode.workspace, { name: "workspace" });
instrument(vscode.commands, { name: "commands" });
instrument(vscode.debug, { name: "debug" });
instrument(vscode.env, { name: "env" });
instrument(vscode.extensions, { name: "extensions" });
return instrument(new DefaultClient(workspaceFolder), { ignore: ["enqueue", "onInterval", "logTelemetry"] });
}
return new DefaultClient(workspaceFolder);
}

Expand Down Expand Up @@ -1323,31 +1334,33 @@ export class DefaultClient implements Client {
this.currentCopilotHoverEnabled = new PersistentWorkspaceState<string>("cpp.copilotHover", settings.copilotHover);
if (settings.copilotHover !== "disabled") {
this.copilotHoverProvider = new CopilotHoverProvider(this);
this.disposables.push(vscode.languages.registerHoverProvider(util.documentSelector, this.copilotHoverProvider));
this.disposables.push(vscode.languages.registerHoverProvider(util.documentSelector, instrument(this.copilotHoverProvider)));
}

if (settings.copilotHover !== this.currentCopilotHoverEnabled.Value) {
this.currentCopilotHoverEnabled.Value = settings.copilotHover;
}
this.disposables.push(vscode.languages.registerHoverProvider(util.documentSelector, this.hoverProvider));
this.disposables.push(vscode.languages.registerInlayHintsProvider(util.documentSelector, this.inlayHintsProvider));
this.disposables.push(vscode.languages.registerRenameProvider(util.documentSelector, new RenameProvider(this)));
this.disposables.push(vscode.languages.registerReferenceProvider(util.documentSelector, new FindAllReferencesProvider(this)));
this.disposables.push(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(this)));
this.disposables.push(vscode.languages.registerDocumentSymbolProvider(util.documentSelector, new DocumentSymbolProvider(), undefined));
this.disposables.push(vscode.languages.registerCodeActionsProvider(util.documentSelector, new CodeActionProvider(this), undefined));
this.disposables.push(vscode.languages.registerCallHierarchyProvider(util.documentSelector, new CallHierarchyProvider(this)));
this.disposables.push(vscode.languages.registerHoverProvider(util.documentSelector, instrument(this.hoverProvider)));
this.disposables.push(vscode.languages.registerInlayHintsProvider(util.documentSelector, instrument(this.inlayHintsProvider)));
this.disposables.push(vscode.languages.registerRenameProvider(util.documentSelector, instrument(new RenameProvider(this))));
this.disposables.push(vscode.languages.registerReferenceProvider(util.documentSelector, instrument(new FindAllReferencesProvider(this))));
this.disposables.push(vscode.languages.registerWorkspaceSymbolProvider(instrument(new WorkspaceSymbolProvider(this))));
this.disposables.push(vscode.languages.registerDocumentSymbolProvider(util.documentSelector, instrument(new DocumentSymbolProvider()), undefined));
this.disposables.push(vscode.languages.registerCodeActionsProvider(util.documentSelector, instrument(new CodeActionProvider(this)), undefined));
this.disposables.push(vscode.languages.registerCallHierarchyProvider(util.documentSelector, instrument(new CallHierarchyProvider(this))));

// Because formatting and codeFolding can vary per folder, we need to register these providers once
// and leave them registered. The decision of whether to provide results needs to be made on a per folder basis,
// within the providers themselves.
this.documentFormattingProviderDisposable = vscode.languages.registerDocumentFormattingEditProvider(util.documentSelector, new DocumentFormattingEditProvider(this));
this.formattingRangeProviderDisposable = vscode.languages.registerDocumentRangeFormattingEditProvider(util.documentSelector, new DocumentRangeFormattingEditProvider(this));
this.onTypeFormattingProviderDisposable = vscode.languages.registerOnTypeFormattingEditProvider(util.documentSelector, new OnTypeFormattingEditProvider(this), ";", "}", "\n");
this.documentFormattingProviderDisposable = vscode.languages.registerDocumentFormattingEditProvider(util.documentSelector, instrument(new DocumentFormattingEditProvider(this)));
this.formattingRangeProviderDisposable = vscode.languages.registerDocumentRangeFormattingEditProvider(util.documentSelector, instrument(new DocumentRangeFormattingEditProvider(this)));
this.onTypeFormattingProviderDisposable = vscode.languages.registerOnTypeFormattingEditProvider(util.documentSelector, instrument(new OnTypeFormattingEditProvider(this)), ";", "}", "\n");

this.codeFoldingProvider = new FoldingRangeProvider(this);
this.codeFoldingProviderDisposable = vscode.languages.registerFoldingRangeProvider(util.documentSelector, this.codeFoldingProvider);
this.codeFoldingProviderDisposable = vscode.languages.registerFoldingRangeProvider(util.documentSelector, instrument(this.codeFoldingProvider));

if (settings.isEnhancedColorizationEnabled && semanticTokensLegend) {
this.semanticTokensProvider = new SemanticTokensProvider();
this.semanticTokensProvider = instrument(new SemanticTokensProvider());
this.semanticTokensProviderDisposable = vscode.languages.registerDocumentSemanticTokensProvider(util.documentSelector, this.semanticTokensProvider, semanticTokensLegend);
}

Expand Down Expand Up @@ -1730,8 +1743,7 @@ export class DefaultClient implements Client {
const oldLoggingLevelLogged: boolean = this.loggingLevel > 1;
this.loggingLevel = util.getNumericLoggingLevel(changedSettings.loggingLevel);
if (oldLoggingLevelLogged || this.loggingLevel > 1) {
const out: Logger = getOutputChannelLogger();
out.appendLine(localize({ key: "loggingLevel.changed", comment: ["{0} is the setting name 'loggingLevel', {1} is a string value such as 'Debug'"] }, "{0} has changed to: {1}", "loggingLevel", changedSettings.loggingLevel));
getOutputChannelLogger().appendLine(localize({ key: "loggingLevel.changed", comment: ["{0} is the setting name 'loggingLevel', {1} is a string value such as 'Debug'"] }, "{0} has changed to: {1}", "loggingLevel", changedSettings.loggingLevel));
}
}
const settings: CppSettings = new CppSettings();
Expand Down Expand Up @@ -2746,12 +2758,7 @@ export class DefaultClient implements Client {
const status: IntelliSenseStatus = { status: Status.IntelliSenseCompiling };
testHook.updateStatus(status);
} else if (message.endsWith("IntelliSense done")) {
const settings: CppSettings = new CppSettings();
if (util.getNumericLoggingLevel(settings.loggingLevel) >= 6) {
const out: Logger = getOutputChannelLogger();
const duration: number = Date.now() - timeStamp;
out.appendLine(localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", duration / 1000));
}
getOutputChannelLogger().appendLineAtLevel(6, localize("update.intellisense.time", "Update IntelliSense time (sec): {0}", (Date.now() - timeStamp) / 1000));
this.model.isUpdatingIntelliSense.Value = false;
const status: IntelliSenseStatus = { status: Status.IntelliSenseReady };
testHook.updateStatus(status);
Expand Down Expand Up @@ -3183,11 +3190,8 @@ export class DefaultClient implements Client {
return;
}

const settings: CppSettings = new CppSettings();
const out: Logger = getOutputChannelLogger();
if (util.getNumericLoggingLevel(settings.loggingLevel) >= 6) {
out.appendLine(localize("configurations.received", "Custom configurations received:"));
}
out.appendLineAtLevel(6, localize("configurations.received", "Custom configurations received:"));
const sanitized: SourceFileConfigurationItemAdapter[] = [];
configs.forEach(item => {
if (this.isSourceFileConfigurationItem(item, providerVersion)) {
Expand All @@ -3199,10 +3203,8 @@ export class DefaultClient implements Client {
uri = item.uri.toString();
}
this.configurationLogging.set(uri, JSON.stringify(item.configuration, null, 4));
if (util.getNumericLoggingLevel(settings.loggingLevel) >= 6) {
out.appendLine(` uri: ${uri}`);
out.appendLine(` config: ${JSON.stringify(item.configuration, null, 2)}`);
}
out.appendLineAtLevel(6, ` uri: ${uri}`);
out.appendLineAtLevel(6, ` config: ${JSON.stringify(item.configuration, null, 2)}`);
if (item.configuration.includePath.some(path => path.endsWith('**'))) {
console.warn("custom include paths should not use recursive includes ('**')");
}
Expand Down Expand Up @@ -3306,11 +3308,7 @@ export class DefaultClient implements Client {
return;
}

const settings: CppSettings = new CppSettings();
if (util.getNumericLoggingLevel(settings.loggingLevel) >= 6) {
const out: Logger = getOutputChannelLogger();
out.appendLine(localize("browse.configuration.received", "Custom browse configuration received: {0}", JSON.stringify(sanitized, null, 2)));
}
getOutputChannelLogger().appendLineAtLevel(6, localize("browse.configuration.received", "Custom browse configuration received: {0}", JSON.stringify(sanitized, null, 2)));

// Separate compiler path and args before sending to language client
if (util.isString(sanitized.compilerPath)) {
Expand Down
11 changes: 5 additions & 6 deletions Extension/src/LanguageServer/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as which from 'which';
import { logAndReturn } from '../Utility/Async/returns';
import * as util from '../common';
import { modelSelector } from '../constants';
import { instrument } from '../instrumentation';
import { getCrashCallStacksChannel } from '../logger';
import { PlatformInformation } from '../platform';
import * as telemetry from '../telemetry';
Expand Down Expand Up @@ -222,7 +223,7 @@ export async function activate(): Promise<void> {
{ scheme: 'file', language: 'cpp' },
{ scheme: 'file', language: 'cuda-cpp' }
];
codeActionProvider = vscode.languages.registerCodeActionsProvider(selector, {
codeActionProvider = vscode.languages.registerCodeActionsProvider(selector, instrument({
provideCodeActions: async (document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext): Promise<vscode.CodeAction[]> => {

if (!await clients.ActiveClient.getVcpkgEnabled()) {
Expand All @@ -248,7 +249,7 @@ export async function activate(): Promise<void> {
const actions: vscode.CodeAction[] = ports.map<vscode.CodeAction>(getVcpkgClipboardInstallAction);
return actions;
}
});
}));

await vscode.commands.executeCommand('setContext', 'cpptools.msvcEnvironmentFound', util.hasMsvcEnvironment());

Expand Down Expand Up @@ -1280,10 +1281,8 @@ async function handleCrashFileRead(crashDirectory: string, crashFile: string, cr
if (crashCallStack !== prevCppCrashCallStackData) {
prevCppCrashCallStackData = crashCallStack;

const settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", null);
if (lines.length >= 6 && util.getNumericLoggingLevel(settings.get<string>("loggingLevel")) >= 1) {
const out: vscode.OutputChannel = getCrashCallStacksChannel();
out.appendLine(`\n${isCppToolsSrv ? "cpptools-srv" : "cpptools"}\n${crashDate.toLocaleString()}\n${signalType}${crashCallStack}`);
if (lines.length >= 6 && util.getLoggingLevel() >= 1) {
getCrashCallStacksChannel().appendLine(`\n${isCppToolsSrv ? "cpptools-srv" : "cpptools"}\n${crashDate.toLocaleString()}\n${signalType}${crashCallStack}`);
}
}

Expand Down
17 changes: 7 additions & 10 deletions Extension/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -759,10 +759,7 @@ export interface ProcessReturnType {
export async function spawnChildProcess(program: string, args: string[] = [], continueOn?: string, skipLogging?: boolean, cancellationToken?: vscode.CancellationToken): Promise<ProcessReturnType> {
// Do not use CppSettings to avoid circular require()
if (skipLogging === undefined || !skipLogging) {
const settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", null);
if (getNumericLoggingLevel(settings.get<string>("loggingLevel")) >= 5) {
getOutputChannelLogger().appendLine(`$ ${program} ${args.join(' ')}`);
}
getOutputChannelLogger().appendLineAtLevel(5, `$ ${program} ${args.join(' ')}`);
}
const programOutput: ProcessOutput = await spawnChildProcessImpl(program, args, continueOn, skipLogging, cancellationToken);
const exitCode: number | NodeJS.Signals | undefined = programOutput.exitCode;
Expand All @@ -789,10 +786,6 @@ interface ProcessOutput {
async function spawnChildProcessImpl(program: string, args: string[], continueOn?: string, skipLogging?: boolean, cancellationToken?: vscode.CancellationToken): Promise<ProcessOutput> {
const result = new ManualPromise<ProcessOutput>();

// Do not use CppSettings to avoid circular require()
const settings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("C_Cpp", null);
const loggingLevel: number = (skipLogging === undefined || !skipLogging) ? getNumericLoggingLevel(settings.get<string>("loggingLevel")) : 0;

let proc: child_process.ChildProcess;
if (await isExecutable(program)) {
proc = child_process.spawn(`.${isWindows ? '\\' : '/'}${path.basename(program)}`, args, { shell: true, cwd: path.dirname(program) });
Expand All @@ -817,8 +810,8 @@ async function spawnChildProcessImpl(program: string, args: string[], continueOn
if (proc.stdout) {
proc.stdout.on('data', data => {
const str: string = data.toString();
if (loggingLevel > 0) {
getOutputChannelLogger().append(str);
if (skipLogging === undefined || !skipLogging) {
getOutputChannelLogger().appendAtLevel(1, str);
}
stdout += str;
if (continueOn) {
Expand Down Expand Up @@ -1576,6 +1569,10 @@ function isIntegral(str: string): boolean {
return regex.test(str);
}

export function getLoggingLevel() {
return getNumericLoggingLevel(vscode.workspace.getConfiguration("C_Cpp", null).get<string>("loggingLevel"));
}

export function getNumericLoggingLevel(loggingLevel: string | undefined): number {
if (!loggingLevel) {
return 1;
Expand Down
Loading