-
Notifications
You must be signed in to change notification settings - Fork 384
[NO-MERGE][dotnet-trace] Add collect-linux verb #5570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs
Outdated
Show resolved
Hide resolved
return (int)ReturnCode.TracingError; | ||
} | ||
|
||
proc.OutputDataReceived += (_, e) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine for now but once we've got the FFI working I'm hoping that dotnet-trace will control the majority of the output and only pass along warnings/errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hooked in the FFI and have the output type routed to Console.Out and Console.Error. Didn't add handling for progress as I haven't seen records yet.
src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs
Outdated
Show resolved
Hide resolved
src/Tools/dotnet-trace/CommandLine/Commands/CollectLinuxCommand.cs
Outdated
Show resolved
Hide resolved
c09b095
to
0989d21
Compare
Extensions houses provider composition helpers, instead of literal extension methods for strings. Centralize all provider parsing + composition logic and keep Profile as a data container.
76e65e1
to
61b2569
Compare
61b2569
to
c8e53ea
Compare
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<_RecordTraceResolved Include="$(_RecordTraceLocal)" Condition="'$(RuntimeIdentifier)' != '' AND Exists('$(_RecordTraceLocal)')" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, artifact from before, will remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking pretty good. Aside from some small comments inline a few broader things:
- Historically we relied on manual testing to keep these tools operating well but now that we have less time available from the testers I think we need to improve our automated testing. Partly this is to ensure we aren't inadvertently changing the original 'collect' verb and partly to ensure going forward the 'collect-linux' behavior doesn't regress either. I think the best way to do this would be:
- Open a new PR that we'll check in first containing some basic tests of the existing collect verb.
- Commit this PR 2nd and all the tests in the 1st PR should continue to pass. This ensures we didn't change anything unintended.
To do the testing we probably need to create some small interface shims. We already have an IConsole interface defined that could be moved to the shared Common folder. We could also create a small interface around the DiagnosticsClient.EventPipeCollect() API so that a test can return some dummy data in a stream instead. dotnet-counters has some example tests that show how we can run some code and then confirm the console output is what we expect. In this case I imagine we'd be running the Collect() function and giving some chosen input arguments.
- I think there is a bit more adjustment to be done on some of the output text, but it should be fine to get this one in first, then tweak afterwards in some 3rd PR.
string options = string.Join(' ', recordTraceArgList); | ||
byte[] command = Encoding.UTF8.GetBytes(options); | ||
int rc; | ||
try |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'd shift the try { to start prior to registering the keypress handler. We want to ensure that any error from then onwards cleans everything up.
|
||
private static int RunRecordTrace(CollectLinuxArgs args) | ||
{ | ||
s_recordStatus = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets use a boolean flag or an enum rather than magic constants.
return collectLinuxCommand; | ||
} | ||
|
||
private static int RunRecordTrace(CollectLinuxArgs args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming and factoring feels a little unexpected. I think of "RunRecordTrace" to mean invoking the FFI, waiting for it to finish, and maybe updating the UI during the process. I didn't expect it to include parsing configuration, formatting the script file, determining the output path, or any other calculations to produce the record-trace arguments. I'd suggest just fold this into CollectLinux and name RecordTrace -> RunRecordTrace
{ | ||
profileEffect = traceProfile.CollectLinuxArgs; | ||
} | ||
Console.WriteLine($"Applying profile '{traceProfile.Name}': {profileEffect}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like debug output that we should remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this and the perf event log because collect-linux
introduces .NET Provider-free configurations such as --profile cpu-sampling
and --perf-events block:block_io_start
. I figured it would be a good sanity check for users to see those effects to know that the tracing session is actually capturing something, rather than
No providers were configured.
Recording started. Press CTRL+C to stop.
Previously, those would have also just been
Provider Name Keywords Level Enabled By
Recording started. Press CTRL+C to stop.
until adding to ProviderUtils.cs PrintProviders
if (providers.Count == 0)
{
Console.WriteLine("No providers were configured.");
return;
}
With this and the below perf-events log, users can see
$ dotnet-trace collect-linux --profile cpu-sampling
Applying profile 'cpu-sampling': --on-cpu
No providers were configured.
Recording started. Press CTRL+C to stop.
and
$ dotnet-trace collect-linux --perf-events block:block_io_start,block:block_io_done
No providers were configured.
Enabling perf event 'block:block_io_start'
Enabling perf event 'block:block_io_done'
Recording started. Press CTRL+C to stop.
|
||
string perfProvider = split[0]; | ||
string perfEventName = split[1]; | ||
Console.WriteLine($"Enabling perf event '{perfEvent}'"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debug output?
Blocked on: Microsoft.OneCollect.RecordTrace version with FFI support
Implements dotnet/docs#47894
Following the addition of emitting native runtime and custom EventSource events as user_events through dotnet/runtime#115265 and the public release of https://github.com/microsoft/one-collect which supports collecting both .NET user_events and Linux perf events into a single .nettrace file,
dotnet-trace
will support a new verb,collect-linux
, that wraps aroundrecord-trace
.This PR does the following:
collect-linux
verb and serializes a subset ofdotnet-trace collect
options in addition to acollect-linux
specific--perf-events
option intorecord-trace
args. (see [Diagnostics][dotnet-trace] Add collect-linux verb docs#47894 for overarching details)dotnet-trace
cpu-sampling
->dotnet-common
+dotnet-sampled-thread-time
) and addscollect-linux
specific profileslist-profiles
verb with revamped profiles + multiline description formattingEventPipeProvider
composition logic (MergeProfileAndProviders
+ToProviders
->ComputeProviderConfig
) and renameExtensions.cs
->ProviderUtils.cs
ProviderParsing.cs
->ProviderCompositionTests.cs
)collect
logic + expanddotnet-trace
common optionsTesting
dotnet-trace collect-linux
On Linux
collect-linux
collect-linux --help
`collect-linux` without elevated privileges
`collect-linux` with elevated privileges
On Windows (and I presume other non-Linux OS):
`collect-linux`
dotnet-trace list-profiles
`list-profiles`