Add runtime resume option to dotnet-trace and dotnet-counters. (#2343)
authorJohan Lorensson <lateralusx.github@gmail.com>
Fri, 18 Jun 2021 21:04:56 +0000 (23:04 +0200)
committerGitHub <noreply@github.com>
Fri, 18 Jun 2021 21:04:56 +0000 (14:04 -0700)
src/Tools/dotnet-counters/CounterMonitor.cs
src/Tools/dotnet-counters/Program.cs
src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs

index 185259014caa1d35f285ca6e3a2b3c6deb4a4462..c8eee8df70ec7b7759a650a64a639678b10061d6 100644 (file)
@@ -91,7 +91,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
             _renderer.Stop();
         }
 
-        public async Task<int> Monitor(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, string name, string diagnosticPort)
+        public async Task<int> Monitor(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, string name, string diagnosticPort, bool resumeRuntime)
         {
             if (!ProcessLauncher.Launcher.HasChildProc && !CommandUtils.ValidateArgumentsForAttach(processId, name, diagnosticPort, out _processId))
             {
@@ -115,7 +115,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
                     _interval = refreshInterval;
                     _renderer = new ConsoleWriter();
                     _diagnosticsClient = holder.Client;
-                    shouldResumeRuntime = ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort);
+                    shouldResumeRuntime = ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort) || resumeRuntime;
                     int ret = await Start();
                     ProcessLauncher.Launcher.Cleanup();
                     return ret;
@@ -135,7 +135,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
         }
 
 
-        public async Task<int> Collect(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, CountersExportFormat format, string output, string name, string diagnosticPort)
+        public async Task<int> Collect(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, CountersExportFormat format, string output, string name, string diagnosticPort, bool resumeRuntime)
         {
             if (!ProcessLauncher.Launcher.HasChildProc && !CommandUtils.ValidateArgumentsForAttach(processId, name, diagnosticPort, out _processId))
             {
@@ -190,7 +190,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
                         _console.Error.WriteLine($"The output format {format} is not a valid output format.");
                         return 0;
                     }
-                    shouldResumeRuntime = ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort);
+                    shouldResumeRuntime = ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort) || resumeRuntime;
                     int ret = await Start();
                     return ret;
                 }
index 5da067fcd95fdafe7f123aae07fc99ef7edfcbe1..ff040f3572e5414bebd923ba4a10cb6c1015add1 100644 (file)
@@ -22,8 +22,8 @@ namespace Microsoft.Diagnostics.Tools.Counters
 
     internal class Program
     {
-        delegate Task<int> CollectDelegate(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, CountersExportFormat format, string output, string processName, string port);
-        delegate Task<int> MonitorDelegate(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, string processName, string port);
+        delegate Task<int> CollectDelegate(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, CountersExportFormat format, string output, string processName, string port, bool resumeRuntime);
+        delegate Task<int> MonitorDelegate(CancellationToken ct, List<string> counter_list, string counters, IConsole console, int processId, int refreshInterval, string processName, string port, bool resumeRuntime);
 
         private static Command MonitorCommand() =>
             new Command(
@@ -33,7 +33,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 // Handler
                 HandlerDescriptor.FromDelegate((MonitorDelegate)new CounterMonitor().Monitor).GetCommandHandler(),
                 // Arguments and Options
-                CounterList(), CounterOption(), ProcessIdOption(), RefreshIntervalOption(), NameOption(), DiagnosticPortOption(),
+                CounterList(), CounterOption(), ProcessIdOption(), RefreshIntervalOption(), NameOption(), DiagnosticPortOption(), ResumeRuntimeOption()
             };
         
         private static Command CollectCommand() =>
@@ -44,7 +44,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 // Handler
                 HandlerDescriptor.FromDelegate((CollectDelegate)new CounterMonitor().Collect).GetCommandHandler(),
                 // Arguments and Options
-                CounterList(), CounterOption(), ProcessIdOption(), RefreshIntervalOption(), ExportFormatOption(), ExportFileNameOption(), NameOption(), DiagnosticPortOption()
+                CounterList(), CounterOption(), ProcessIdOption(), RefreshIntervalOption(), ExportFormatOption(), ExportFileNameOption(), NameOption(), DiagnosticPortOption(), ResumeRuntimeOption()
             };
 
         private static Option NameOption() =>
@@ -127,6 +127,14 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 Argument = new Argument<string>(name: "diagnosticPort", getDefaultValue: () => "")
             };
 
+        private static Option ResumeRuntimeOption() =>
+            new Option(
+                alias: "--resume-runtime",
+                description: @"Resume runtime once session has been initialized, defaults to true. Disable resume of runtime using --resume-runtime:false")
+            {
+                Argument = new Argument<bool>(name: "resumeRuntime", getDefaultValue: () => true)
+            };
+
         private static readonly string[] s_SupportedRuntimeVersions = new[] { "3.0", "3.1", "5.0" };
 
         public static int List(IConsole console, string runtimeVersion)
index 3764b1da9f57328b69d013d66877315430bb7421..65856947ae695f00b06bde0661d428fe2dfc65bd 100644 (file)
@@ -21,7 +21,7 @@ namespace Microsoft.Diagnostics.Tools.Trace
 {
     internal static class CollectCommandHandler
     {
-        delegate Task<int> CollectDelegate(CancellationToken ct, IConsole console, int processId, FileInfo output, uint buffersize, string providers, string profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name, string port, bool showchildio);
+        delegate Task<int> CollectDelegate(CancellationToken ct, IConsole console, int processId, FileInfo output, uint buffersize, string providers, string profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name, string port, bool showchildio, bool resumeRuntime);
 
         /// <summary>
         /// Collects a diagnostic trace from a currently running process or launch a child process and trace it.
@@ -41,8 +41,9 @@ namespace Microsoft.Diagnostics.Tools.Trace
         /// <param name="clreventlevel">The verbosity level of CLR events</param>
         /// <param name="port">Path to the diagnostic port to be created.</param>
         /// <param name="showchildio">Should IO from a child process be hidden.</param>
+        /// <param name="resumeRuntime">Resume runtime once session has been initialized.</param>
         /// <returns></returns>
-        private static async Task<int> Collect(CancellationToken ct, IConsole console, int processId, FileInfo output, uint buffersize, string providers, string profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name, string diagnosticPort, bool showchildio)
+        private static async Task<int> Collect(CancellationToken ct, IConsole console, int processId, FileInfo output, uint buffersize, string providers, string profile, TraceFileFormat format, TimeSpan duration, string clrevents, string clreventlevel, string name, string diagnosticPort, bool showchildio, bool resumeRuntime)
         {
             int ret = 0;
             bool collectionStopped = false;
@@ -150,7 +151,7 @@ namespace Microsoft.Diagnostics.Tools.Trace
                 DiagnosticsClient diagnosticsClient;
                 Process process;
                 DiagnosticsClientBuilder builder = new DiagnosticsClientBuilder("dotnet-trace", 10);
-                bool shouldResumeRuntime = ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort);
+                bool shouldResumeRuntime = ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort) || resumeRuntime;
                 var shouldExit = new ManualResetEvent(false);
                 ct.Register(() => shouldExit.Set());
 
@@ -162,7 +163,7 @@ namespace Microsoft.Diagnostics.Tools.Trace
                         return await Task.FromResult(ret);
                     }
                     diagnosticsClient = holder.Client;
-                    if (shouldResumeRuntime)
+                    if (ProcessLauncher.Launcher.HasChildProc || !string.IsNullOrEmpty(diagnosticPort))
                     {
                         process = Process.GetProcessById(holder.EndpointInfo.ProcessId);
                     }
@@ -399,7 +400,8 @@ namespace Microsoft.Diagnostics.Tools.Trace
                 CLREventLevelOption(),
                 CommonOptions.NameOption(),
                 DiagnosticPortOption(),
-                ShowChildIOOption()
+                ShowChildIOOption(),
+                ResumeRuntimeOption()
             };
 
         private static uint DefaultCircularBufferSizeInMB() => 256;
@@ -482,5 +484,13 @@ namespace Microsoft.Diagnostics.Tools.Trace
             {
                 Argument = new Argument<bool>(name: "show-child-io", getDefaultValue: () => false)
             };
+
+        private static Option ResumeRuntimeOption() =>
+            new Option(
+                alias: "--resume-runtime",
+                description: @"Resume runtime once session has been initialized, defaults to true. Disable resume of runtime using --resume-runtime:false")
+            {
+                Argument = new Argument<bool>(name: "resumeRuntime", getDefaultValue: () => true)
+            };
     }
 }