mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 09:35:37 -05:00
* Adding support for configuring SqlTools log levels from user configuration. This also adds changes to see the tail of the sqltoolsservicelayer log file in the newly created 'Output->Log (SqlTools)' channel * Three new user settings control how logging happens. tracingLevel, logRetentionMinutes & logFilesRemovalLimit. Default tracingLevel is set to 'Critical'. * The logfiles include ui Extension host process id in their log file names. This ensures that filenames from multiple instances of Azure Data Studio running do not collide with each other. Furthermore log directory for being used for the tools service backend processes. This ensures that there is no name conflict when multiple instances of azuredatastudio are running on the same box. Also when azuredatastudio is started from vscode under debugger the log directory is set to %APPDATA%\Code\mssql while the official location is %APPDATA%\azuredatastudio\mssql. So dev environment should not affect other running instances. Kindly note that all debug runs of azuredatastudio share the same directory and all non debug runs share a directory different from those running under debugger. * Log files older than a week get cleaned up upon start-up. The log file cleanup behavior can be controlled at user level by logRetentionMinutes & logFilesRemovalLimit settings.
159 lines
5.4 KiB
TypeScript
159 lines
5.4 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
'use strict';
|
|
|
|
import * as vscode from 'vscode';
|
|
import * as path from 'path';
|
|
import { SqlOpsDataClient, ClientOptions } from 'dataprotocol-client';
|
|
import { IConfig, ServerProvider, Events } from 'service-downloader';
|
|
import { ServerOptions, TransportKind } from 'vscode-languageclient';
|
|
|
|
import * as Constants from './constants';
|
|
import ContextProvider from './contextProvider';
|
|
import { CredentialStore } from './credentialstore/credentialstore';
|
|
import { AzureResourceProvider } from './resourceProvider/resourceProvider';
|
|
import * as Utils from './utils';
|
|
import { Telemetry, LanguageClientErrorHandler } from './telemetry';
|
|
import { TelemetryFeature, AgentServicesFeature } from './features';
|
|
|
|
const baseConfig = require('./config.json');
|
|
const outputChannel = vscode.window.createOutputChannel(Constants.serviceName);
|
|
const statusView = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
|
|
|
export async function activate(context: vscode.ExtensionContext) {
|
|
// lets make sure we support this platform first
|
|
let supported = await Utils.verifyPlatform();
|
|
|
|
if (!supported) {
|
|
vscode.window.showErrorMessage('Unsupported platform');
|
|
return;
|
|
}
|
|
|
|
let config: IConfig = JSON.parse(JSON.stringify(baseConfig));
|
|
config.installDirectory = path.join(__dirname, config.installDirectory);
|
|
config.proxy = vscode.workspace.getConfiguration('http').get('proxy');
|
|
config.strictSSL = vscode.workspace.getConfiguration('http').get('proxyStrictSSL') || true;
|
|
|
|
const credentialsStore = new CredentialStore(config);
|
|
const resourceProvider = new AzureResourceProvider(config);
|
|
let languageClient: SqlOpsDataClient;
|
|
|
|
const serverdownloader = new ServerProvider(config);
|
|
|
|
serverdownloader.eventEmitter.onAny(generateHandleServerProviderEvent());
|
|
|
|
let clientOptions: ClientOptions = {
|
|
documentSelector: ['sql'],
|
|
synchronize: {
|
|
configurationSection: Constants.extensionConfigSectionName
|
|
},
|
|
providerId: Constants.providerId,
|
|
errorHandler: new LanguageClientErrorHandler(),
|
|
features: [
|
|
// we only want to add new features
|
|
...SqlOpsDataClient.defaultFeatures,
|
|
TelemetryFeature,
|
|
AgentServicesFeature
|
|
],
|
|
outputChannel: new CustomOutputChannel()
|
|
};
|
|
|
|
const installationStart = Date.now();
|
|
serverdownloader.getOrDownloadServer().then(e => {
|
|
const installationComplete = Date.now();
|
|
let serverOptions = generateServerOptions(e);
|
|
languageClient = new SqlOpsDataClient(Constants.serviceName, serverOptions, clientOptions);
|
|
const processStart = Date.now();
|
|
languageClient.onReady().then(() => {
|
|
const processEnd = Date.now();
|
|
statusView.text = 'Service Started';
|
|
setTimeout(() => {
|
|
statusView.hide();
|
|
}, 1500);
|
|
Telemetry.sendTelemetryEvent('startup/LanguageClientStarted', {
|
|
installationTime: String(installationComplete - installationStart),
|
|
processStartupTime: String(processEnd - processStart),
|
|
totalTime: String(processEnd - installationStart),
|
|
beginningTimestamp: String(installationStart)
|
|
});
|
|
});
|
|
statusView.show();
|
|
statusView.text = 'Starting service';
|
|
languageClient.start();
|
|
credentialsStore.start();
|
|
resourceProvider.start();
|
|
}, e => {
|
|
Telemetry.sendTelemetryEvent('ServiceInitializingFailed');
|
|
vscode.window.showErrorMessage('Failed to start Sql tools service');
|
|
});
|
|
|
|
let contextProvider = new ContextProvider();
|
|
context.subscriptions.push(contextProvider);
|
|
context.subscriptions.push(credentialsStore);
|
|
context.subscriptions.push(resourceProvider);
|
|
context.subscriptions.push({ dispose: () => languageClient.stop() });
|
|
}
|
|
|
|
function generateServerOptions(executablePath: string): ServerOptions {
|
|
let launchArgs = Utils.getCommonLaunchArgsAndCleanupOldLogFiles('sqltools', executablePath);
|
|
return { command: executablePath, args: launchArgs, transport: TransportKind.stdio };
|
|
}
|
|
|
|
function generateHandleServerProviderEvent() {
|
|
let dots = 0;
|
|
return (e: string, ...args: any[]) => {
|
|
outputChannel.show();
|
|
statusView.show();
|
|
switch (e) {
|
|
case Events.INSTALL_START:
|
|
outputChannel.appendLine(`Installing ${Constants.serviceName} service to ${args[0]}`);
|
|
statusView.text = 'Installing Service';
|
|
break;
|
|
case Events.INSTALL_END:
|
|
outputChannel.appendLine('Installed');
|
|
break;
|
|
case Events.DOWNLOAD_START:
|
|
outputChannel.appendLine(`Downloading ${args[0]}`);
|
|
outputChannel.append(`(${Math.ceil(args[1] / 1024)} KB)`);
|
|
statusView.text = 'Downloading Service';
|
|
break;
|
|
case Events.DOWNLOAD_PROGRESS:
|
|
let newDots = Math.ceil(args[0] / 5);
|
|
if (newDots > dots) {
|
|
outputChannel.append('.'.repeat(newDots - dots));
|
|
dots = newDots;
|
|
}
|
|
break;
|
|
case Events.DOWNLOAD_END:
|
|
outputChannel.appendLine('Done!');
|
|
break;
|
|
}
|
|
};
|
|
}
|
|
|
|
// this method is called when your extension is deactivated
|
|
export function deactivate(): void {
|
|
}
|
|
|
|
class CustomOutputChannel implements vscode.OutputChannel {
|
|
name: string;
|
|
append(value: string): void {
|
|
console.log(value);
|
|
}
|
|
appendLine(value: string): void {
|
|
console.log(value);
|
|
}
|
|
clear(): void {
|
|
}
|
|
show(preserveFocus?: boolean): void;
|
|
show(column?: vscode.ViewColumn, preserveFocus?: boolean): void;
|
|
show(column?: any, preserveFocus?: any) {
|
|
}
|
|
hide(): void {
|
|
}
|
|
dispose(): void {
|
|
}
|
|
}
|