Skip to content

Commit 48883a3

Browse files
Merge branch 'release/1.1.1'
2 parents 416d589 + 3d6c504 commit 48883a3

File tree

5 files changed

+74
-69
lines changed

5 files changed

+74
-69
lines changed

ProcessPerformance/PerformanceReporter.cs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ namespace ProcessPerformance
2828
/// Implements the performance reporter.
2929
/// </summary>
3030
public sealed class PerformanceReporter : IDisposable
31-
{
32-
private DateTime _etwStartTime;
31+
{
3332
private TraceEventSession _etwSession;
3433
private Func<HashSet<int>> _processList;
3534
private NetworkInterface _network;
3635
private readonly Counters _counters = new Counters();
36+
private int _intervalTime;
3737

3838
private class Counters
3939
{
@@ -64,9 +64,9 @@ private class Counters
6464
public long networkDownloadSpeed;
6565
}
6666

67-
public PerformanceReporter(String[] processNames, string networkIP = null)
68-
{
69-
67+
public PerformanceReporter(String[] processNames, int intervalTime = 1000, string networkIP = null)
68+
{
69+
7070
if (processNames.Length == 0)
7171
{
7272
_processList = () => { return Process.GetProcesses().Select(p => p.Id).ToHashSet(); };
@@ -78,23 +78,23 @@ public PerformanceReporter(String[] processNames, string networkIP = null)
7878
return processNames.Aggregate(new List<int>(), (partial, processName) =>
7979
{
8080
partial.AddRange(Process.GetProcesses().Where(
81-
p => p.MainWindowTitle.ToLower().Contains(processName.ToLower())
81+
p => p.MainWindowTitle.ToLower().Equals(processName.ToLower())
8282
|| p.ProcessName.ToLower().Contains(processName.ToLower())
8383
|| p.Id.ToString().Equals(processName)
84-
).Select(p => p.Id)); return partial;
84+
).Select(p => p.Id)); return partial;
8585
}).ToHashSet();
8686
};
8787
}
8888

89-
if(! String.IsNullOrEmpty(networkIP) && NetworkInterface.GetIsNetworkAvailable())
90-
{
91-
_network = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(n => n.GetIPProperties().UnicastAddresses.Any( a => a.Address.ToString().Equals(networkIP)));
89+
if (!String.IsNullOrEmpty(networkIP) && NetworkInterface.GetIsNetworkAvailable())
90+
{
91+
_network = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(n => n.GetIPProperties().UnicastAddresses.Any(a => a.Address.ToString().Equals(networkIP)));
9292
}
93-
93+
_intervalTime = intervalTime;
9494
Task.Run(() => StartEtwSession());
9595
}
9696

97-
97+
9898
private void StartEtwSession()
9999
{
100100
try
@@ -166,17 +166,16 @@ public void GetNetworkData()
166166
}
167167
else
168168
{
169-
_counters.networkCurrentTime = DateTime.Now;
170-
var timeDifferenceInSeconds = (_counters.networkCurrentTime - _counters.networkLastTime).TotalSeconds;
169+
_counters.networkCurrentTime = DateTime.Now;
171170
long networkCurrentBytesReceived = statistics.BytesReceived;
172171
long networkCurrentBytesSent = statistics.BytesSent;
173-
_counters.networkDownloadSpeed = Convert.ToInt64((networkCurrentBytesReceived - _counters.networkLastBytesReceived) * 8 / 1000 / timeDifferenceInSeconds);
174-
_counters.networkUploadSpeed = Convert.ToInt64((networkCurrentBytesSent - _counters.networkLastBytesSend) * 8 / 1000 / timeDifferenceInSeconds);
172+
_counters.networkDownloadSpeed = Convert.ToInt64((networkCurrentBytesReceived - _counters.networkLastBytesReceived) * 8 / 1000 / (_intervalTime/ 1000));
173+
_counters.networkUploadSpeed = Convert.ToInt64((networkCurrentBytesSent - _counters.networkLastBytesSend) * 8 / 1000 / (_intervalTime / 1000));
175174
_counters.networkTotalBytesReceived += (networkCurrentBytesReceived - _counters.networkLastBytesReceived);
176175
_counters.networkTotalBytesSend += (networkCurrentBytesSent - _counters.networkLastBytesSend);
177176
_counters.networkLastTime = _counters.networkCurrentTime;
178177
_counters.networkLastBytesReceived = networkCurrentBytesReceived;
179-
_counters.networkLastBytesSend = networkCurrentBytesSent;
178+
_counters.networkLastBytesSend = networkCurrentBytesSent;
180179
}
181180
}
182181

@@ -218,11 +217,8 @@ public void GetCPUData()
218217

219218

220219
public ReportData GetPerformanceData()
221-
{
222-
var timeDifferenceInSeconds = (DateTime.Now - _etwStartTime).TotalSeconds;
223-
220+
{
224221
ReportData performanceData;
225-
226222
Parallel.Invoke(
227223
() => GetMemoryData(),
228224
() => GetCPUData(),
@@ -232,10 +228,10 @@ public ReportData GetPerformanceData()
232228
lock (_counters)
233229
{
234230
performanceData = new ReportData
235-
{
231+
{
236232
Threads = _processList().Count,
237-
ProcessDownloadSpeed = Convert.ToInt64((_counters.processDownloadSpeed / 1000) / timeDifferenceInSeconds),
238-
ProcessUploadSpeed = Convert.ToInt64((_counters.processUploadSpeed / 1000) / timeDifferenceInSeconds),
233+
ProcessDownloadSpeed = Convert.ToInt64((_counters.processDownloadSpeed / 1000) / (_intervalTime / 1000)),
234+
ProcessUploadSpeed = Convert.ToInt64((_counters.processUploadSpeed / 1000) / (_intervalTime / 1000)),
239235
ProcessReceivedData = _counters.processTotalBytesReceived / 1024,
240236
ProcessSentData = _counters.processTotalBytesSent / 1024,
241237
ProcessMemoryUsage = _counters.physicalMemory,
@@ -262,8 +258,7 @@ private void ResetCounters()
262258
_counters.networkDownloadSpeed = 0;
263259
_counters.physicalMemory = 0;
264260
_counters.cpuProcessorTime = 0;
265-
}
266-
_etwStartTime = DateTime.Now;
261+
}
267262
}
268263

269264
public void Dispose()

ProcessPerformance/Program.cs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,38 +29,44 @@ public class Program
2929
public static void Main(string[] args)
3030
{
3131
var parameters = ParseArguments(args);
32-
var reporter = new PerformanceReporter(parameters.ProcessNames, parameters.NetworkIP);
32+
var reporter = new PerformanceReporter(parameters.ProcessNames, parameters.IntervalTime, parameters.NetworkIP);
3333

3434
NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
3535
if (parameters.CSV)
36-
Console.WriteLine($"Process Name(s),Thread(s),CPU (%),Memory (MB),Process Sent (KB),Process Upload Speed (kbps),Process Received (KB),Process Download Speed (kbps)" + (String.IsNullOrEmpty(parameters.NetworkIP)?"":",Network Sent (KB),Network Upload Speed (kbps),Network Received (KB),Network Download Speed (kbps)"));
36+
Console.WriteLine($"Process Name(s),Processes(s),CPU (%),Memory (MB),Process Sent (KB),Process Upload Speed (kbps),Process Received (KB),Process Download Speed (kbps)" + (String.IsNullOrEmpty(parameters.NetworkIP) ? "" : ",Network Sent (KB),Network Upload Speed (kbps),Network Received (KB),Network Download Speed (kbps)"));
3737
while (true)
3838
{
3939
Task.Delay(parameters.IntervalTime).Wait();
4040
var result = reporter.GetPerformanceData();
41-
if(parameters.CSV)
41+
if (parameters.CSV)
4242
Console.WriteLine($"{String.Join('+', parameters.ProcessNames)}," +
4343
$"{result.Threads}," +
44-
$"{ result.ProcessCPUUsage.ToString("P", nfi)}," +
45-
$"{result.ProcessMemoryUsage.ToString("N0",nfi)}," +
46-
$"{result.ProcessSentData.ToString("N0",nfi)}," +
47-
$"{result.ProcessUploadSpeed.ToString("N0", nfi)}," +
48-
$"{result.ProcessReceivedData.ToString("N0", nfi)}," +
49-
$"{result.ProcessDownloadSpeed.ToString("N0", nfi)}" +
44+
$"{ (result.ProcessCPUUsage / 100).ToString("P", nfi)}," +
45+
$"{result.ProcessMemoryUsage}," +
46+
$"{result.ProcessSentData}," +
47+
$"{result.ProcessUploadSpeed}," +
48+
$"{result.ProcessReceivedData}," +
49+
$"{result.ProcessDownloadSpeed}" +
5050
(String.IsNullOrEmpty(parameters.NetworkIP) ? "" : $"," +
51-
$"{result.NetworkSentData.ToString("N0", nfi)}," +
52-
$"{result.NetworkUploadSpeed.ToString("N0", nfi)}," +
53-
$"{result.NetworkReceivedData.ToString("N0", nfi)}," +
54-
$"{result.NetworkDownloadSpeed.ToString("N0", nfi)}"));
55-
else
56-
Console.WriteLine($"{String.Join('+', parameters.ProcessNames)} ({result.Threads} ths):" +
57-
$" CPU: { result.ProcessCPUUsage.ToString("P",nfi)} " +
58-
$"| Memory: {result.ProcessMemoryUsage.ToString("N0", nfi)} MB " +
59-
$"| Process: Sent {result.ProcessSentData.ToString("N0", nfi)} KB ({result.ProcessUploadSpeed.ToString("N0", nfi)} kbps) " +
60-
$"- Received {result.ProcessReceivedData.ToString("N0", nfi)} KB ({result.ProcessDownloadSpeed.ToString("N0", nfi)} kbps)" +
61-
(String.IsNullOrEmpty(parameters.NetworkIP) ? "" : $" " +
62-
$"| Network: Sent {result.NetworkSentData.ToString("N0", nfi)} KB ({result.NetworkUploadSpeed.ToString("N0", nfi)} kbps) " +
63-
$"- Received {result.NetworkReceivedData.ToString("N0", nfi)} KB ({result.NetworkDownloadSpeed.ToString("N0", nfi)} kbps)"));
51+
$"{result.NetworkSentData}," +
52+
$"{result.NetworkUploadSpeed}," +
53+
$"{result.NetworkReceivedData}," +
54+
$"{result.NetworkDownloadSpeed}"));
55+
else
56+
{
57+
if(result.Threads == 0)
58+
Console.WriteLine($"No \"{String.Join('+', parameters.ProcessNames)}\" process is running.");
59+
else
60+
Console.WriteLine($"{String.Join('+', parameters.ProcessNames)} " +
61+
(result.Threads == 1 ? "" : $"({result.Threads} processes):") +
62+
$" CPU: { (result.ProcessCPUUsage / 100).ToString("P", nfi)} " +
63+
$"| Memory: {result.ProcessMemoryUsage.ToString("N0", nfi)} MB " +
64+
$"| Process: Sent {result.ProcessSentData.ToString("N0", nfi)} KB ({result.ProcessUploadSpeed.ToString("N0", nfi)} kbps) " +
65+
$"- Received {result.ProcessReceivedData.ToString("N0", nfi)} KB ({result.ProcessDownloadSpeed.ToString("N0", nfi)} kbps)" +
66+
(String.IsNullOrEmpty(parameters.NetworkIP) ? "" : $" " +
67+
$"| Network: Sent {result.NetworkSentData.ToString("N0", nfi)} KB ({result.NetworkUploadSpeed.ToString("N0", nfi)} kbps) " +
68+
$"- Received {result.NetworkReceivedData.ToString("N0", nfi)} KB ({result.NetworkDownloadSpeed.ToString("N0", nfi)} kbps)"));
69+
}
6470
}
6571
}
6672

@@ -90,18 +96,18 @@ private static Parameters ParseArguments(string[] args)
9096
}
9197
return new Parameters() { ProcessNames = processNames.ToArray(), NetworkIP = networkIP, IntervalTime = intervalTime, CSV = csv };
9298
}
93-
catch
99+
catch
94100
{
95101
Console.Error.WriteLine("\nSome error in the input parameters.Type -help for help.\n");
96102
System.Environment.Exit(1);
97103
return new Parameters();
98104
}
99105
}
100106

101-
public const string HELP_MESSAGE = "ProcessPerformance 2021 Computational Reflection Research Group.\n" +
107+
public const string HELP_MESSAGE = "ProcessPerformance 2021 Computational Reflection Research Group.\n" +
102108
"-help Displays this usage message.\n" +
103109
"-network:NETWORK_IP Specify the network interface IP (disable by default).\n" +
104-
"-interval:MILLISECONDS Specify the interval time in milliseconds (default is 1000).\n" +
110+
"-interval:MILLISECONDS Specify the time interval in milliseconds (default is 1000).\n" +
105111
"-csv Specify output format as CSV (disable by default).\n" +
106112
"process_1 ... process_n A space-separated list of processes names or PIDs (if empty, all running processes are used).\n" +
107113
"\nCtrl + c Terminate the execution of the program.\n" +
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
22
"profiles": {
33
"ProcessPerformance": {
4-
"commandName": "Project",
5-
"commandLineArgs": "chrome"
4+
"commandName": "Project"
65
}
76
}
87
}

ProcessPerformance/ReportData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace ProcessPerformance
1515
// Encapsulates all the information collected in the report. //
1616
// -------------------------------------------------------------------------//
1717
//////////////////////////////////////////////////////////////////////////////
18-
18+
1919
/// <summary>
2020
/// Encapsulates all the information collected in the report.
2121
/// </summary>

README.md

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,41 @@
11
# ProcessPerformance
2-
ProcessPerformance is a tool that allows you to collect performance data and memory and network of running processes.
2+
ProcessPerformance is an easy-to-use command-line tool that provides runtime information about the CPU, memory, and network resources consumed by any combination of running processes. It does not inject code in the program sources or the binaries, avoiding the overhead caused by that measurement technique. ProcessPerformance is implemented as an open-source .NET Core application, which runs on Linux, macOS, and Windows.
33

44
## Prerequisites
5-
[.NET Core Runtime 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1) or higher
5+
[.NET Core Runtime 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1) or higher.
66

77
## Usage
8-
To run ProcessPerformance you just need to execute:
8+
To run ProcessPerformance on Windows, you just need to execute:
99

1010
```bash
1111
ProcessPerformance.exe
1212
```
13+
On Linux and macOS:
14+
15+
```bash
16+
dotnet run ProcessPerformance
17+
```
1318

1419
This will start the process performance reporter with default parameters.
1520

1621
## Options
17-
* `-help` Displays the usage message
18-
* `-network:NETWORK_IP` Specify the network interface IP (disable by default).
19-
* `-interval:MILISENCONS` Specify the interval time in milisecons (default is 1000).
20-
* `-csv` Specify output format as CSV (disable by default).
21-
* `process_1 ... process_n` A list of process names (if empty, all running processes are used).
22-
* `Ctrl + c` interrupts the execution.
22+
* `-help` Display the command line arguments.
23+
* `-network:NETWORK_IP` Specify P address of the network interface used to measure data transmission (disabled by default).
24+
* `-interval:MILLISECONDS` The interval used to gather the runtime information of resource consumption, expressed in milliseconds. The default value is 1,000 (one second).
25+
* `-csv` Show the output in comma-separated values (CSV) format (disabled by default).
26+
* `process_1 ... process_n` A space-separated list of the names or PIDs (process identifiers) of the processes to be monitored. If no process is passed, the overall system resources are displayed.
27+
* `Ctrl + c` Terminate the execution of ProcessPerformance.
2328

2429
## Example
25-
An example of use is monitoring Google Chrome and Microsoft Teams applications every 5 seconds, including system network traffic.
30+
An example of use is monitoring Google Chrome and Microsoft Teams applications every 5 seconds, including system network traffic:
2631

2732
```bash
28-
ProcessPerformance.exe -network:192.168.0.100 -interval:500 chrome teams
33+
ProcessPerformance.exe -network:192.168.0.100 -interval:5000 chrome teams
2934

30-
chrome+teams (34 ths) = CPU: 5,18 % | Memory: 3.999 MB | Process: Sent 0 KB (0 kbps) - Received 0 KB (0 kbps) | Network: Sent 12 KB (89 kbps) - Received 4 KB (29 kbps)
31-
chrome+teams (26 ths) = CPU: 1,69 % | Memory: 3.761 MB | Process: Sent 3 KB (24 kbps) - Received 29 KB (237 kbps) | Network: Sent 42 KB (219 kbps) - Received 62 KB (431 kbps)
32-
chrome+teams (20 ths) = CPU: 0,00 % | Memory: 3.294 MB | Process: Sent 46 KB (350 kbps) - Received 96 KB (542 kbps) | Network: Sent 169 KB (918 kbps) - Received 287 KB (1.622 kbps)
33-
chrome+teams (24 ths) = CPU: 11,53 % | Memory: 3.425 MB | Process: Sent 93 KB (382 kbps) - Received 201 KB (864 kbps) | Network: Sent 242 KB (562 kbps) - Received 380 KB (716 kbps)
35+
chrome+teams (34 processes) = CPU: 5.18 % | Memory: 3,999 MB | Processes: Sent 0 KB (0 kbps) - Received 0 KB (0 kbps) | Network: Sent 12 KB (89 kbps) - Received 4 KB (29 kbps)
36+
chrome+teams (26 processes) = CPU: 1.69 % | Memory: 3,761 MB | Processes: Sent 3 KB (24 kbps) - Received 29 KB (237 kbps) | Network: Sent 42 KB (219 kbps) - Received 62 KB (431 kbps)
37+
chrome+teams (20 processes) = CPU: 0.00 % | Memory: 3,294 MB | Processes: Sent 46 KB (350 kbps) - Received 96 KB (542 kbps) | Network: Sent 169 KB (918 kbps) - Received 287 KB (1,622 kbps)
38+
chrome+teams (24 processes) = CPU: 11.53 % | Memory: 3,425 MB | Processes: Sent 93 KB (382 kbps) - Received 201 KB (864 kbps) | Network: Sent 242 KB (562 kbps) - Received 380 KB (716 kbps)
3439
...
3540
```
3641

0 commit comments

Comments
 (0)