@@ -5,6 +5,7 @@ import utils = require("./utils");
5
5
import os = require( "os" ) ;
6
6
import vscode = require( "vscode" ) ;
7
7
8
+ // NOTE: This is not a string enum because the order is used for comparison.
8
9
export enum LogLevel {
9
10
Diagnostic ,
10
11
Verbose ,
@@ -27,17 +28,29 @@ export interface ILogger {
27
28
}
28
29
29
30
export class Logger implements ILogger {
30
- public logBasePath : vscode . Uri ;
31
- public logSessionPath : vscode . Uri | undefined ;
32
- public MinimumLogLevel : LogLevel = LogLevel . Normal ;
31
+ public logDirectoryPath : vscode . Uri ;
33
32
33
+ private logLevel : LogLevel ;
34
34
private commands : vscode . Disposable [ ] ;
35
35
private logChannel : vscode . OutputChannel ;
36
- private logFilePath : vscode . Uri | undefined ;
36
+ private logFilePath : vscode . Uri ;
37
+ private logDirectoryCreated = false ;
37
38
38
- constructor ( logBasePath : vscode . Uri ) {
39
+ constructor ( logLevelName : string , globalStorageUri : vscode . Uri ) {
40
+ this . logLevel = Logger . logLevelNameToValue ( logLevelName ) ;
39
41
this . logChannel = vscode . window . createOutputChannel ( "PowerShell Extension Logs" ) ;
40
- this . logBasePath = vscode . Uri . joinPath ( logBasePath , "logs" ) ;
42
+ this . logDirectoryPath = vscode . Uri . joinPath (
43
+ globalStorageUri ,
44
+ "logs" ,
45
+ `${ Math . floor ( Date . now ( ) / 1000 ) } -${ vscode . env . sessionId } ` ) ;
46
+ this . logFilePath = this . getLogFilePath ( "vscode-powershell" ) ;
47
+
48
+ // Early logging of the log paths for debugging.
49
+ if ( LogLevel . Diagnostic >= this . logLevel ) {
50
+ const uriMessage = Logger . timestampMessage ( `Global storage URI: '${ globalStorageUri } ', log file path: '${ this . logFilePath } '` , LogLevel . Diagnostic ) ;
51
+ this . logChannel . appendLine ( uriMessage ) ;
52
+ }
53
+
41
54
this . commands = [
42
55
vscode . commands . registerCommand (
43
56
"PowerShell.ShowLogs" ,
@@ -57,11 +70,11 @@ export class Logger implements ILogger {
57
70
}
58
71
59
72
public getLogFilePath ( baseName : string ) : vscode . Uri {
60
- return vscode . Uri . joinPath ( this . logSessionPath ! , `${ baseName } .log` ) ;
73
+ return vscode . Uri . joinPath ( this . logDirectoryPath , `${ baseName } .log` ) ;
61
74
}
62
75
63
76
private writeAtLevel ( logLevel : LogLevel , message : string , ...additionalMessages : string [ ] ) : void {
64
- if ( logLevel >= this . MinimumLogLevel ) {
77
+ if ( logLevel >= this . logLevel ) {
65
78
void this . writeLine ( message , logLevel ) ;
66
79
67
80
for ( const additionalMessage of additionalMessages ) {
@@ -140,20 +153,8 @@ export class Logger implements ILogger {
140
153
}
141
154
}
142
155
143
- public async startNewLog ( minimumLogLevel = "Normal" ) : Promise < void > {
144
- this . MinimumLogLevel = Logger . logLevelNameToValue ( minimumLogLevel ) ;
145
-
146
- this . logSessionPath =
147
- vscode . Uri . joinPath (
148
- this . logBasePath ,
149
- `${ Math . floor ( Date . now ( ) / 1000 ) } -${ vscode . env . sessionId } ` ) ;
150
-
151
- this . logFilePath = this . getLogFilePath ( "vscode-powershell" ) ;
152
- await vscode . workspace . fs . createDirectory ( this . logSessionPath ) ;
153
- }
154
-
155
156
// TODO: Make the enum smarter about strings so this goes away.
156
- public static logLevelNameToValue ( logLevelName : string ) : LogLevel {
157
+ private static logLevelNameToValue ( logLevelName : string ) : LogLevel {
157
158
switch ( logLevelName . trim ( ) . toLowerCase ( ) ) {
158
159
case "diagnostic" : return LogLevel . Diagnostic ;
159
160
case "verbose" : return LogLevel . Verbose ;
@@ -165,27 +166,40 @@ export class Logger implements ILogger {
165
166
}
166
167
}
167
168
169
+ public updateLogLevel ( logLevelName : string ) : void {
170
+ this . logLevel = Logger . logLevelNameToValue ( logLevelName ) ;
171
+ }
172
+
168
173
private showLogPanel ( ) : void {
169
174
this . logChannel . show ( ) ;
170
175
}
171
176
172
177
private async openLogFolder ( ) : Promise < void > {
173
- if ( this . logSessionPath ) {
178
+ if ( this . logDirectoryCreated ) {
174
179
// Open the folder in VS Code since there isn't an easy way to
175
180
// open the folder in the platform's file browser
176
- await vscode . commands . executeCommand ( "vscode.openFolder" , this . logSessionPath , true ) ;
181
+ await vscode . commands . executeCommand ( "vscode.openFolder" , this . logDirectoryPath , true ) ;
182
+ } else {
183
+ void this . writeAndShowError ( "Cannot open PowerShell log directory as it does not exist!" ) ;
177
184
}
178
185
}
179
186
180
- // TODO: Should we await this function above?
181
- private async writeLine ( message : string , level : LogLevel = LogLevel . Normal ) : Promise < void > {
187
+ private static timestampMessage ( message : string , level : LogLevel ) : string {
182
188
const now = new Date ( ) ;
183
- const timestampedMessage =
184
- ` ${ now . toLocaleDateString ( ) } ${ now . toLocaleTimeString ( ) } [ ${ LogLevel [ level ] . toUpperCase ( ) } ] - ${ message } ${ os . EOL } ` ;
189
+ return ` ${ now . toLocaleDateString ( ) } ${ now . toLocaleTimeString ( ) } [ ${ LogLevel [ level ] . toUpperCase ( ) } ] - ${ message } ${ os . EOL } ` ;
190
+ }
185
191
192
+ // TODO: Should we await this function above?
193
+ private async writeLine ( message : string , level : LogLevel = LogLevel . Normal ) : Promise < void > {
194
+ const timestampedMessage = Logger . timestampMessage ( message , level ) ;
186
195
this . logChannel . appendLine ( timestampedMessage ) ;
187
- if ( this . logFilePath && this . MinimumLogLevel !== LogLevel . None ) {
196
+ if ( this . logLevel !== LogLevel . None ) {
188
197
try {
198
+ if ( ! this . logDirectoryCreated ) {
199
+ this . logChannel . appendLine ( Logger . timestampMessage ( `Creating log directory at: '${ this . logDirectoryPath } '` , level ) ) ;
200
+ await vscode . workspace . fs . createDirectory ( this . logDirectoryPath ) ;
201
+ this . logDirectoryCreated = await utils . checkIfDirectoryExists ( this . logDirectoryPath ) ;
202
+ }
189
203
let log = new Uint8Array ( ) ;
190
204
if ( await utils . checkIfFileExists ( this . logFilePath ) ) {
191
205
log = await vscode . workspace . fs . readFile ( this . logFilePath ) ;
0 commit comments