From b1757d5b43b6c44a20fe1e4d45736079253ec30f Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Mon, 7 Oct 2019 11:59:03 -0700 Subject: [PATCH] Refactor out list-processes command handler and add it to dotnet-dump (#534) * 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 | 4 +- documentation/dotnet-counters-instructions.md | 12 ++++ .../Eventing/EventPipeClient.cs | 1 + src/Tools/Common/Commands/ProcessStatus.cs | 62 +++++++++++++++++++ src/Tools/dotnet-counters/Program.cs | 44 ++----------- .../dotnet-counters/dotnet-counters.csproj | 1 + src/Tools/dotnet-dump/Program.cs | 10 +++ src/Tools/dotnet-dump/dotnet-dump.csproj | 4 ++ .../Commands/ListProcessesCommandHandler.cs | 48 ++------------ src/Tools/dotnet-trace/dotnet-trace.csproj | 4 ++ 10 files changed, 107 insertions(+), 83 deletions(-) create mode 100644 src/Tools/Common/Commands/ProcessStatus.cs diff --git a/documentation/design-docs/dotnet-tools.md b/documentation/design-docs/dotnet-tools.md index a27d9bbc5..557eaf7e0 100644 --- a/documentation/design-docs/dotnet-tools.md +++ b/documentation/design-docs/dotnet-tools.md @@ -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 diff --git a/documentation/dotnet-counters-instructions.md b/documentation/dotnet-counters-instructions.md index 5e5515e29..3c673799d 100644 --- a/documentation/dotnet-counters-instructions.md +++ b/documentation/dotnet-counters-instructions.md @@ -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] diff --git a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs index c2b19be9c..4c46c9bcd 100644 --- a/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs +++ b/src/Microsoft.Diagnostics.Tools.RuntimeClient/Eventing/EventPipeClient.cs @@ -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 index 000000000..cdf2111fb --- /dev/null +++ b/src/Tools/Common/Commands/ProcessStatus.cs @@ -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 + { + /// + /// Print the current list of available .NET core processes for diagnosis and their statuses + /// + 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; + } + } + } +} diff --git a/src/Tools/dotnet-counters/Program.cs b/src/Tools/dotnet-counters/Program.cs index 94fd87d44..c9a36fe53 100644 --- a/src/Tools/dotnet-counters/Program.cs +++ b/src/Tools/dotnet-counters/Program.cs @@ -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(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(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(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); diff --git a/src/Tools/dotnet-counters/dotnet-counters.csproj b/src/Tools/dotnet-counters/dotnet-counters.csproj index 15f286875..adcd8a4fa 100644 --- a/src/Tools/dotnet-counters/dotnet-counters.csproj +++ b/src/Tools/dotnet-counters/dotnet-counters.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Tools/dotnet-dump/Program.cs b/src/Tools/dotnet-dump/Program.cs index 5f624fdc0..2f2d9aa04 100644 --- a/src/Tools/dotnet-dump/Program.cs +++ b/src/Tools/dotnet-dump/Program.cs @@ -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() { 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(ProcessStatusCommandHandler.PrintProcessStatus)); } } diff --git a/src/Tools/dotnet-dump/dotnet-dump.csproj b/src/Tools/dotnet-dump/dotnet-dump.csproj index f1aa20e8e..c6ba3724d 100644 --- a/src/Tools/dotnet-dump/dotnet-dump.csproj +++ b/src/Tools/dotnet-dump/dotnet-dump.csproj @@ -16,6 +16,10 @@ + + + + diff --git a/src/Tools/dotnet-trace/CommandLine/Commands/ListProcessesCommandHandler.cs b/src/Tools/dotnet-trace/CommandLine/Commands/ListProcessesCommandHandler.cs index 12c0e0238..c8afc5695 100644 --- a/src/Tools/dotnet-trace/CommandLine/Commands/ListProcessesCommandHandler.cs +++ b/src/Tools/dotnet-trace/CommandLine/Commands/ListProcessesCommandHandler.cs @@ -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 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(GetActivePorts), isHidden: false); diff --git a/src/Tools/dotnet-trace/dotnet-trace.csproj b/src/Tools/dotnet-trace/dotnet-trace.csproj index 7c0ba2456..43dfc2dc2 100644 --- a/src/Tools/dotnet-trace/dotnet-trace.csproj +++ b/src/Tools/dotnet-trace/dotnet-trace.csproj @@ -19,6 +19,10 @@ + + + + -- 2.34.1