"use strict"; /*--------------------------------------------------------- * Copyright (C) Microsoft Corporation. All rights reserved. *--------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const debugSession_1 = require("./debugSession"); var LogLevel; (function (LogLevel) { LogLevel[LogLevel["Verbose"] = 0] = "Verbose"; LogLevel[LogLevel["Log"] = 1] = "Log"; LogLevel[LogLevel["Warn"] = 2] = "Warn"; LogLevel[LogLevel["Error"] = 3] = "Error"; LogLevel[LogLevel["Stop"] = 4] = "Stop"; })(LogLevel = exports.LogLevel || (exports.LogLevel = {})); class Logger { constructor() { this._pendingLogQ = []; } log(msg, level = LogLevel.Log) { msg = msg + '\n'; this._write(msg, level); } verbose(msg) { this.log(msg, LogLevel.Verbose); } warn(msg) { this.log(msg, LogLevel.Warn); } error(msg) { this.log(msg, LogLevel.Error); } /** * `log` adds a newline, `write` doesn't */ _write(msg, level = LogLevel.Log) { // [null, undefined] => string msg = msg + ''; if (this._pendingLogQ) { this._pendingLogQ.push({ msg, level }); } else { this._currentLogger.log(msg, level); } } /** * Set the logger's minimum level to log in the console, and whether to log to the file. Log messages are queued before this is * called the first time, because minLogLevel defaults to Warn. */ setup(consoleMinLogLevel, logToFile) { if (this._currentLogger) { this._currentLogger.setup(consoleMinLogLevel, logToFile); // Now that we have a minimum logLevel, we can clear out the queue of pending messages if (this._pendingLogQ) { const logQ = this._pendingLogQ; this._pendingLogQ = null; logQ.forEach(item => this._write(item.msg, item.level)); } } } init(logCallback, logFilePath, logToConsole) { // Re-init, create new global Logger this._pendingLogQ = this._pendingLogQ || []; this._currentLogger = new InternalLogger(logCallback, logFilePath, logToConsole); if (logFilePath) { const d = new Date(); const timestamp = d.toLocaleTimeString() + ', ' + d.toLocaleDateString(); this.verbose(timestamp); } } } exports.Logger = Logger; exports.logger = new Logger(); /** * Manages logging, whether to console.log, file, or VS Code console. * Encapsulates the state specific to each logging session */ class InternalLogger { constructor(logCallback, logFilePath, isServer) { this._logCallback = logCallback; this._logFilePath = logFilePath; this._logToConsole = isServer; this._minLogLevel = LogLevel.Warn; } setup(consoleMinLogLevel, logToFile) { this._minLogLevel = consoleMinLogLevel; // Open a log file in the specified location. Overwritten on each run. if (logToFile) { this.log(`Verbose logs are written to:\n`, LogLevel.Warn); this.log(this._logFilePath + '\n', LogLevel.Warn); this._logFileStream = fs.createWriteStream(this._logFilePath); this._logFileStream.on('error', e => { this.sendLog(`Error involving log file at path: ${this._logFilePath}. Error: ${e.toString()}`, LogLevel.Error); }); } } log(msg, level) { if (this._minLogLevel === LogLevel.Stop) { return; } if (level >= this._minLogLevel) { this.sendLog(msg, level); } if (this._logToConsole) { const logFn = level === LogLevel.Error ? console.error : level === LogLevel.Warn ? console.warn : console.log; logFn(trimLastNewline(msg)); } // If an error, prepend with '[Error]' if (level === LogLevel.Error) { msg = `[${LogLevel[level]}] ${msg}`; } if (this._logFileStream) { this._logFileStream.write(msg); } } sendLog(msg, level) { // Truncate long messages, they can hang VS Code if (msg.length > 1500) { const endsInNewline = !!msg.match(/(\n|\r\n)$/); msg = msg.substr(0, 1500) + '[...]'; if (endsInNewline) { msg = msg + '\n'; } } if (this._logCallback) { const event = new LogOutputEvent(msg, level); this._logCallback(event); } } } class LogOutputEvent extends debugSession_1.OutputEvent { constructor(msg, level) { const category = level === LogLevel.Error ? 'stderr' : level === LogLevel.Warn ? 'console' : 'stdout'; super(msg, category); } } exports.LogOutputEvent = LogOutputEvent; function trimLastNewline(str) { return str.replace(/(\n|\r\n)$/, ''); } exports.trimLastNewline = trimLastNewline; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xvZ2dlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OzREQUU0RDs7QUFFNUQseUJBQXlCO0FBQ3pCLGlEQUEyQztBQUUzQyxJQUFZLFFBTVg7QUFORCxXQUFZLFFBQVE7SUFDbkIsNkNBQVcsQ0FBQTtJQUNYLHFDQUFPLENBQUE7SUFDUCx1Q0FBUSxDQUFBO0lBQ1IseUNBQVMsQ0FBQTtJQUNULHVDQUFRLENBQUE7QUFDVCxDQUFDLEVBTlcsUUFBUSxHQUFSLGdCQUFRLEtBQVIsZ0JBQVEsUUFNbkI7QUFnQkQ7SUFBQTtRQUVTLGlCQUFZLEdBQWUsRUFBRSxDQUFDO0lBMkR2QyxDQUFDO0lBekRBLEdBQUcsQ0FBQyxHQUFXLEVBQUUsS0FBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHO1FBQ3BDLEdBQUcsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxPQUFPLENBQUMsR0FBVztRQUNsQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELElBQUksQ0FBQyxHQUFXO1FBQ2YsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxLQUFLLENBQUMsR0FBVztRQUNoQixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVEOztPQUVHO0lBQ0ssTUFBTSxDQUFDLEdBQVcsRUFBRSxLQUFLLEdBQUcsUUFBUSxDQUFDLEdBQUc7UUFDL0MsOEJBQThCO1FBQzlCLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ2YsRUFBRSxDQUFD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O0FBRkQsMENBRUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ29weXJpZ2h0IChDKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHtPdXRwdXRFdmVudH0gZnJvbSAnLi9kZWJ1Z1Nlc3Npb24nO1xuXG5leHBvcnQgZW51bSBMb2dMZXZlbCB7XG5cdFZlcmJvc2UgPSAwLFxuXHRMb2cgPSAxLFxuXHRXYXJuID0gMixcblx0RXJyb3IgPSAzLFxuXHRTdG9wID0gNFxufVxuXG5leHBvcnQgdHlwZSBJTG9nQ2FsbGJhY2sgPSAob3V0cHV0RXZlbnQ6IE91dHB1dEV2ZW50KSA9PiB2b2lkO1xuXG5pbnRlcmZhY2UgSUxvZ0l0ZW0ge1xuXHRtc2c6IHN0cmluZztcblx0bGV2ZWw6IExvZ0xldmVsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIElMb2dnZXIge1xuXHRsb2cobXNnOiBzdHJpbmcsIGxldmVsPzogTG9nTGV2ZWwpOiB2b2lkO1xuXHR2ZXJib3NlKG1zZzogc3RyaW5nKTogdm9pZDtcblx0d2Fybihtc2c6IHN0cmluZyk6IHZvaWQ7XG5cdGVycm9yKG1zZzogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGNsYXNzIExvZ2dlciB7XG5cdHByaXZhdGUgX2N1cnJlbnRMb2dnZXI6IEludGVybmFsTG9nZ2VyO1xuXHRwcml2YXRlIF9wZW5kaW5nTG9nUTogSUxvZ0l0ZW1bXSA9IFtdO1xuXG5cdGxvZyhtc2c6IHN0cmluZywgbGV2ZWwgPSBMb2dMZXZlbC5Mb2cpOiB2b2lkIHtcblx0XHRtc2cgPSBtc2cgKyAnXFxuJztcblx0XHR0aGlzLl93cml0ZShtc2csIGxldmVsKTtcblx0fVxuXG5cdHZlcmJvc2UobXNnOiBzdHJpbmcpOiB2b2lkIHtcblx0XHR0aGlzLmxvZyhtc2csIExvZ0xldmVsLlZlcmJvc2UpO1xuXHR9XG5cblx0d2Fybihtc2c6IHN0cmluZyk6IHZvaWQge1xuXHRcdHRoaXMubG9nKG1zZywgTG9nTGV2ZWwuV2Fybik7XG5cdH1cblxuXHRlcnJvcihtc2c6IHN0cmluZyk6IHZvaWQge1xuXHRcdHRoaXMubG9nKG1zZywgTG9nTGV2ZWwuRXJyb3IpO1xuXHR9XG5cblx0LyoqXG5cdCAqIGBsb2dgIGFkZHMgYSBuZXdsaW5lLCBgd3JpdGVgIGRvZXNuJ3Rcblx0ICovXG5cdHByaXZhdGUgX3dyaXRlKG1zZzogc3RyaW5nLCBsZXZlbCA9IExvZ0xldmVsLkxvZyk6IHZvaWQge1xuXHRcdC8vIFtudWxsLCB1bmRlZmluZWRdID0+IHN0cmluZ1xuXHRcdG1zZyA9IG1zZyArICcnO1xuXHRcdGlmICh0aGlzLl9wZW5kaW5nTG9nUSkge1xuXHRcdFx0dGhpcy5fcGVuZGluZ0xvZ1EucHVzaCh7IG1zZywgbGV2ZWwgfSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX2N1cnJlbnRMb2dnZXIubG9nKG1zZywgbGV2ZWwpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIGxvZ2dlcidzIG1pbmltdW0gbGV2ZWwgdG8gbG9nIGluIHRoZSBjb25zb2xlLCBhbmQgd2hldGhlciB0byBsb2cgdG8gdGhlIGZpbGUuIExvZyBtZXNzYWdlcyBhcmUgcXVldWVkIGJlZm9yZSB0aGlzIGlzXG5cdCAqIGNhbGxlZCB0aGUgZmlyc3QgdGltZSwgYmVjYXVzZSBtaW5Mb2dMZXZlbCBkZWZhdWx0cyB0byBXYXJuLlxuXHQgKi9cblx0c2V0dXAoY29uc29sZU1pbkxvZ0xldmVsOiBMb2dMZXZlbCwgbG9nVG9GaWxlOiBib29sZWFuKTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuX2N1cnJlbnRMb2dnZXIpIHtcblx0XHRcdHRoaXMuX2N1cnJlbnRMb2dnZXIuc2V0dXAoY29uc29sZU1pbkxvZ0xldmVsLCBsb2dUb0ZpbGUpO1xuXG5cdFx0XHQvLyBOb3cgdGhhdCB3ZSBoYXZlIGEgbWluaW11bSBsb2dMZXZlbCwgd2UgY2FuIGNsZWFyIG91dCB0aGUgcXVldWUgb2YgcGVuZGluZyBtZXNzYWdlc1xuXHRcdFx0aWYgKHRoaXMuX3BlbmRpbmdMb2dRKSB7XG5cdFx0XHRcdGNvbnN0IGxvZ1EgPSB0aGlzLl9wZW5kaW5nTG9nUTtcblx0XHRcdFx0dGhpcy5fcGVuZGluZ0xvZ1EgPSBudWxsO1xuXHRcdFx0XHRsb2dRLmZvckVhY2goaXRlbSA9PiB0aGlzLl93cml0ZShpdGVtLm1zZywgaXRlbS5sZXZlbCkpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGluaXQobG9nQ2FsbGJhY2s6IElMb2dDYWxsYmFjaywgbG9nRmlsZVBhdGg/OiBzdHJpbmcsIGxvZ1RvQ29uc29sZT86IGJvb2xlYW4pOiB2b2lkIHtcblx0XHQvLyBSZS1pbml0LCBjcmVhdGUgbmV3IGdsb2JhbCBMb2dnZXJcblx0XHR0aGlzLl9wZW5kaW5nTG9nUSA9IHRoaXMuX3BlbmRpbmdMb2dRIHx8IFtdO1xuXHRcdHRoaXMuX2N1cnJlbnRMb2dnZXIgPSBuZXcgSW50ZXJuYWxMb2dnZXIobG9nQ2FsbGJhY2ssIGxvZ0ZpbGVQYXRoLCBsb2dUb0NvbnNvbGUpO1xuXHRcdGlmIChsb2dGaWxlUGF0aCkge1xuXHRcdFx0Y29uc3QgZCA9IG5ldyBEYXRlKCk7XG5cdFx0XHRjb25zdCB0aW1lc3RhbXAgPSBkLnRvTG9jYWxlVGltZVN0cmluZygpICsgJywgJyArIGQudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG5cdFx0XHR0aGlzLnZlcmJvc2UodGltZXN0YW1wKTtcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IGxvZ2dlciA9IG5ldyBMb2dnZXIoKTtcblxuLyoqXG4gKiBNYW5hZ2VzIGxvZ2dpbmcsIHdoZXRoZXIgdG8gY29uc29sZS5sb2csIGZpbGUsIG9yIFZTIENvZGUgY29uc29sZS5cbiAqIEVuY2Fwc3VsYXRlcyB0aGUgc3RhdGUgc3BlY2lmaWMgdG8gZWFjaCBsb2dnaW5nIHNlc3Npb25cbiAqL1xuY2xhc3MgSW50ZXJuYWxMb2dnZXIge1xuXHQvKiogVGhlIHBhdGggb2YgdGhlIGxvZyBmaWxlICovXG5cdHByaXZhdGUgX2xvZ0ZpbGVQYXRoOiBzdHJpbmc7XG5cblx0cHJpdmF0ZSBfbWluTG9nTGV2ZWw6IExvZ0xldmVsO1xuXHRwcml2YXRlIF9sb2dUb0NvbnNvbGU6IGJvb2xlYW47XG5cblx0LyoqIExvZyBpbmZvIHRoYXQgbWVldHMgbWluTG9nTGV2ZWwgaXMgc2VudCB0byB0aGlzIGNhbGxiYWNrLiAqL1xuXHRwcml2YXRlIF9sb2dDYWxsYmFjazogSUxvZ0NhbGxiYWNrO1xuXG5cdC8qKiBXcml0ZSBzdGVhbSBmb3IgbG9nIGZpbGUgKi9cblx0cHJpdmF0ZSBfbG9nRmlsZVN0cmVhbTogZnMuV3JpdGVTdHJlYW07XG5cblx0Y29uc3RydWN0b3IobG9nQ2FsbGJhY2s6IElMb2dDYWxsYmFjaywgbG9nRmlsZVBhdGg/OiBzdHJpbmcsIGlzU2VydmVyPzogYm9vbGVhbikge1xuXHRcdHRoaXMuX2xvZ0NhbGxiYWNrID0gbG9nQ2FsbGJhY2s7XG5cdFx0dGhpcy5fbG9nRmlsZVBhdGggPSBsb2dGaWxlUGF0aDtcblx0XHR0aGlzLl9sb2dUb0NvbnNvbGUgPSBpc1NlcnZlcjtcblxuXHRcdHRoaXMuX21pbkxvZ0xldmVsID0gTG9nTGV2ZWwuV2Fybjtcblx0fVxuXG5cdHB1YmxpYyBzZXR1cChjb25zb2xlTWluTG9nTGV2ZWw6IExvZ0xldmVsLCBsb2dUb0ZpbGU6IGJvb2xlYW4pOiB2b2lkIHtcblx0XHR0aGlzLl9taW5Mb2dMZXZlbCA9IGNvbnNvbGVNaW5Mb2dMZXZlbDtcblxuXHRcdC8vIE9wZW4gYSBsb2cgZmlsZSBpbiB0aGUgc3BlY2lmaWVkIGxvY2F0aW9uLiBPdmVyd3JpdHRlbiBvbiBlYWNoIHJ1bi5cblx0XHRpZiAobG9nVG9GaWxlKSB7XG5cdFx0XHR0aGlzLmxvZyhgVmVyYm9zZSBsb2dzIGFyZSB3cml0dGVuIHRvOlxcbmAsIExvZ0xldmVsLldhcm4pO1xuXHRcdFx0dGhpcy5sb2codGhpcy5fbG9nRmlsZVBhdGggKyAnXFxuJywgTG9nTGV2ZWwuV2Fybik7XG5cblx0XHRcdHRoaXMuX2xvZ0ZpbGVTdHJlYW0gPSBmcy5jcmVhdGVXcml0ZVN0cmVhbSh0aGlzLl9sb2dGaWxlUGF0aCk7XG5cdFx0XHR0aGlzLl9sb2dGaWxlU3RyZWFtLm9uKCdlcnJvcicsIGUgPT4ge1xuXHRcdFx0XHR0aGlzLnNlbmRMb2coYEVycm9yIGludm9sdmluZyBsb2cgZmlsZSBhdCBwYXRoOiAke3RoaXMuX2xvZ0ZpbGVQYXRofS4gRXJyb3I6ICR7ZS50b1N0cmluZygpfWAsIExvZ0xldmVsLkVycm9yKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBsb2cobXNnOiBzdHJpbmcsIGxldmVsOiBMb2dMZXZlbCk6IHZvaWQge1xuXG5cdFx0aWYgKHRoaXMuX21pbkxvZ0xldmVsID09PSBMb2dMZXZlbC5TdG9wKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKGxldmVsID49IHRoaXMuX21pbkxvZ0xldmVsKSB7XG5cdFx0XHR0aGlzLnNlbmRMb2cobXNnLCBsZXZlbCk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX2xvZ1RvQ29uc29sZSkge1xuXHRcdFx0Y29uc3QgbG9nRm4gPVxuXHRcdFx0XHRsZXZlbCA9PT0gTG9nTGV2ZWwuRXJyb3IgPyBjb25zb2xlLmVycm9yIDpcblx0XHRcdFx0bGV2ZWwgPT09IExvZ0xldmVsLldhcm4gPyBjb25zb2xlLndhcm4gOlxuXHRcdFx0XHRjb25zb2xlLmxvZztcblx0XHRcdGxvZ0ZuKHRyaW1MYXN0TmV3bGluZShtc2cpKTtcblx0XHR9XG5cblx0XHQvLyBJZiBhbiBlcnJvciwgcHJlcGVuZCB3aXRoICdbRXJyb3JdJ1xuXHRcdGlmIChsZXZlbCA9PT0gTG9nTGV2ZWwuRXJyb3IpIHtcblx0XHRcdG1zZyA9IGBbJHtMb2dMZXZlbFtsZXZlbF19XSAke21zZ31gO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9sb2dGaWxlU3RyZWFtKSB7XG5cdFx0XHR0aGlzLl9sb2dGaWxlU3RyZWFtLndyaXRlKG1zZyk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBzZW5kTG9nKG1zZzogc3RyaW5nLCBsZXZlbDogTG9nTGV2ZWwpOiB2b2lkIHtcblx0XHQvLyBUcnVuY2F0ZSBsb25nIG1lc3NhZ2VzLCB0aGV5IGNhbiBoYW5nIFZTIENvZGVcblx0XHRpZiAobXNnLmxlbmd0aCA+IDE1MDApIHtcblx0XHRcdGNvbnN0IGVuZHNJbk5ld2xpbmUgPSAhIW1zZy5tYXRjaCgvKFxcbnxcXHJcXG4pJC8pO1xuXHRcdFx0bXNnID0gbXNnLnN1YnN0cigwLCAxNTAwKSArICdbLi4uXSc7XG5cdFx0XHRpZiAoZW5kc0luTmV3bGluZSkge1xuXHRcdFx0XHRtc2cgPSBtc2cgKyAnXFxuJztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAodGhpcy5fbG9nQ2FsbGJhY2spIHtcblx0XHRcdGNvbnN0IGV2ZW50ID0gbmV3IExvZ091dHB1dEV2ZW50KG1zZywgbGV2ZWwpO1xuXHRcdFx0dGhpcy5fbG9nQ2FsbGJhY2soZXZlbnQpO1xuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY2xhc3MgTG9nT3V0cHV0RXZlbnQgZXh0ZW5kcyBPdXRwdXRFdmVudCB7XG5cdGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nLCBsZXZlbDogTG9nTGV2ZWwpIHtcblx0XHRjb25zdCBjYXRlZ29yeSA9XG5cdFx0XHRsZXZlbCA9PT0gTG9nTGV2ZWwuRXJyb3IgPyAnc3RkZXJyJyA6XG5cdFx0XHRsZXZlbCA9PT0gTG9nTGV2ZWwuV2FybiA/ICdjb25zb2xlJyA6XG5cdFx0XHQnc3Rkb3V0Jztcblx0XHRzdXBlcihtc2csIGNhdGVnb3J5KTtcblx0fVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJpbUxhc3ROZXdsaW5lKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcblx0cmV0dXJuIHN0ci5yZXBsYWNlKC8oXFxufFxcclxcbikkLywgJycpO1xufVxuIl19