@@ -17,19 +17,21 @@ import configuration from "../configuration";
17
17
18
18
export class SwiftOutputChannel implements vscode . OutputChannel {
19
19
private channel : vscode . OutputChannel ;
20
- private logStore = new RollingLog ( 1024 * 1024 * 5 ) ;
21
- private logToConsole : boolean ;
22
-
23
- public name : string ;
20
+ private logStore : RollingLog ;
24
21
25
22
/**
26
23
* Creates a vscode.OutputChannel that allows for later retrival of logs.
27
24
* @param name
28
25
*/
29
- constructor ( name : string , logToConsole : boolean = true ) {
26
+ constructor (
27
+ public name : string ,
28
+ private logToConsole : boolean = true ,
29
+ logStoreLinesSize : number = 250_000 // default to capturing 250k log lines
30
+ ) {
30
31
this . name = name ;
31
32
this . logToConsole = process . env [ "CI" ] !== "1" && logToConsole ;
32
33
this . channel = vscode . window . createOutputChannel ( name ) ;
34
+ this . logStore = new RollingLog ( logStoreLinesSize ) ;
33
35
}
34
36
35
37
append ( value : string ) : void {
@@ -109,40 +111,52 @@ export class SwiftOutputChannel implements vscode.OutputChannel {
109
111
}
110
112
111
113
class RollingLog {
112
- private _logs : string [ ] = [ ] ;
113
- private currentLogLength : number = 0 ;
114
+ private _logs : ( string | null ) [ ] ;
115
+ private startIndex : number = 0 ;
116
+ private endIndex : number = 0 ;
117
+ private logCount : number = 0 ;
114
118
115
- constructor ( private maxSizeCharacters : number ) { }
119
+ constructor ( private maxLogs : number ) {
120
+ this . _logs = new Array ( maxLogs ) . fill ( null ) ;
121
+ }
116
122
117
123
public get logs ( ) : string [ ] {
118
- return [ ...this . _logs ] ;
124
+ const logs : string [ ] = [ ] ;
125
+ for ( let i = 0 ; i < this . logCount ; i ++ ) {
126
+ logs . push ( this . _logs [ ( this . startIndex + i ) % this . maxLogs ] ! ) ;
127
+ }
128
+ return logs ;
129
+ }
130
+
131
+ private incrementIndex ( index : number ) : number {
132
+ return ( index + 1 ) % this . maxLogs ;
119
133
}
120
134
121
135
appendLine ( log : string ) {
122
- // It can be costly to calculate the actual memory size of a string in Node so just
123
- // use the total number of characters in the logs as a huristic for total size.
124
- const logSize = log . length ;
125
-
126
- while ( this . currentLogLength + logSize > this . maxSizeCharacters && this . logs . length > 0 ) {
127
- const oldestLog = this . logs . shift ( ) ;
128
- if ( oldestLog ) {
129
- this . currentLogLength -= oldestLog . length ;
130
- }
136
+ if ( this . logCount === this . maxLogs ) {
137
+ this . startIndex = this . incrementIndex ( this . startIndex ) ;
138
+ } else {
139
+ this . logCount ++ ;
131
140
}
132
141
133
- this . _logs . push ( log ) ;
134
-
135
- this . currentLogLength += logSize ;
142
+ this . _logs [ this . endIndex ] = log ;
143
+ this . endIndex = this . incrementIndex ( this . endIndex ) ;
136
144
}
137
145
138
146
append ( log : string ) {
139
- const line = this . _logs . pop ( ) ;
140
- this . currentLogLength -= line ?. length ?? 0 ;
141
- this . appendLine ( ( line ?? "" ) + log ) ;
147
+ const endIndex = this . endIndex - 1 < 0 ? Math . max ( this . logCount - 1 , 0 ) : this . endIndex ;
148
+ if ( this . _logs [ endIndex ] === null ) {
149
+ this . logCount = 1 ;
150
+ }
151
+ const newLogLine = ( this . _logs [ endIndex ] ?? "" ) + log ;
152
+ this . _logs [ endIndex ] = newLogLine ;
142
153
}
143
154
144
155
replace ( log : string ) {
145
- this . _logs = [ log ] ;
146
- this . currentLogLength = log . length ;
156
+ this . _logs = new Array ( this . maxLogs ) . fill ( null ) ;
157
+ this . _logs [ 0 ] = log ;
158
+ this . startIndex = 0 ;
159
+ this . endIndex = 1 ;
160
+ this . logCount = 1 ;
147
161
}
148
162
}
0 commit comments