Skip to content

Commit 99032fe

Browse files
authored
Capture Perfetto Trace Processor output to UI logger, so that is can be viewed inline as diagnostics w/o dissapearing. Also hide the window popup for a more seamless UI expereince. (#47)
1 parent ba00be5 commit 99032fe

2 files changed

Lines changed: 54 additions & 19 deletions

File tree

PerfettoCds/Pipeline/PerfettoSourceParser.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using PerfettoCds.Pipeline.Events;
1111
using System.IO;
1212
using System.Reflection;
13+
using System.Diagnostics;
1314

1415
namespace PerfettoCds
1516
{
@@ -86,8 +87,12 @@ public void ProcessSource(ISourceDataProcessor<PerfettoSqlEventKeyed, PerfettoSo
8687
var shellDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
8788
var shellPath = Path.Combine(shellDir, PerfettoPluginConstants.TraceProcessorShellFileName);
8889

90+
// TraceProcessor seems to incorrectly output via stderr and not stdout (so we won't label stderr as Error)
91+
DataReceivedEventHandler outputDataReceivedHandler = (sender, args) => logger.Verbose($"{PerfettoPluginConstants.TraceProcessorShellFileName}: {args.Data}");
92+
DataReceivedEventHandler errorDataReceivedHandler = (sender, args) => logger.Verbose($"{PerfettoPluginConstants.TraceProcessorShellFileName}: {args.Data}");
93+
8994
// Start the Perfetto trace processor shell with the trace file
90-
traceProc.OpenTraceProcessor(shellPath, filePath);
95+
traceProc.OpenTraceProcessor(shellPath, filePath, outputDataReceivedHandler, errorDataReceivedHandler);
9196

9297
// Use this callback to receive events parsed and turn them in events with keys
9398
// that get used by data cookers
@@ -188,7 +193,7 @@ void EventCallback(PerfettoSqlEvent ev)
188193
traceProc.QueryTraceForEvents(query.GetSqlQuery(), query.GetEventKey(), EventCallback);
189194
var dateTimeQueryFinished = DateTime.UtcNow;
190195

191-
logger.Verbose($"Query for {query.GetEventKey()} completed in {(dateTimeQueryFinished - dateTimeQueryStarted).TotalSeconds}s at {dateTimeQueryFinished} UTC");
196+
logger.Verbose($"Query for {query.GetEventKey()} completed in {(dateTimeQueryFinished - dateTimeQueryStarted).TotalSeconds}s at {dateTimeQueryFinished.ToString("MM/dd/yyyy HH:mm:ss.fff")} UTC");
192197

193198
IncreaseProgress(queryProgressIncrease);
194199

PerfettoProcessor/PerfettoTraceProcessor.cs

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -95,29 +95,26 @@ private bool IsPortAvailable(int port)
9595
/// </summary>
9696
/// <param name="shellPath">Full path to trace_processor_shell.exe</param>
9797
/// <param name="tracePath">Full path to the Perfetto trace file</param>
98-
public void OpenTraceProcessor(string shellPath, string tracePath)
98+
public void OpenTraceProcessor(string shellPath, string tracePath, DataReceivedEventHandler outputDataReceivedEventHandler, DataReceivedEventHandler errorDataReceivedEventHandler)
9999
{
100-
using (var client = new HttpClient())
101-
{
102-
// Make sure another instance of trace_processor_shell isn't already running
103-
while (!IsPortAvailable(HttpPort) && HttpPort < PortMax)
104-
{
105-
HttpPort++;
106-
}
107-
108-
ShellProcess = Process.Start(shellPath, $"-D --http-port {HttpPort} -i \"{tracePath}\"");
109-
}
110-
if (ShellProcess.HasExited)
111-
{
112-
throw new Exception("Problem starting trace_processor_shell.exe");
113-
}
100+
StartTraceProcessor(shellPath, $"-D --http-port {HttpPort} -i \"{tracePath}\"", outputDataReceivedEventHandler, errorDataReceivedEventHandler);
114101
}
115102

116103
/// <summary>
117104
/// Initializes trace_processor_shell.exe in HTTP/RPC mode without the trace file
118105
/// </summary>
119106
/// <param name="shellPath">Full path to trace_processor_shell.exe</param>
120-
public void OpenTraceProcessor(string shellPath)
107+
public void OpenTraceProcessor(string shellPath, DataReceivedEventHandler outputDataReceivedEventHandler, DataReceivedEventHandler errorDataReceivedEventHandler)
108+
{
109+
StartTraceProcessor(shellPath, $"-D --http-port {HttpPort}", outputDataReceivedEventHandler, errorDataReceivedEventHandler);
110+
}
111+
112+
/// <summary>
113+
/// Launches trace_processor_shell.exe
114+
/// </summary>
115+
/// <param name="shellPath">Full path to trace_processor_shell.exe</param>
116+
/// <param name="args"></param>
117+
private void StartTraceProcessor(string shellPath, string args, DataReceivedEventHandler outputDataReceivedEventHandler, DataReceivedEventHandler errorDataReceivedEventHandler)
121118
{
122119
using (var client = new HttpClient())
123120
{
@@ -126,7 +123,38 @@ public void OpenTraceProcessor(string shellPath)
126123
{
127124
HttpPort++;
128125
}
129-
ShellProcess = Process.Start(shellPath, $"-D --http-port {HttpPort}");
126+
127+
var traceProcessorProcessStartInfo = new ProcessStartInfo()
128+
{
129+
FileName = shellPath,
130+
Arguments = args,
131+
RedirectStandardOutput = true,
132+
RedirectStandardError = true,
133+
CreateNoWindow = true,
134+
};
135+
136+
ShellProcess = new Process();
137+
ShellProcess.StartInfo = traceProcessorProcessStartInfo;
138+
139+
if (outputDataReceivedEventHandler != null)
140+
{
141+
ShellProcess.OutputDataReceived += outputDataReceivedEventHandler;
142+
}
143+
if (errorDataReceivedEventHandler != null)
144+
{
145+
ShellProcess.ErrorDataReceived += errorDataReceivedEventHandler;
146+
}
147+
148+
ShellProcess.Start();
149+
150+
if (outputDataReceivedEventHandler != null)
151+
{
152+
ShellProcess.BeginOutputReadLine();
153+
}
154+
if (errorDataReceivedEventHandler != null)
155+
{
156+
ShellProcess.BeginErrorReadLine();
157+
}
130158
}
131159
if (ShellProcess.HasExited)
132160
{
@@ -317,6 +345,8 @@ public void QueryTraceForEvents(string sqlQuery, string eventKey, Action<Perfett
317345

318346
public void CloseTraceConnection()
319347
{
348+
ShellProcess.CancelOutputRead();
349+
ShellProcess.CancelErrorRead();
320350
ShellProcess?.Kill();
321351
}
322352
}

0 commit comments

Comments
 (0)