Skip to content

Commit 2aa1f64

Browse files
committed
Write client log to file if option set
And add a new log level: Debug
1 parent 779f211 commit 2aa1f64

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

src/extension.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ function findManualExecutable(logger: Logger, uri: Uri, folder?: WorkspaceFolder
108108
}
109109
logger.info(`Trying to find the server executable in: ${exePath}`);
110110
exePath = resolvePathPlaceHolders(exePath, folder);
111-
logger.info(`Location after path variables substitution: ${exePath}`);
111+
logger.log(`Location after path variables substitution: ${exePath}`);
112112

113113
if (!executableExists(exePath)) {
114114
let msg = `serverExecutablePath is set to ${exePath}`;
@@ -164,6 +164,8 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
164164
return;
165165
}
166166

167+
const currentWorkingDir = folder ? folder.uri.fsPath : path.dirname(uri.fsPath);
168+
167169
// Set the key to null to prevent multiple servers being launched at once
168170
clients.set(clientsKey, null);
169171

@@ -173,11 +175,14 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
173175

174176
const outputChannel: OutputChannel = window.createOutputChannel(langName);
175177

176-
const logger: Logger = new ExtensionLogger('client', clientLogLevel, outputChannel);
177-
178-
logger.info('Environment variables:');
178+
const logFilePath = logFile ? path.resolve(currentWorkingDir, logFile) : undefined;
179+
const logger: Logger = new ExtensionLogger('client', clientLogLevel, outputChannel, logFilePath);
180+
if (logFilePath) {
181+
logger.info(`Writing client log to file ${logFilePath}`);
182+
}
183+
logger.log('Environment variables:');
179184
Object.entries(process.env).forEach(([key, value]: [string, string | undefined]) => {
180-
logger.info(` ${key}: ${value}`);
185+
logger.log(` ${key}: ${value}`);
181186
});
182187

183188
let serverExecutable;
@@ -217,11 +222,13 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
217222
// If we're operating on a standalone file (i.e. not in a folder) then we need
218223
// to launch the server in a reasonable current directory. Otherwise the cradle
219224
// guessing logic in hie-bios will be wrong!
225+
let cwdMsg = `Activating the language server in working dir: ${currentWorkingDir}`;
220226
if (folder) {
221-
logger.info(`Activating the language server in the workspace folder: ${folder?.uri.fsPath}`);
227+
cwdMsg += ' (the workspace folder)';
222228
} else {
223-
logger.info(`Activating the language server in the parent dir of the file: ${uri.fsPath}`);
229+
cwdMsg += ` (parent dir of loaded file ${uri.fsPath})`;
224230
}
231+
logger.info(cwdMsg);
225232

226233
const serverEnvironment: IEnvVars = workspace.getConfiguration('haskell', uri).serverEnvironment;
227234
const exeOptions: ExecutableOptions = {
@@ -252,7 +259,7 @@ async function activateServerForFolder(context: ExtensionContext, uri: Uri, fold
252259
}
253260

254261
const pat = folder ? `${folder.uri.fsPath}/**/*` : '**/*';
255-
logger.info(`document selector patten: ${pat}`);
262+
logger.log(`document selector patten: ${pat}`);
256263
const clientOptions: LanguageClientOptions = {
257264
// Use the document selector to only notify the LSP on files inside the folder
258265
// path for the specific workspace.

src/utils.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@ enum LogLevel {
1818
Error,
1919
Warn,
2020
Info,
21+
Debug
2122
}
2223
export class ExtensionLogger implements Logger {
2324
public readonly name: string;
2425
public readonly level: LogLevel;
2526
public readonly channel: OutputChannel;
27+
public readonly logFile: string | undefined;
2628

27-
constructor(name: string, level: string, channel: OutputChannel) {
29+
constructor(name: string, level: string, channel: OutputChannel, logFile: string | undefined) {
2830
this.name = name;
2931
this.level = this.getLogLevel(level);
3032
this.channel = channel;
33+
this.logFile = logFile;
3134
}
3235
public warn(message: string): void {
3336
this.logLevel(LogLevel.Warn, message);
@@ -41,13 +44,25 @@ export class ExtensionLogger implements Logger {
4144
this.logLevel(LogLevel.Error, message);
4245
}
4346

44-
public log(msg: string) {
45-
this.channel.appendLine(msg);
47+
public log(message: string) {
48+
this.logLevel(LogLevel.Debug, message);
49+
}
50+
51+
private write(msg: string) {
52+
let now = new Date();
53+
// Ugly hack to make js date iso format similar to hls one
54+
const offset = now.getTimezoneOffset();
55+
now = new Date(now.getTime() - (offset * 60 * 1000));
56+
const timedMsg = `${new Date().toISOString().replace('T', ' ').replace('Z', '0000')} ${msg}`;
57+
this.channel.appendLine(timedMsg);
58+
if (this.logFile) {
59+
fs.appendFileSync(this.logFile, timedMsg + '\n');
60+
}
4661
}
4762

4863
private logLevel(level: LogLevel, msg: string) {
4964
if (level <= this.level) {
50-
this.log(`[${this.name}][${LogLevel[level].toUpperCase()}] ${msg}`);
65+
this.write(`[${this.name}] ${LogLevel[level].toUpperCase()} ${msg}`);
5166
}
5267
}
5368

@@ -57,6 +72,8 @@ export class ExtensionLogger implements Logger {
5772
return LogLevel.Off;
5873
case 'error':
5974
return LogLevel.Error;
75+
case 'debug':
76+
return LogLevel.Debug;
6077
default:
6178
return LogLevel.Info;
6279
}

0 commit comments

Comments
 (0)