@@ -100,136 +100,91 @@ switch($Command.ToLowerInvariant()){
100100 ' trace-flame' {
101101 Ensure- Tool ' dotnet-counters' ' dotnet-counters'
102102 Ensure- Tool ' dotnet-trace' ' dotnet-trace'
103- $script :DotNetOnly = $true
104- # Duration selection (interactive)
105- $durationsMap = [ordered ]@ { ' 10 sec' = ' 00:00:10' ; ' 30 sec' = ' 00:00:30' ; ' 1 min' = ' 00:01:00' ; ' 5 min' = ' 00:05:00' }
106- $duration = $durationsMap [' 10 sec' ]
107- try {
108- Import-Module PwshSpectreConsole - ErrorAction Stop
109- $choice = Read-SpectreSelection - Title ' Select flame trace duration' - Choices ($durationsMap.Keys + ' Cancel' ) - EnableSearch - PageSize 10
110- if ($choice -and $choice -ne ' Cancel' ){ $duration = $durationsMap [$choice ] }
111- if ($choice -eq ' Cancel' ){ Write-Host ' Flame trace cancelled.' - ForegroundColor Yellow; break }
112- } catch { Write-Host ' Spectre selection unavailable; using default 10 sec.' - ForegroundColor Yellow }
113- $procId = Select-Pid ' Select process to trace (flame)'
114- if (-not $procId ){ Write-Host ' No PID selected.' - ForegroundColor Yellow; break }
103+ $script :DotNetOnly = $true
104+ $durationsMap = [ordered ]@ { ' 10 sec' = ' 00:00:10' ; ' 30 sec' = ' 00:00:30' ; ' 1 min' = ' 00:01:00' ; ' 5 min' = ' 00:05:00' }
105+ $duration = $durationsMap [' 10 sec' ]
106+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; $choice = Read-SpectreSelection - Title ' Select flame trace duration' - Choices ($durationsMap.Keys + ' Cancel' ) - EnableSearch - PageSize 10 ; if ($choice -and $choice -ne ' Cancel' ){ $duration = $durationsMap [$choice ] }; if ($choice -eq ' Cancel' ){ Write-Host ' Flame trace cancelled.' - ForegroundColor Yellow; break } } catch { Write-Host ' Spectre selection unavailable; using default 10 sec.' - ForegroundColor Yellow }
107+ $procId = Select-Pid ' Select process to trace (flame)'
108+ if (-not $procId ){ Write-Host ' No PID selected.' - ForegroundColor Yellow; break }
115109 $outDir = Join-Path $PSScriptRoot ' ..' ' .tmp' ' diagnostics'
116110 New-Item - ItemType Directory - Force - Path $outDir | Out-Null
117- $fileBase = " trace_${procId} _$ ( Get-Date - Format ' yyyyMMdd_HHmmss' ) "
118- $traceFile = Join-Path $outDir " $fileBase .nettrace"
119- $speedFile = Join-Path $outDir " $fileBase "
120- Write-Host " Collecting flame trace (SampleProfiler, $duration ) for PID $procId ..." - ForegroundColor Cyan
121- & dotnet- trace collect -- process- id $procId -- providers Microsoft- DotNETCore- SampleProfiler:1 -- duration $duration - o $traceFile
122- if ($LASTEXITCODE -ne 0 ){
123- Write-Host ' SampleProfiler provider failed, retrying with default trace config (cpu+gc)...' - ForegroundColor Yellow
124- & dotnet- trace collect -- process- id $procId -- duration $duration - o $traceFile
125- if ($LASTEXITCODE -ne 0 ){ throw ' Trace collection failed (fallback also failed)' }
126- }
111+ $fileBase = " trace_${procId} _$ ( Get-Date - Format ' yyyyMMdd_HHmmss' ) "
112+ $traceFile = Join-Path $outDir " $fileBase .nettrace"
113+ $speedBase = Join-Path $outDir $fileBase
114+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; @ ( ' Flame Trace' , ' PID: ' + $procId , ' Duration: ' + $duration , ' Providers: SampleProfiler' , ' Artifacts Base: ' + $fileBase ) | Format-SpectreRows | Format-SpectrePanel - Expand } catch {}
115+ Write-Host " Collecting flame trace (SampleProfiler, $duration ) for PID $procId ..." - ForegroundColor Cyan
116+ & dotnet- trace collect -- process- id $procId -- providers Microsoft- DotNETCore- SampleProfiler:1 -- duration $duration - o $traceFile
117+ if ($LASTEXITCODE -ne 0 ){ Write-Host ' SampleProfiler provider failed, retrying with default trace config (cpu+gc)...' - ForegroundColor Yellow; & dotnet- trace collect -- process- id $procId -- duration $duration - o $traceFile ; if ($LASTEXITCODE -ne 0 ){ throw ' Trace collection failed (fallback also failed)' } }
127118 Write-Host ' Converting to speedscope...' - ForegroundColor Cyan
128- & dotnet- trace convert -- format SpeedScope $traceFile - o $speedFile
119+ & dotnet- trace convert -- format SpeedScope $traceFile - o $speedBase
129120 if ($LASTEXITCODE -ne 0 ){ throw ' Trace conversion failed' }
130- Write-Host " Trace complete: $traceFile " - ForegroundColor Green
131- Write-Host " Speedscope file: $speedFile " - ForegroundColor Green
132- # Auto-open speedscope view
133- try {
134- $speedFile = $speedFile + ' .speedscope.json'
135- $resolvedSpeed = (Resolve-Path $speedFile ).Path
136- if (-not (Test-Path $resolvedSpeed )) { throw " Speedscope file not found: $resolvedSpeed " }
137- if (Get-Command npx - ErrorAction SilentlyContinue){
138- Write-Host " Opening speedscope (npx) -> $resolvedSpeed " - ForegroundColor Cyan
139- & npx speedscope " $resolvedSpeed "
140- if ($LASTEXITCODE -ne 0 ){ Write-Host ' npx speedscope returned non-zero; fallback to browser.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) }
141- } else {
142- Write-Host ' npx not available; opening speedscope.app and folder.' - ForegroundColor Yellow
143- Start-Process ' https://www.speedscope.app'
144- Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent)
145- }
146- } catch { Write-Host " Speedscope auto-open failed: $ ( $_.Exception.Message ) " - ForegroundColor Yellow }
121+ Write-Host " Trace complete: $traceFile " - ForegroundColor Green
122+ $speedFile = $speedBase + ' .speedscope.json'
123+ if (Test-Path " $speedFile .speedscope.json" ){ Move-Item - Force " $speedFile .speedscope.json" $speedFile }
124+ Write-Host " Speedscope file: $speedFile " - ForegroundColor Green
125+ if (-not $env: TRACE_NO_VIEW ){
126+ try { $resolvedSpeed = (Resolve-Path $speedFile ).Path; if (-not (Test-Path $resolvedSpeed )){ throw " Speedscope file not found: $resolvedSpeed " }; if (Get-Command npx - ErrorAction SilentlyContinue){ Write-Host " Opening speedscope (npx) -> $resolvedSpeed " - ForegroundColor Cyan; & npx speedscope " $resolvedSpeed " ; if ($LASTEXITCODE -ne 0 ){ Write-Host ' npx speedscope returned non-zero; fallback to browser.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) } } else { Write-Host ' npx not available; opening speedscope.app and folder.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) } } catch { Write-Host " Speedscope auto-open failed: $ ( $_.Exception.Message ) " - ForegroundColor Yellow }
127+ } else { Write-Host ' TRACE_NO_VIEW set; skipping auto-open.' - ForegroundColor DarkYellow }
147128 }
148129 ' trace-cpu' {
149130 Ensure- Tool ' dotnet-trace' ' dotnet-trace'
150131 $script :DotNetOnly = $true
151- # Duration selection (interactive)
152132 $durationsMap = [ordered ]@ { ' 10 sec' = ' 00:00:10' ; ' 30 sec' = ' 00:00:30' ; ' 1 min' = ' 00:01:00' ; ' 5 min' = ' 00:05:00' }
153133 $duration = $durationsMap [' 10 sec' ]
154- try {
155- Import-Module PwshSpectreConsole - ErrorAction Stop
156- $choice = Read-SpectreSelection - Title ' Select trace duration' - Choices ($durationsMap.Keys + ' Cancel' ) - EnableSearch - PageSize 10
157- if ($choice -and $choice -ne ' Cancel' ){ $duration = $durationsMap [$choice ] }
158- if ($choice -eq ' Cancel' ){ Write-Host ' CPU trace cancelled.' - ForegroundColor Yellow; break }
159- } catch { Write-Host ' Spectre selection unavailable; using default 10 sec.' - ForegroundColor Yellow }
134+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; $choice = Read-SpectreSelection - Title ' Select trace duration' - Choices ($durationsMap.Keys + ' Cancel' ) - EnableSearch - PageSize 10 ; if ($choice -and $choice -ne ' Cancel' ){ $duration = $durationsMap [$choice ] }; if ($choice -eq ' Cancel' ){ Write-Host ' CPU trace cancelled.' - ForegroundColor Yellow; break } } catch { Write-Host ' Spectre selection unavailable; using default 10 sec.' - ForegroundColor Yellow }
160135 $procId = Select-Pid ' Select process for CPU trace'
161136 if (-not $procId ){ Write-Host ' No PID selected.' - ForegroundColor Yellow; break }
162137 $outDir = Join-Path $PSScriptRoot ' ..' ' .tmp' ' diagnostics'
163138 New-Item - ItemType Directory - Force - Path $outDir | Out-Null
164139 $fileBase = " cpu_${procId} _$ ( Get-Date - Format ' yyyyMMdd_HHmmss' ) "
165140 $traceFile = Join-Path $outDir " $fileBase .nettrace"
166- $speedFile = Join-Path $outDir " $fileBase "
167- Write-Host " Collecting CPU trace (SampleProfiler, $duration ) for PID $procId ..." - ForegroundColor Cyan
168- & dotnet- trace collect -- process- id $procId -- providers Microsoft- DotNETCore- SampleProfiler:1 -- duration $duration - o $traceFile
141+ $speedBase = Join-Path $outDir $fileBase
142+ $extended = $false
143+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; $provChoice = Read-SpectreSelection - Title ' Include extended runtime providers?' - Choices @ (' No' , ' Yes' , ' Cancel' ) - EnableSearch - PageSize 5 ; if ($provChoice -eq ' Cancel' ){ Write-Host ' CPU trace cancelled.' - ForegroundColor Yellow; break }; if ($provChoice -eq ' Yes' ){ $extended = $true } } catch { Write-Host ' Provider selection skipped (Spectre unavailable).' - ForegroundColor Yellow }
144+ $providers = ' Microsoft-DotNETCore-SampleProfiler:1,System.Runtime:4'
145+ if ($extended ){ $providers += ' ,Microsoft-DotNETCore-EventSource:5' }
146+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; @ ( ' CPU Trace' , ' PID: ' + $procId , ' Duration: ' + $duration , ' Providers: ' + $providers , ' Extended: ' + $extended , ' Artifacts Base: ' + $fileBase ) | Format-SpectreRows | Format-SpectrePanel - Expand } catch {}
147+ Write-Host " Collecting CPU trace ($providers , $duration ) for PID $procId ..." - ForegroundColor Cyan
148+ & dotnet- trace collect -- process- id $procId -- providers $providers -- duration $duration - o $traceFile
169149 if ($LASTEXITCODE -ne 0 ){ throw ' CPU trace collection failed' }
170150 Write-Host ' Converting to speedscope...' - ForegroundColor Cyan
171- & dotnet- trace convert -- format SpeedScope $traceFile - o $speedFile
151+ & dotnet- trace convert -- format SpeedScope $traceFile - o $speedBase
172152 if ($LASTEXITCODE -ne 0 ){ throw ' CPU trace conversion failed' }
173153 Write-Host " CPU trace complete: $traceFile " - ForegroundColor Green
154+ $speedFile = $speedBase + ' .speedscope.json'
155+ if (Test-Path " $speedFile .speedscope.json" ){ Move-Item - Force " $speedFile .speedscope.json" $speedFile }
174156 Write-Host " Speedscope file: $speedFile " - ForegroundColor Green
175- # Auto-open speedscope view
176- try {
177- $speedFile = $speedFile + ' .speedscope.json'
178- $resolvedSpeed = (Resolve-Path $speedFile ).Path
179- if (-not (Test-Path $resolvedSpeed )) { throw " Speedscope file not found: $resolvedSpeed " }
180- if (Get-Command npx - ErrorAction SilentlyContinue){
181- Write-Host " Opening speedscope (npx) -> $resolvedSpeed " - ForegroundColor Cyan
182- & npx speedscope " $resolvedSpeed "
183- if ($LASTEXITCODE -ne 0 ){ Write-Host ' npx speedscope returned non-zero; fallback to browser.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) }
184- } else {
185- Write-Host ' npx not available; opening speedscope.app and folder.' - ForegroundColor Yellow
186- Start-Process ' https://www.speedscope.app'
187- Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent)
188- }
189- } catch { Write-Host " Speedscope auto-open failed: $ ( $_.Exception.Message ) " - ForegroundColor Yellow }
157+ if (-not $env: TRACE_NO_VIEW ){
158+ try { $resolvedSpeed = (Resolve-Path $speedFile ).Path; if (-not (Test-Path $resolvedSpeed )){ throw " Speedscope file not found: $resolvedSpeed " }; if (Get-Command npx - ErrorAction SilentlyContinue){ Write-Host " Opening speedscope (npx) -> $resolvedSpeed " - ForegroundColor Cyan; & npx speedscope " $resolvedSpeed " ; if ($LASTEXITCODE -ne 0 ){ Write-Host ' npx speedscope returned non-zero; fallback to browser.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) } } else { Write-Host ' npx not available; opening speedscope.app and folder.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) } } catch { Write-Host " Speedscope auto-open failed: $ ( $_.Exception.Message ) " - ForegroundColor Yellow }
159+ } else { Write-Host ' TRACE_NO_VIEW set; skipping auto-open.' - ForegroundColor DarkYellow }
190160 }
191161 ' trace-gc' {
192162 Ensure- Tool ' dotnet-trace' ' dotnet-trace'
193163 $script :DotNetOnly = $true
194- # Duration selection (interactive)
195164 $durationsMap = [ordered ]@ { ' 10 sec' = ' 00:00:10' ; ' 30 sec' = ' 00:00:30' ; ' 1 min' = ' 00:01:00' ; ' 5 min' = ' 00:05:00' }
196165 $duration = $durationsMap [' 10 sec' ]
197- try {
198- Import-Module PwshSpectreConsole - ErrorAction Stop
199- $choice = Read-SpectreSelection - Title ' Select GC trace duration' - Choices ($durationsMap.Keys + ' Cancel' ) - EnableSearch - PageSize 10
200- if ($choice -and $choice -ne ' Cancel' ){ $duration = $durationsMap [$choice ] }
201- if ($choice -eq ' Cancel' ){ Write-Host ' GC trace cancelled.' - ForegroundColor Yellow; break }
202- } catch { Write-Host ' Spectre selection unavailable; using default 10 sec.' - ForegroundColor Yellow }
166+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; $choice = Read-SpectreSelection - Title ' Select GC trace duration' - Choices ($durationsMap.Keys + ' Cancel' ) - EnableSearch - PageSize 10 ; if ($choice -and $choice -ne ' Cancel' ){ $duration = $durationsMap [$choice ] }; if ($choice -eq ' Cancel' ){ Write-Host ' GC trace cancelled.' - ForegroundColor Yellow; break } } catch { Write-Host ' Spectre selection unavailable; using default 10 sec.' - ForegroundColor Yellow }
203167 $procId = Select-Pid ' Select process for GC-focused trace'
204168 if (-not $procId ){ Write-Host ' No PID selected.' - ForegroundColor Yellow; break }
205169 $outDir = Join-Path $PSScriptRoot ' ..' ' .tmp' ' diagnostics'
206170 New-Item - ItemType Directory - Force - Path $outDir | Out-Null
207171 $fileBase = " gc_${procId} _$ ( Get-Date - Format ' yyyyMMdd_HHmmss' ) "
208172 $traceFile = Join-Path $outDir " $fileBase .nettrace"
209- $speedFile = Join-Path $outDir " $fileBase "
173+ $speedBase = Join-Path $outDir $fileBase
174+ try { Import-Module PwshSpectreConsole - ErrorAction Stop; @ ( ' GC Trace' , ' PID: ' + $procId , ' Duration: ' + $duration , ' Providers: SampleProfiler + System.Runtime' , ' Artifacts Base: ' + $fileBase ) | Format-SpectreRows | Format-SpectrePanel - Expand } catch {}
210175 Write-Host " Collecting GC-focused trace (SampleProfiler + System.Runtime, $duration ) for PID $procId ..." - ForegroundColor Cyan
211176 & dotnet- trace collect -- process- id $procId -- providers Microsoft- DotNETCore- SampleProfiler:1 , System.Runtime:4 -- duration $duration - o $traceFile
212177 if ($LASTEXITCODE -ne 0 ){ throw ' GC trace collection failed' }
213178 Write-Host ' Converting to speedscope...' - ForegroundColor Cyan
214- & dotnet- trace convert -- format SpeedScope $traceFile - o $speedFile
179+ & dotnet- trace convert -- format SpeedScope $traceFile - o $speedBase
215180 if ($LASTEXITCODE -ne 0 ){ throw ' GC trace conversion failed' }
216181 Write-Host " GC trace complete: $traceFile " - ForegroundColor Green
182+ $speedFile = $speedBase + ' .speedscope.json'
183+ if (Test-Path " $speedFile .speedscope.json" ){ Move-Item - Force " $speedFile .speedscope.json" $speedFile }
217184 Write-Host " Speedscope file: $speedFile " - ForegroundColor Green
218- # Auto-open speedscope view
219- try {
220- $speedFile = $speedFile + ' .speedscope.json'
221- $resolvedSpeed = (Resolve-Path $speedFile ).Path
222- if (-not (Test-Path $resolvedSpeed )) { throw " Speedscope file not found: $resolvedSpeed " }
223- if (Get-Command npx - ErrorAction SilentlyContinue){
224- Write-Host " Opening speedscope (npx) -> $resolvedSpeed " - ForegroundColor Cyan
225- & npx speedscope " $resolvedSpeed "
226- if ($LASTEXITCODE -ne 0 ){ Write-Host ' npx speedscope returned non-zero; fallback to browser.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) }
227- } else {
228- Write-Host ' npx not available; opening speedscope.app and folder.' - ForegroundColor Yellow
229- Start-Process ' https://www.speedscope.app'
230- Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent)
231- }
232- } catch { Write-Host " Speedscope auto-open failed: $ ( $_.Exception.Message ) " - ForegroundColor Yellow }
185+ if (-not $env: TRACE_NO_VIEW ){
186+ try { $resolvedSpeed = (Resolve-Path $speedFile ).Path; if (-not (Test-Path $resolvedSpeed )){ throw " Speedscope file not found: $resolvedSpeed " }; if (Get-Command npx - ErrorAction SilentlyContinue){ Write-Host " Opening speedscope (npx) -> $resolvedSpeed " - ForegroundColor Cyan; & npx speedscope " $resolvedSpeed " ; if ($LASTEXITCODE -ne 0 ){ Write-Host ' npx speedscope returned non-zero; fallback to browser.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) } } else { Write-Host ' npx not available; opening speedscope.app and folder.' - ForegroundColor Yellow; Start-Process ' https://www.speedscope.app' ; Start-Process explorer.exe (Split-Path $resolvedSpeed - Parent) } } catch { Write-Host " Speedscope auto-open failed: $ ( $_.Exception.Message ) " - ForegroundColor Yellow }
187+ } else { Write-Host ' TRACE_NO_VIEW set; skipping auto-open.' - ForegroundColor DarkYellow }
233188 }
234189 ' speedscope-view' {
235190 # Select a speedscope json file and open visualization
0 commit comments