1
1
2
2
$peekBuf = $null
3
3
$currentLineNum = 1
4
+ $logEntryNum = 1
4
5
5
6
function Parse-PsesLog {
6
7
param (
@@ -9,24 +10,41 @@ function Parse-PsesLog {
9
10
[Alias (" PSPath" )]
10
11
[ValidateNotNullOrEmpty ()]
11
12
[string ]
12
- $Path
13
+ $Path ,
14
+
15
+ # Hides the progress bar.
16
+ [Parameter ()]
17
+ [switch ]
18
+ $HideProgress ,
19
+
20
+ # Skips conversion from JSON & storage of the JsonRpc message body which can be large.
21
+ [Parameter ()]
22
+ [switch ]
23
+ $SkipRpcMessageBody ,
24
+
25
+ [Parameter ()]
26
+ [switch ]
27
+ $DebugTimingInfo ,
28
+
29
+ [Parameter ()]
30
+ [int ]
31
+ $DebugTimingThresholdMs = 100
13
32
)
14
33
15
34
begin {
16
-
17
35
# Example log entry start:
18
36
# 2018-11-24 12:26:58.302 [DIAGNOSTIC] tid:28 in 'ReadMessage' C:\Users\Keith\GitHub\rkeithhill\PowerShellEditorServices\src\PowerShellEditorServices.Protocol\MessageProtocol\MessageReader.cs:114:
19
- $logEntryRegex =
37
+ $logEntryRegex =
20
38
[regex ]::new(
21
- ' (?<ts>[^\[]+)\[(?<lev>([^\]]+))\]\s+tid:(?<tid>\d+)\s+in\s+'' (?<meth>\w+)'' \s+(?<file>..[^:]+):(?<line>\d+)' ,
39
+ ' (?<ts>[^\[]+)\[(?<lev>([^\]]+))\]\s+tid:(?<tid>\d+)\s+in\s+'' (?<meth>\w+)'' \s+(?<file>..[^:]+):(?<line>\d+)' ,
22
40
[System.Text.RegularExpressions.RegexOptions ]::Compiled -bor [System.Text.RegularExpressions.RegexOptions ]::IgnoreCase)
23
41
24
- $filestream =
42
+ $filestream =
25
43
[System.IO.FileStream ]::new(
26
- $Path ,
27
- [System.IO.FileMode ]:: Open,
28
- [System.IO.FileAccess ]::Read,
29
- [System.IO.FileShare ]::ReadWrite,
44
+ $Path ,
45
+ [System.IO.FileMode ]:: Open,
46
+ [System.IO.FileAccess ]::Read,
47
+ [System.IO.FileShare ]::ReadWrite,
30
48
4096 ,
31
49
[System.IO.FileOptions ]::SequentialScan)
32
50
@@ -41,7 +59,7 @@ function Parse-PsesLog {
41
59
$line = $streamReader.ReadLine ()
42
60
}
43
61
44
- $script :currentLineNum += 1
62
+ $script :currentLineNum ++
45
63
$line
46
64
}
47
65
@@ -55,25 +73,42 @@ function Parse-PsesLog {
55
73
56
74
$line
57
75
}
58
-
76
+
59
77
function parseLogEntryStart ([string ]$line ) {
78
+ if ($DebugTimingInfo ) {
79
+ $sw = [System.Diagnostics.Stopwatch ]::StartNew()
80
+ }
81
+
60
82
while ($line -notmatch $logEntryRegex ) {
61
83
Write-Warning " Ignoring line: '$line '"
62
84
$line = nextLine
63
85
}
64
-
86
+
87
+ if (! $HideProgress -and ($script :logEntryNum % 50 -eq 0 )) {
88
+ Write-Progress " Processing log entry ${ script:logEntryNum } on line: ${ script:currentLineNum } "
89
+ }
90
+
65
91
[string ]$timestampStr = $matches [" ts" ]
66
92
[DateTime ]$timestamp = $timestampStr
67
93
[PsesLogLevel ]$logLevel = $matches [" lev" ]
68
94
[int ]$threadId = $matches [" tid" ]
69
95
[string ]$method = $matches [" meth" ]
70
96
[string ]$file = $matches [" file" ]
71
97
[int ]$lineNumber = $matches [" line" ]
72
-
98
+
73
99
$message = parseMessage $method
74
100
75
- [PsesLogEntry ]::new($timestamp , $timestampStr , $logLevel , $threadId , $method , $file , $lineNumber ,
101
+ [PsesLogEntry ]::new($timestamp , $timestampStr , $logLevel , $threadId , $method , $file , $lineNumber ,
76
102
$message.MessageType , $message.Message )
103
+
104
+ if ($DebugTimingInfo ) {
105
+ $sw.Stop ()
106
+ if ($sw.ElapsedMilliseconds -gt $DebugTimingThresholdMs ) {
107
+ Write-Warning " Time to parse log entry ${ script:logEntryNum } - $ ( $sw.ElapsedMilliseconds ) ms"
108
+ }
109
+ }
110
+
111
+ $script :logEntryNum ++
77
112
}
78
113
79
114
function parseMessage ([string ]$Method ) {
@@ -88,30 +123,30 @@ function Parse-PsesLog {
88
123
return $result
89
124
}
90
125
91
- if (($Method -eq ' ReadMessage' ) -and
126
+ if (($Method -eq ' ReadMessage' ) -and
92
127
($line -match ' \s+Received Request '' (?<msg>[^'' ]+)'' with id (?<id>\d+)' )) {
93
128
$result.MessageType = [PsesMessageType ]::Request
94
129
$msg = $matches [" msg" ]
95
130
$id = $matches [" id" ]
96
131
$json = parseJsonMessageBody
97
132
$result.Message = [PsesJsonRpcMessage ]::new($msg , $id , $json )
98
133
}
99
- elseif (($Method -eq ' ReadMessage' ) -and
134
+ elseif (($Method -eq ' ReadMessage' ) -and
100
135
($line -match ' \s+Received event '' (?<msg>[^'' ]+)'' ' )) {
101
136
$result.MessageType = [PsesMessageType ]::Notification
102
137
$msg = $matches [" msg" ]
103
138
$json = parseJsonMessageBody
104
139
$result.Message = [PsesNotificationMessage ]::new($msg , [PsesNotificationSource ]::Client, $json )
105
140
}
106
- elseif (($Method -eq ' WriteMessage' ) -and
141
+ elseif (($Method -eq ' WriteMessage' ) -and
107
142
($line -match ' \s+Writing Response '' (?<msg>[^'' ]+)'' with id (?<id>\d+)' )) {
108
143
$result.MessageType = [PsesMessageType ]::Response
109
144
$msg = $matches [" msg" ]
110
145
$id = $matches [" id" ]
111
146
$json = parseJsonMessageBody
112
147
$result.Message = [PsesJsonRpcMessage ]::new($msg , $id , $json )
113
148
}
114
- elseif (($Method -eq ' WriteMessage' ) -and
149
+ elseif (($Method -eq ' WriteMessage' ) -and
115
150
($line -match ' \s+Writing event '' (?<msg>[^'' ]+)'' ' )) {
116
151
$result.MessageType = [PsesMessageType ]::Notification
117
152
$msg = $matches [" msg" ]
@@ -127,35 +162,54 @@ function Parse-PsesLog {
127
162
$result
128
163
}
129
164
130
- function parseMessageBody ([string ]$startLine = ' ' ) {
131
- $result = $startLine
165
+ function parseMessageBody ([string ]$startLine = ' ' , [switch ]$Discard ) {
166
+ if (! $Discard ) {
167
+ $strBld = [System.Text.StringBuilder ]::new($startLine , 4096 )
168
+ $newLine = " `r`n "
169
+ }
170
+
132
171
try {
133
172
while ($true ) {
134
173
$peekLine = peekLine
135
174
if ($null -eq $peekLine ) {
136
175
break
137
176
}
138
177
139
- if ($peekLine - match $logEntryRegex ) {
178
+ if (( $peekLine.Length -gt 0 ) -and ( $peekLine [ 0 ] -ne ' ' ) -and ( $peekLine - match $logEntryRegex ) ) {
140
179
break
141
180
}
142
181
143
- $result += (nextLine) + " `r`n "
182
+ $nextLine = nextLine
183
+ if (! $Discard ) {
184
+ [void ]$strBld.Append ($nextLine ).Append($newLine )
185
+ }
144
186
}
145
-
146
187
}
147
188
catch {
148
189
Write-Error " Failed parsing message body with error: $_ "
149
190
}
150
191
151
- $result.Trim ()
192
+ if (! $Discard ) {
193
+ $msgBody = $strBld.ToString ().Trim()
194
+ $msgBody
195
+ }
196
+ else {
197
+ $startLine
198
+ }
152
199
}
153
200
154
201
function parseJsonMessageBody () {
155
202
$obj = $null
156
203
157
- try {
204
+ if ($SkipRpcMessageBody ) {
205
+ parseMessageBody - Discard
206
+ return $null
207
+ }
208
+ else {
158
209
$result = parseMessageBody
210
+ }
211
+
212
+ try {
159
213
$obj = $result.Trim () | ConvertFrom-Json
160
214
}
161
215
catch {
0 commit comments