Add Logger
This commit is contained in:
parent
4c48cc52de
commit
8005b3dce5
|
@ -3,32 +3,32 @@
|
|||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}",
|
||||
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
}
|
||||
]
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run Extension",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
},
|
||||
{
|
||||
"name": "Extension Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}",
|
||||
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/out/test/**/*.js"
|
||||
],
|
||||
"preLaunchTask": "${defaultBuildTask}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
22
package.json
22
package.json
|
@ -64,10 +64,30 @@
|
|||
"title": "CMake IntelliSence",
|
||||
"properties": {
|
||||
"cmakeIntelliSence.languageServerPath": {
|
||||
"scope": "resource",
|
||||
"type": "string",
|
||||
"default": "cmakels",
|
||||
"description": "Path to CMake Language Server"
|
||||
},
|
||||
"cmakeIntelliSence.loggingLevel": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Off",
|
||||
"Error",
|
||||
"Warnning",
|
||||
"Info",
|
||||
"Debug"
|
||||
],
|
||||
"default": "Info",
|
||||
"markdownDescription": "Control the logging level"
|
||||
},
|
||||
"cmakeIntelliSence.trace.server": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"verbose",
|
||||
"message",
|
||||
"off"
|
||||
],
|
||||
"default": "verbose"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
// The module 'vscode' contains the VS Code extensibility API
|
||||
// Import the module and reference it with the alias vscode in your code below
|
||||
import * as path from 'path';
|
||||
import * as net from 'net';
|
||||
import * as vscode from 'vscode';
|
||||
import {
|
||||
LanguageClient,
|
||||
LanguageClientOptions,
|
||||
ServerOptions,
|
||||
TransportKind
|
||||
} from 'vscode-languageclient/node';
|
||||
import { getConfigLogLevel, Logger } from './logging';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';
|
||||
|
||||
|
||||
export const SERVER_ID = 'cmakeIntelliSence';
|
||||
export const SERVER_NAME = 'CMake Language Server';
|
||||
|
||||
let client: LanguageClient;
|
||||
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const config = vscode.workspace.getConfiguration(SERVER_ID);
|
||||
const logger = new Logger();
|
||||
logger.setLogLevel(getConfigLogLevel(config));
|
||||
|
||||
const config = vscode.workspace.getConfiguration('cmakeIntelliSence');
|
||||
let cmakels = config.get<string>('languageServerPath');
|
||||
if (cmakels === undefined) {
|
||||
cmakels = 'cmakels';
|
||||
}
|
||||
|
||||
// language server options
|
||||
// default transport is TransportKind.stdio
|
||||
const serverOptions: ServerOptions = {
|
||||
command: cmakels,
|
||||
// args: [serverEntryPath]
|
||||
};
|
||||
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration((e) => {
|
||||
if (e.affectsConfiguration(`${SERVER_ID}.loggingLevel`)) {
|
||||
logger.setLogLevel(getConfigLogLevel(config));
|
||||
}
|
||||
}));
|
||||
|
||||
// Options to control the language client
|
||||
const clientOptions: LanguageClientOptions = {
|
||||
|
@ -34,22 +26,44 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
{ language: 'cmake', scheme: 'file' },
|
||||
{ language: 'cmake', scheme: 'untitled' }
|
||||
],
|
||||
outputChannel: vscode.window.createOutputChannel('CMake IntelliSence')
|
||||
outputChannel: logger.getOutputChannel()
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
client = new LanguageClient(
|
||||
'cmakeLanguageServer',
|
||||
'CMake Language Server',
|
||||
serverOptions,
|
||||
clientOptions
|
||||
);
|
||||
// language server options
|
||||
let serverOptions: ServerOptions;
|
||||
let mode: string;
|
||||
if (context.extensionMode === vscode.ExtensionMode.Development) {
|
||||
// Development - communicate using tcp
|
||||
serverOptions = () => {
|
||||
return new Promise((resolve) => {
|
||||
const clientSocket = new net.Socket();
|
||||
clientSocket.connect(2088, "127.0.0.1", () => {
|
||||
resolve({
|
||||
reader: clientSocket,
|
||||
writer: clientSocket
|
||||
});
|
||||
});
|
||||
clientSocket.on('connect', () => { logger.info('Connected'); });
|
||||
clientSocket.on('error', (err) => { logger.info('error', err); });
|
||||
clientSocket.on('close', () => { logger.info('connection closed'); });
|
||||
});
|
||||
};
|
||||
mode = 'Development';
|
||||
} else {
|
||||
// Production - communicate using stdio
|
||||
serverOptions = {
|
||||
command: 'cmakels'
|
||||
};
|
||||
mode = 'Production';
|
||||
}
|
||||
client = new LanguageClient(SERVER_ID, SERVER_NAME, serverOptions, clientOptions);
|
||||
|
||||
// start the client. This will also launch the server
|
||||
logger.info(`Start ${SERVER_NAME} in ${mode} mode...`);
|
||||
client.start();
|
||||
}
|
||||
|
||||
// this method is called when your extension is deactivated
|
||||
|
||||
export function deactivate() {
|
||||
if (!client) {
|
||||
return undefined;
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { OutputChannel, window, workspace, WorkspaceConfiguration } from 'vscode';
|
||||
import { SERVER_ID } from './extension';
|
||||
|
||||
export enum LogLevel {
|
||||
DEBUG = 0,
|
||||
INFO = 1,
|
||||
WARN = 2,
|
||||
ERROR = 3,
|
||||
OFF = 4,
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
constructor(
|
||||
private channel: OutputChannel = window.createOutputChannel('CMake IntelliSence'),
|
||||
private level: LogLevel = LogLevel.INFO
|
||||
) { }
|
||||
|
||||
public setLogLevel(logLevel: LogLevel) {
|
||||
this.level = logLevel;
|
||||
}
|
||||
|
||||
public getLogLevel(): LogLevel {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public getOutputChannel(): OutputChannel {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
public debug(message: string, data?: unknown): void {
|
||||
if (this.level > LogLevel.DEBUG) {
|
||||
return;
|
||||
}
|
||||
this.log(message, LogLevel.DEBUG);
|
||||
if (data) {
|
||||
this.logObject(data);
|
||||
}
|
||||
}
|
||||
|
||||
public info(message: string, data?: unknown): void {
|
||||
if (this.level > LogLevel.INFO) {
|
||||
return;
|
||||
}
|
||||
this.log(message, LogLevel.INFO);
|
||||
if (data) {
|
||||
this.logObject(data);
|
||||
}
|
||||
}
|
||||
|
||||
public warn(message: string, data?: unknown): void {
|
||||
if (this.level > LogLevel.WARN) {
|
||||
return;
|
||||
}
|
||||
this.log(message, LogLevel.WARN);
|
||||
if (data) {
|
||||
this.logObject(data);
|
||||
}
|
||||
}
|
||||
|
||||
public error(message: string, error?: Error | string) {
|
||||
if (this.level > LogLevel.ERROR) {
|
||||
return;
|
||||
}
|
||||
this.log(message, LogLevel.ERROR);
|
||||
|
||||
if (typeof error === 'string') {
|
||||
// Errors as a string usually only happen with
|
||||
// plugins that don't return the expected error.
|
||||
this.channel.appendLine(error);
|
||||
} else if (error?.message || error?.stack) {
|
||||
if (error?.message) {
|
||||
this.log(error.message, LogLevel.ERROR);
|
||||
}
|
||||
if (error?.stack) {
|
||||
this.channel.appendLine(error.stack);
|
||||
}
|
||||
} else if (error) {
|
||||
this.logObject(error);
|
||||
}
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.channel.show();
|
||||
}
|
||||
|
||||
private logObject(data: unknown): void {
|
||||
const message = JSON.stringify(data, null, 2);
|
||||
this.channel.appendLine(message);
|
||||
}
|
||||
|
||||
private log(message: string, level: LogLevel): void {
|
||||
const title = new Date().toLocaleTimeString();
|
||||
this.channel.appendLine(`[${LogLevel[level]} - ${title}] ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `loggingLevel` option from the workspace settings and converts
|
||||
* it a `LogLevel` enum value.
|
||||
* @param config workspace configuration object
|
||||
* @returns `LogLevel` enum value
|
||||
*/
|
||||
export function getConfigLogLevel(
|
||||
config: WorkspaceConfiguration = workspace.getConfiguration(SERVER_ID)
|
||||
): LogLevel {
|
||||
return LogLevel[(config.get<string>('loggingLevel') as string).toUpperCase() as keyof typeof LogLevel];
|
||||
}
|
Loading…
Reference in New Issue