Refactor out list-processes command handler and add it to dotnet-dump (#534)
authorSung Yoon Whang <suwhang@microsoft.com>
Mon, 7 Oct 2019 18:59:03 +0000 (11:59 -0700)
committerGitHub <noreply@github.com>
Mon, 7 Oct 2019 18:59:03 +0000 (11:59 -0700)
* Refactor out ps command handler and add it to dotnet-dump

* More refactoring

* Some renaming

* update doc

* More docs update

* fix broken renamed file reference

* catch InvalidOperationException only

documentation/design-docs/dotnet-tools.md
documentation/dotnet-counters-instructions.md
src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs
src/Tools/Common/Commands/ProcessStatus.cs [new file with mode: 0644]
src/Tools/dotnet-counters/Program.cs
src/Tools/dotnet-counters/dotnet-counters.csproj
src/Tools/dotnet-dump/Program.cs
src/Tools/dotnet-dump/dotnet-dump.csproj
src/Tools/dotnet-trace/CommandLine/Commands/ListProcessesCommandHandler.cs
src/Tools/dotnet-trace/dotnet-trace.csproj

index a27d9bbc5eda43d1ef8618f4e789db9d619477da..557eaf7e0cfd757616c4e3b4cf4068fb3c59e29d 100644 (file)
@@ -148,6 +148,7 @@ OPTIONS
 COMMANDS
 
     list      Display a list of counter names and descriptions
+    ps        Display a list of dotnet processes that can be monitored
     monitor   Display periodically refreshing values of selected counters
 
 LIST
@@ -247,7 +248,7 @@ OPTIONS
 COMMANDS
 
     collect         Collects a diagnostic trace from a currently running process
-    list-processes  Lists dotnet processes that can be attached to.
+    ps              Lists dotnet processes that can be attached to.
     list-profiles   Lists pre-built tracing profiles with a description of what providers and filters are in each profile.
     convert         Converts traces to alternate formats for use with alternate trace analysis tools
 
@@ -355,6 +356,7 @@ COMMANDS
 
     collect   Capture dumps from a process
     analyze   Starts an interactive shell with debugging commands to explore a dump
+    ps        Display a list of dotnet processes to create dump from
 
 COLLECT
 
index 5e5515e29251bee5d8ac22f005535068fc062b0b..3c673799df52c53facb7acbebcc6cd0d09b5c263 100644 (file)
@@ -32,8 +32,20 @@ dotnet tool install --global dotnet-counters
 *COMMANDS*
 
     list      Display a list of counter names and descriptions
+    ps        Display a list of dotnet processes that can be monitored
     monitor   Display periodically refreshing values of selected counters
 
+*PS*
+    dotnet-counters ps
+
+    Display a list of dotnet processes that can be monitored.
+
+    Examples:
+      > dotnet-counters ps
+
+     15683 WebApi     /home/suwhang/repos/WebApi/WebApi
+     16324 dotnet     /usr/local/share/dotnet/dotnet
+
 *LIST*
 
     dotnet-counters list [-h|--help]
index c2b19be9c7b1a9095d1c9c2353ec01b41aae8fc8..4c46c9bcd7a295caf29927ffb5f42023ef3e97f1 100644 (file)
@@ -13,6 +13,7 @@ using System.Linq;
 using System.Net.Sockets;
 using System.Runtime.InteropServices;
 using System.Security.Principal;
+using System.Text;
 using System.Text.RegularExpressions;
 
 namespace Microsoft.Diagnostics.Tools.RuntimeClient
diff --git a/src/Tools/Common/Commands/ProcessStatus.cs b/src/Tools/Common/Commands/ProcessStatus.cs
new file mode 100644 (file)
index 0000000..cdf2111
--- /dev/null
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.CommandLine;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+
+using Microsoft.Diagnostics.Tools.RuntimeClient;
+
+namespace Microsoft.Internal.Common.Commands
+{
+    public class ProcessStatusCommandHandler
+    {
+        /// <summary>
+        /// Print the current list of available .NET core processes for diagnosis and their statuses
+        /// </summary>
+        public static void PrintProcessStatus(IConsole console)
+        {
+            try
+            {
+                StringBuilder sb = new StringBuilder();
+                var processes = EventPipeClient.ListAvailablePorts()
+                    .Select(GetProcessById)
+                    .Where(process => process != null)
+                    .OrderBy(process => process.ProcessName)
+                    .ThenBy(process => process.Id);
+
+                foreach (var process in processes)
+                {
+                    try
+                    {
+                        sb.Append($"{process.Id, 10} {process.ProcessName, -10} {process.MainModule.FileName}\n");
+                    }
+                    catch (InvalidOperationException)
+                    {
+                        sb.Append($"{process.Id, 10} {process.ProcessName, -10} [Elevated process - cannot determine path]\n");
+                    }
+                }
+                console.Out.WriteLine(sb.ToString());
+            }
+            catch (InvalidOperationException ex)
+            {
+                console.Out.WriteLine(ex.ToString());
+            }
+        }
+
+        private static Process GetProcessById(int processId)
+        {
+            try
+            {
+                return Process.GetProcessById(processId);
+            }
+            catch (ArgumentException)
+            {
+                return null;
+            }
+        }
+    }
+}
index 94fd87d44023310ebfd16abe524417d944faa5df..c9a36fe5326332ede152018e3cc728a8b50daaa9 100644 (file)
@@ -12,6 +12,7 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Collections.Generic;
 using Microsoft.Diagnostics.Tools.RuntimeClient;
+using Microsoft.Internal.Common.Commands;
 
 namespace Microsoft.Diagnostics.Tools.Counters
 {
@@ -54,47 +55,12 @@ namespace Microsoft.Diagnostics.Tools.Counters
                 new Option[] { },
                 handler: CommandHandler.Create<IConsole>(List));
 
-        private static Command ListProcessesCommand() =>
+        private static Command ProcessStatusCommand() =>
             new Command(
-                "list-processes",
+                "ps",
                 "Display a list of dotnet processes that can be monitored.",
                 new Option[] { },
-                handler: CommandHandler.Create<IConsole>(ListProcesses));
-
-        private static int ListProcesses(IConsole console)
-        {
-            var processes = EventPipeClient.ListAvailablePorts()
-                .Select(GetProcess)
-                .Where(process => process != null)
-                .OrderBy(process => process.ProcessName)
-                .ThenBy(process => process.Id);
-
-            foreach (var process in processes)
-            {
-                try
-                {
-                    console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} {process.MainModule.FileName}");
-                }
-                catch (Exception)
-                {
-                    console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} [Elevated process - cannot determine path]");
-                }
-            }
-
-            return 0;
-        }
-
-        private static System.Diagnostics.Process GetProcess(int processId)
-        {
-            try
-            {
-                return System.Diagnostics.Process.GetProcessById(processId);
-            }
-            catch (ArgumentException)
-            {
-                return null;
-            }
-        }
+                handler: CommandHandler.Create<IConsole>(ProcessStatusCommandHandler.PrintProcessStatus));
 
         public static int List(IConsole console)
         {
@@ -120,7 +86,7 @@ namespace Microsoft.Diagnostics.Tools.Counters
             var parser = new CommandLineBuilder()
                 .AddCommand(MonitorCommand())
                 .AddCommand(ListCommand())
-                .AddCommand(ListProcessesCommand())
+                .AddCommand(ProcessStatusCommand())
                 .UseDefaults()
                 .Build();
             return parser.InvokeAsync(args);
index 15f28687540e8d564d08681b2009e022865f4223..adcd8a4fafaecca1b79b04646f2a7d5b6b22e998 100644 (file)
@@ -12,6 +12,7 @@
 
   <ItemGroup>
     <Compile Include="$(MSBuildThisFileDirectory)..\dotnet-trace\Extensions.cs" Link="Extensions.cs" />
+    <Compile Include="..\Common\Commands\ProcessStatus.cs" Link="ProcessStatus.cs" />
   </ItemGroup>
 
   <ItemGroup>
index 5f624fdc01def15a3b743e2d755927796763d9b2..2f2d9aa04186b658ae2340b5dfc982edc4066a2f 100644 (file)
@@ -7,6 +7,8 @@ using System.CommandLine.Builder;
 using System.CommandLine.Invocation;
 using System.IO;
 using System.Threading.Tasks;
+using Microsoft.Diagnostics.Tools.RuntimeClient;
+using Microsoft.Internal.Common.Commands;
 
 namespace Microsoft.Diagnostics.Tools.Dump
 {
@@ -17,6 +19,7 @@ namespace Microsoft.Diagnostics.Tools.Dump
             var parser = new CommandLineBuilder()
                 .AddCommand(CollectCommand())
                 .AddCommand(AnalyzeCommand())
+                .AddCommand(ProcessStatusCommand())
                 .UseDefaults()
                 .Build();
 
@@ -79,5 +82,12 @@ If not specified 'heap' is the default.",
                 new[] { "-c", "--command" },
                 "Run the command on start.",
                 new Argument<string[]>() { Name = "command", Arity = ArgumentArity.ZeroOrMore });
+
+        private static Command ProcessStatusCommand() =>
+            new Command(
+                "ps",
+                "Display a list of dotnet processes to create dump from",
+                new Option[] { },
+                handler: CommandHandler.Create<IConsole>(ProcessStatusCommandHandler.PrintProcessStatus));
     }
 }
index f1aa20e8e0882d1daf8e82c0f40b445b386b2c57..c6ba3724d250614fadcfda8e2061376399479989 100644 (file)
     <PackageReference Include="Microsoft.Diagnostics.Runtime" Version="$(MicrosoftDiagnosticsRuntimeVersion)" />
     <PackageReference Include="Microsoft.SymbolStore" Version="$(MicrosoftSymbolStoreVersion)" />
   </ItemGroup>
+
+  <ItemGroup>
+    <Compile Include="..\Common\Commands\ProcessStatus.cs" Link="ProcessStatus.cs" />
+  </ItemGroup>
   
   <ItemGroup>
     <ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Microsoft.Diagnostics.Repl\Microsoft.Diagnostics.Repl.csproj" />
index 12c0e02387fb1550d25bee4c7aef0a80dfe62dbb..c8afc5695d36fbdfdcbe125fc29e561591d529c5 100644 (file)
@@ -3,10 +3,9 @@
 // See the LICENSE file in the project root for more information.
 
 using Microsoft.Diagnostics.Tools.RuntimeClient;
+using Microsoft.Internal.Common.Commands;
 using System;
 using System.CommandLine;
-using System.Diagnostics;
-using System.Linq;
 using System.Threading.Tasks;
 
 namespace Microsoft.Diagnostics.Tools.Trace
@@ -15,51 +14,14 @@ namespace Microsoft.Diagnostics.Tools.Trace
     {
         public static async Task<int> GetActivePorts(IConsole console)
         {
-            try
-            {
-                var processes = EventPipeClient.ListAvailablePorts()
-                    .Select(GetProcessById)
-                    .Where(process => process != null)
-                    .OrderBy(process => process.ProcessName)
-                    .ThenBy(process => process.Id);
-
-                foreach (var process in processes)
-                {
-                    try
-                    {
-                        Console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} {process.MainModule.FileName}");
-                    }
-                    catch (Exception)
-                    {
-                        Console.Out.WriteLine($"{process.Id, 10} {process.ProcessName, -10} [Elevated process - cannot determine path]");
-                    }
-                }
-
-                await Task.FromResult(0);
-                return 0;
-            }
-            catch (Exception ex)
-            {
-                Console.Error.WriteLine($"[ERROR] {ex.ToString()}");
-                return 1;
-            }
-        }
-
-        private static Process GetProcessById(int processId)
-        {
-            try
-            {
-                return Process.GetProcessById(processId);
-            }
-            catch (ArgumentException)
-            {
-                return null;
-            }
+            ProcessStatusCommandHandler.PrintProcessStatus(console);
+            await Task.FromResult(0);
+            return 0;
         }
 
         public static Command ListProcessesCommand() =>
             new Command(
-                name: "list-processes",
+                name: "ps",
                 description: "Lists dotnet processes that can be attached to.",
                 handler: System.CommandLine.Invocation.CommandHandler.Create<IConsole>(GetActivePorts),
                 isHidden: false);
index 7c0ba2456250e16653718a70f36b529f90b0ea20..43dfc2dc2ab8eac281783ea3eab685fb16dcc2ad 100644 (file)
     <ProjectReference Include="$(MSBuildThisFileDirectory)..\..\Microsoft.Diagnostics.Tools.RuntimeClient\Microsoft.Diagnostics.Tools.RuntimeClient.csproj" />
   </ItemGroup>
 
+  <ItemGroup>
+    <Compile Include="..\Common\Commands\ProcessStatus.cs" Link="ProcessStatus.cs" />
+  </ItemGroup>
+
   <ItemGroup>
     <InternalsVisibleTo Include="DotnetTrace.UnitTests" />
   </ItemGroup>