mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
add logging for data workspace extension (#20601)
* add logging for data workspace extension * Addressing comments * adding back getProjectsInWorkspace() in constructor * Add more logging in activate()
This commit is contained in:
@@ -33,6 +33,7 @@ export const Select = localize('dataworkspace.select', "Select");
|
|||||||
export const WorkspaceFileExtension = '.code-workspace';
|
export const WorkspaceFileExtension = '.code-workspace';
|
||||||
export const DefaultInputWidth = '400px';
|
export const DefaultInputWidth = '400px';
|
||||||
export const DefaultButtonWidth = '80px';
|
export const DefaultButtonWidth = '80px';
|
||||||
|
export const DataWorkspaceOutputChannel = 'Data Workspace';
|
||||||
|
|
||||||
// New Project Dialog
|
// New Project Dialog
|
||||||
export const NewProjectDialogTitle = localize('dataworkspace.NewProjectDialogTitle', "Create new database project");
|
export const NewProjectDialogTitle = localize('dataworkspace.NewProjectDialogTitle', "Create new database project");
|
||||||
|
|||||||
@@ -2,10 +2,37 @@
|
|||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { DataWorkspaceOutputChannel } from './constants';
|
||||||
|
|
||||||
export class Log {
|
export class Log {
|
||||||
error(msg: string): void {
|
private output: vscode.OutputChannel;
|
||||||
console.error(msg);
|
|
||||||
|
constructor() {
|
||||||
|
this.output = vscode.window.createOutputChannel(DataWorkspaceOutputChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(message: string): void {
|
||||||
|
this.output.appendLine(`[Error - ${this.now()}] ${message}`);
|
||||||
|
console.error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message: string): void {
|
||||||
|
this.output.appendLine(`[Info - ${this.now()}] ${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private now(): string {
|
||||||
|
const now = new Date();
|
||||||
|
return this.padLeft(now.getUTCFullYear() + '', 2, '0')
|
||||||
|
+ '-' + this.padLeft(now.getUTCMonth() + '', 2, '0')
|
||||||
|
+ '-' + this.padLeft(now.getUTCDate() + '', 2, '0')
|
||||||
|
+ ' ' + this.padLeft(now.getUTCHours() + '', 2, '0')
|
||||||
|
+ ':' + this.padLeft(now.getMinutes() + '', 2, '0')
|
||||||
|
+ ':' + this.padLeft(now.getUTCSeconds() + '', 2, '0') + '.' + now.getMilliseconds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private padLeft(s: string, n: number, pad = ' ') {
|
||||||
|
return pad.repeat(Math.max(0, n - s.length)) + s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const Logger = new Log();
|
const Logger = new Log();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { IWorkspaceService } from './interfaces';
|
|||||||
import { ProjectsFailedToLoad, UnknownProjectsError } from './constants';
|
import { ProjectsFailedToLoad, UnknownProjectsError } from './constants';
|
||||||
import { WorkspaceTreeItem } from 'dataworkspace';
|
import { WorkspaceTreeItem } from 'dataworkspace';
|
||||||
import { TelemetryReporter } from './telemetry';
|
import { TelemetryReporter } from './telemetry';
|
||||||
|
import Logger from './logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tree data provider for the workspace main view
|
* Tree data provider for the workspace main view
|
||||||
@@ -24,6 +25,7 @@ export class WorkspaceTreeDataProvider implements vscode.TreeDataProvider<Worksp
|
|||||||
readonly onDidChangeTreeData?: vscode.Event<void | WorkspaceTreeItem | null | undefined> | undefined = this._onDidChangeTreeData?.event;
|
readonly onDidChangeTreeData?: vscode.Event<void | WorkspaceTreeItem | null | undefined> | undefined = this._onDidChangeTreeData?.event;
|
||||||
|
|
||||||
async refresh(): Promise<void> {
|
async refresh(): Promise<void> {
|
||||||
|
Logger.log(`Refreshing projects tree`);
|
||||||
await this._workspaceService.getProjectsInWorkspace(undefined, true);
|
await this._workspaceService.getProjectsInWorkspace(undefined, true);
|
||||||
this._onDidChangeTreeData?.fire();
|
this._onDidChangeTreeData?.fire();
|
||||||
}
|
}
|
||||||
@@ -39,6 +41,7 @@ export class WorkspaceTreeDataProvider implements vscode.TreeDataProvider<Worksp
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if the element is undefined return the project tree items
|
// if the element is undefined return the project tree items
|
||||||
|
Logger.log(`Calling getProjectsInWorkspace() from getChildren()`);
|
||||||
const projects = await this._workspaceService.getProjectsInWorkspace(undefined, false);
|
const projects = await this._workspaceService.getProjectsInWorkspace(undefined, false);
|
||||||
await vscode.commands.executeCommand('setContext', 'isProjectsViewEmpty', projects.length === 0);
|
await vscode.commands.executeCommand('setContext', 'isProjectsViewEmpty', projects.length === 0);
|
||||||
const unknownProjects: string[] = [];
|
const unknownProjects: string[] = [];
|
||||||
|
|||||||
@@ -15,23 +15,44 @@ import { IconPathHelper } from './common/iconHelper';
|
|||||||
import { ProjectDashboard } from './dialogs/projectDashboard';
|
import { ProjectDashboard } from './dialogs/projectDashboard';
|
||||||
import { getAzdataApi } from './common/utils';
|
import { getAzdataApi } from './common/utils';
|
||||||
import { createNewProjectWithQuickpick } from './dialogs/newProjectQuickpick';
|
import { createNewProjectWithQuickpick } from './dialogs/newProjectQuickpick';
|
||||||
|
import Logger from './common/logger';
|
||||||
|
|
||||||
export async function activate(context: vscode.ExtensionContext): Promise<IExtension> {
|
export async function activate(context: vscode.ExtensionContext): Promise<IExtension> {
|
||||||
|
const startTime = new Date().getTime();
|
||||||
|
Logger.log(`Starting Data Workspace activate()`);
|
||||||
|
|
||||||
|
const azDataApiStartTime = new Date().getTime();
|
||||||
const azdataApi = getAzdataApi();
|
const azdataApi = getAzdataApi();
|
||||||
void vscode.commands.executeCommand('setContext', 'azdataAvailable', !!azdataApi);
|
void vscode.commands.executeCommand('setContext', 'azdataAvailable', !!azdataApi);
|
||||||
const workspaceService = new WorkspaceService();
|
Logger.log(`Setting azdataAvailable took ${new Date().getTime() - azDataApiStartTime}ms`);
|
||||||
|
|
||||||
|
const workspaceServiceConstructorStartTime = new Date().getTime();
|
||||||
|
const workspaceService = new WorkspaceService();
|
||||||
|
Logger.log(`WorkspaceService constructor took ${new Date().getTime() - workspaceServiceConstructorStartTime}ms`);
|
||||||
|
|
||||||
|
const workspaceTreeDataProviderStartTime = new Date().getTime();
|
||||||
const workspaceTreeDataProvider = new WorkspaceTreeDataProvider(workspaceService);
|
const workspaceTreeDataProvider = new WorkspaceTreeDataProvider(workspaceService);
|
||||||
context.subscriptions.push(vscode.workspace.onDidChangeWorkspaceFolders(async () => {
|
context.subscriptions.push(vscode.workspace.onDidChangeWorkspaceFolders(async () => {
|
||||||
await workspaceTreeDataProvider.refresh();
|
await workspaceTreeDataProvider.refresh();
|
||||||
}));
|
}));
|
||||||
|
Logger.log(`WorkspaceTreeDataProvider constructor took ${new Date().getTime() - workspaceTreeDataProviderStartTime}ms`);
|
||||||
|
|
||||||
|
const dataWorkspaceExtensionStartTime = new Date().getTime();
|
||||||
const dataWorkspaceExtension = new DataWorkspaceExtension(workspaceService);
|
const dataWorkspaceExtension = new DataWorkspaceExtension(workspaceService);
|
||||||
|
Logger.log(`DataWorkspaceExtension constructor took ${new Date().getTime() - dataWorkspaceExtensionStartTime}ms`);
|
||||||
|
|
||||||
|
const registerTreeDataProvidertartTime = new Date().getTime();
|
||||||
context.subscriptions.push(vscode.window.registerTreeDataProvider('dataworkspace.views.main', workspaceTreeDataProvider));
|
context.subscriptions.push(vscode.window.registerTreeDataProvider('dataworkspace.views.main', workspaceTreeDataProvider));
|
||||||
|
Logger.log(`registerTreeDataProvider took ${new Date().getTime() - registerTreeDataProvidertartTime}ms`);
|
||||||
|
|
||||||
|
const settingProjectProviderContextStartTime = new Date().getTime();
|
||||||
context.subscriptions.push(vscode.extensions.onDidChange(() => {
|
context.subscriptions.push(vscode.extensions.onDidChange(() => {
|
||||||
setProjectProviderContextValue(workspaceService);
|
setProjectProviderContextValue(workspaceService);
|
||||||
}));
|
}));
|
||||||
setProjectProviderContextValue(workspaceService);
|
setProjectProviderContextValue(workspaceService);
|
||||||
|
Logger.log(`setProjectProviderContextValue took ${new Date().getTime() - settingProjectProviderContextStartTime}ms`);
|
||||||
|
|
||||||
|
const registerCommandStartTime = new Date().getTime();
|
||||||
context.subscriptions.push(vscode.commands.registerCommand('projects.new', async () => {
|
context.subscriptions.push(vscode.commands.registerCommand('projects.new', async () => {
|
||||||
if (azdataApi) {
|
if (azdataApi) {
|
||||||
const dialog = new NewProjectDialog(workspaceService);
|
const dialog = new NewProjectDialog(workspaceService);
|
||||||
@@ -70,9 +91,13 @@ export async function activate(context: vscode.ExtensionContext): Promise<IExten
|
|||||||
const dashboard = new ProjectDashboard(workspaceService, treeItem);
|
const dashboard = new ProjectDashboard(workspaceService, treeItem);
|
||||||
await dashboard.showDashboard();
|
await dashboard.showDashboard();
|
||||||
}));
|
}));
|
||||||
|
Logger.log(`Registering commands took ${new Date().getTime() - registerCommandStartTime}ms`);
|
||||||
|
|
||||||
|
const iconPathHelperTime = new Date().getTime();
|
||||||
IconPathHelper.setExtensionContext(context);
|
IconPathHelper.setExtensionContext(context);
|
||||||
|
Logger.log(`IconPathHelper took ${new Date().getTime() - iconPathHelperTime}ms`);
|
||||||
|
|
||||||
|
Logger.log(`Finished activating Data Workspace extension. Total time = ${new Date().getTime() - startTime}ms`);
|
||||||
return Promise.resolve(dataWorkspaceExtension);
|
return Promise.resolve(dataWorkspaceExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,22 +27,22 @@ export class WorkspaceService implements IWorkspaceService {
|
|||||||
private excludedProjects: string[] | undefined;
|
private excludedProjects: string[] | undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.getProjectsInWorkspace(undefined, true).catch(err => console.error('Error initializing projects in workspace ', err));
|
Logger.log(`Calling getProjectsInWorkspace() from WorkspaceService constructor`);
|
||||||
|
this.getProjectsInWorkspace(undefined, true).catch(err => Logger.error(`Error initializing projects in workspace ${err}`));
|
||||||
TelemetryReporter.createActionEvent(TelemetryViews.WorkspaceTreePane, TelemetryActions.ProjectsLoaded)
|
|
||||||
.withAdditionalProperties({
|
|
||||||
openProjectCount: this.openedProjects?.length.toString() ?? '0',
|
|
||||||
exludedProjectCount: this.excludedProjects?.length.toString() ?? '0'
|
|
||||||
}).send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get isProjectProviderAvailable(): boolean {
|
get isProjectProviderAvailable(): boolean {
|
||||||
|
Logger.log(`Checking ${vscode.extensions.all.length} extensions to see if there is a project provider is available`);
|
||||||
|
const startTime = new Date().getTime();
|
||||||
for (const extension of vscode.extensions.all) {
|
for (const extension of vscode.extensions.all) {
|
||||||
const projectTypes = extension.packageJSON.contributes && extension.packageJSON.contributes.projects as string[];
|
const projectTypes = extension.packageJSON.contributes && extension.packageJSON.contributes.projects as string[];
|
||||||
if (projectTypes && projectTypes.length > 0) {
|
if (projectTypes && projectTypes.length > 0) {
|
||||||
|
Logger.log(`Project provider found. Total time = ${new Date().getTime() - startTime}ms`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.log(`No project providers found. Total time = ${new Date().getTime() - startTime}ms`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +134,8 @@ export class WorkspaceService implements IWorkspaceService {
|
|||||||
* @returns array of file URIs for projects
|
* @returns array of file URIs for projects
|
||||||
*/
|
*/
|
||||||
public async getProjectsInWorkspace(ext?: string, refreshFromDisk: boolean = false): Promise<vscode.Uri[]> {
|
public async getProjectsInWorkspace(ext?: string, refreshFromDisk: boolean = false): Promise<vscode.Uri[]> {
|
||||||
|
Logger.log(`Getting projects in workspace`);
|
||||||
|
const startTime = new Date().getTime();
|
||||||
|
|
||||||
if (refreshFromDisk || this.openedProjects === undefined) { // always check if nothing cached
|
if (refreshFromDisk || this.openedProjects === undefined) { // always check if nothing cached
|
||||||
await this.refreshProjectsFromDisk();
|
await this.refreshProjectsFromDisk();
|
||||||
@@ -147,6 +149,8 @@ export class WorkspaceService implements IWorkspaceService {
|
|||||||
this.excludedProjects = this.getWorkspaceConfigurationValue<string[]>(ExcludedProjectsConfigurationName);
|
this.excludedProjects = this.getWorkspaceConfigurationValue<string[]>(ExcludedProjectsConfigurationName);
|
||||||
this.openedProjects = this.openedProjects.filter(project => !this.excludedProjects?.find(excludedProject => excludedProject === vscode.workspace.asRelativePath(project)));
|
this.openedProjects = this.openedProjects.filter(project => !this.excludedProjects?.find(excludedProject => excludedProject === vscode.workspace.asRelativePath(project)));
|
||||||
|
|
||||||
|
Logger.log(`Finished looking for projects in workspace. Opened: ${this.openedProjects.length}. Excluded: ${this.excludedProjects.length}. Total time = ${new Date().getTime() - startTime}ms`);
|
||||||
|
|
||||||
// filter by specified extension
|
// filter by specified extension
|
||||||
if (ext) {
|
if (ext) {
|
||||||
return this.openedProjects.filter(p => p.fsPath.toLowerCase().endsWith(ext.toLowerCase()));
|
return this.openedProjects.filter(p => p.fsPath.toLowerCase().endsWith(ext.toLowerCase()));
|
||||||
|
|||||||
Reference in New Issue
Block a user