process-metrics 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1dfdad473ae6b2f7680c1c62bf67144c0451014c61e6a4d9c38650d2b51dcc86
4
- data.tar.gz: 5938c811e5b7cab7d849b9430236bd60712158fe744ee5b494e3d01f0ed49997
3
+ metadata.gz: 42d11b0f2e725706c447c1b4cfa3f15a961f759fb8cacf0ef0d238338c3be6ab
4
+ data.tar.gz: 80468efcb1b3eab151f8fcf0d054d93d11dcd90127ec70a6ad63e5fc10b68f89
5
5
  SHA512:
6
- metadata.gz: 2c607a0f1eb78abe097463ebd46784f2212b60b6bc5590dff646aecac131e5da59eb0e3a5ea082943c66d3fc0cb4425d19abb3596ed0350aec51718ac6fb4244
7
- data.tar.gz: 420abffc1c85856674376cf95455972e58a18b18591ccc003be3e0d9bad6212d17587d93e10c0ec06691c60c187ba43e80af472c8c74be619f4e06f370780d3d
6
+ metadata.gz: 5c765d57991e1a15e8c966ea1497234dae6e8e98cdd8e2463cefe1caf046770b1930b01b68b202b7ace9d802ad6d0577dfbb3cfef48a1d23abc3013ea5a48580
7
+ data.tar.gz: 8c2bf4692a659037dc8167ad7f3349beb300e4bf021ee97b8ed3bf645cc83eaeefa19ae6ef5aee62855d781f7782ab9750d3999ca21982b865c24afbb65a0be5
checksums.yaml.gz.sig CHANGED
Binary file
data/bin/process-metrics CHANGED
@@ -21,7 +21,7 @@
21
21
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
  # THE SOFTWARE.
23
23
 
24
- require_relative '../lib/process/metrics/command'
24
+ require_relative "../lib/process/metrics/command"
25
25
 
26
26
  begin
27
27
  Process::Metrics::Command.call
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2020-2024, by Samuel Williams.
4
+ # Copyright, 2020-2025, by Samuel Williams.
5
5
 
6
- require 'samovar'
6
+ require "samovar"
7
7
 
8
- require_relative '../general'
8
+ require_relative "../general"
9
9
 
10
- require 'console/terminal'
10
+ require "console/terminal"
11
11
 
12
12
  module Process
13
13
  module Metrics
@@ -42,10 +42,8 @@ module Process
42
42
  self.description = "Display a summary of memory usage statistics."
43
43
 
44
44
  options do
45
- option '--pid <integer>', "Report on a single process id.", type: Integer, required: true
46
- option '-p/--ppid <integer>', "Report on all children of this process id.", type: Integer, required: true
47
-
48
- option '--memory-scale <integer>', "Scale maximum memory usage to the specified amount (MiB).", type: Integer, default: 512
45
+ option "--pid <integer>", "Report on a single process id.", type: Integer, required: true
46
+ option "-p/--ppid <integer>", "Report on all children of this process id.", type: Integer, required: true
49
47
  end
50
48
 
51
49
  def terminal
@@ -89,18 +87,18 @@ module Process
89
87
  return "#{value.round(unit)}#{units[unit]}"
90
88
  end
91
89
 
92
- def format_memory_usage(value, terminal, scale: @options[:memory_scale])
93
- if value > (1024.0 * scale * 0.8)
90
+ def format_memory_usage(value, total, terminal)
91
+ if value > (total * 0.8)
94
92
  intensity = :high
95
- elsif value > (1024.0 * scale * 0.5)
93
+ elsif value > (total * 0.5)
96
94
  intensity = :medium
97
95
  else
98
96
  intensity = :low
99
97
  end
100
98
 
101
- formatted = (format_size(value) + ' ').rjust(10)
99
+ formatted = (format_size(value) + " ").rjust(10)
102
100
 
103
- terminal.print(formatted, intensity, "[", Bar.format(value / (1024.0 * scale), 60), "]", :reset)
101
+ terminal.print(formatted, intensity, "[", Bar.format(value / total.to_f, 60), "]", :reset)
104
102
  end
105
103
 
106
104
  def call
@@ -111,6 +109,15 @@ module Process
111
109
  format_memory_usage = self.method(:format_memory_usage).curry
112
110
  shared_memory_usage = 0
113
111
  private_memory_usage = 0
112
+ total_memory_usage = 0
113
+
114
+ summary.each do |pid, general|
115
+ if memory = general.memory
116
+ total_memory_usage += memory.proportional_size + memory.unique_size
117
+ else
118
+ total_memory_usage += general.resident_size
119
+ end
120
+ end
114
121
 
115
122
  proportional = true
116
123
 
@@ -126,21 +133,21 @@ module Process
126
133
  private_memory_usage += memory.unique_size
127
134
 
128
135
  terminal.print_line(
129
- :key, "Memory (PSS): ".rjust(20), :reset,
130
- format_memory_usage[memory.proportional_size]
136
+ :key, "Shared Memory: ".rjust(20), :reset,
137
+ format_memory_usage[memory.proportional_size, total_memory_usage]
131
138
  )
132
139
 
133
140
  terminal.print_line(
134
- :key, "Private (USS): ".rjust(20), :reset,
135
- format_memory_usage[memory.unique_size]
141
+ :key, "Private Memory: ".rjust(20), :reset,
142
+ format_memory_usage[memory.unique_size, total_memory_usage]
136
143
  )
137
144
  else
138
- shared_memory_usage += general.rss
145
+ shared_memory_usage += general.resident_size
139
146
  proportional = false
140
147
 
141
148
  terminal.print_line(
142
- :key, "Memory (RSS): ".rjust(20), :reset,
143
- format_memory_usage[general.rss]
149
+ :key, "Memory: ".rjust(20), :reset,
150
+ format_memory_usage[general.resident_size, total_memory_usage]
144
151
  )
145
152
  end
146
153
  end
@@ -149,24 +156,24 @@ module Process
149
156
 
150
157
  if proportional
151
158
  terminal.print_line(
152
- :key, "Memory (PSS): ".rjust(20), :reset,
153
- format_memory_usage[shared_memory_usage]
159
+ :key, "Shared Memory: ".rjust(20), :reset,
160
+ format_memory_usage[shared_memory_usage, total_memory_usage]
154
161
  )
155
162
 
156
163
  terminal.print_line(
157
- :key, "Memory (USS): ".rjust(20), :reset,
158
- format_memory_usage[private_memory_usage]
164
+ :key, "Private Memory: ".rjust(20), :reset,
165
+ format_memory_usage[private_memory_usage, total_memory_usage]
159
166
  )
160
167
  else
161
168
  terminal.print_line(
162
- :key, "Memory (RSS): ".rjust(20), :reset,
163
- format_memory_usage[memory_usage]
169
+ :key, "Memory: ".rjust(20), :reset,
170
+ format_memory_usage[memory_usage, total_memory_usage]
164
171
  )
165
172
  end
166
173
 
167
174
  terminal.print_line(
168
175
  :key, "Memory (Total): ".rjust(20), :reset,
169
- format_memory_usage[shared_memory_usage + private_memory_usage]
176
+ format_memory_usage[shared_memory_usage + private_memory_usage, total_memory_usage]
170
177
  )
171
178
  end
172
179
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2020-2024, by Samuel Williams.
4
+ # Copyright, 2020-2025, by Samuel Williams.
5
5
 
6
- require 'samovar'
6
+ require "samovar"
7
7
 
8
- require_relative 'summary'
9
- require_relative '../version'
8
+ require_relative "summary"
9
+ require_relative "../version"
10
10
 
11
11
  module Process
12
12
  module Metrics
@@ -15,13 +15,13 @@ module Process
15
15
  self.description = "Collect memory usage statistics."
16
16
 
17
17
  options do
18
- option '-h/--help', "Print out help information."
19
- option '-v/--version', "Print out the application version."
18
+ option "-h/--help", "Print out help information."
19
+ option "-v/--version", "Print out the application version."
20
20
  end
21
21
 
22
22
  nested :command, {
23
- 'summary' => Summary,
24
- }, default: 'summary'
23
+ "summary" => Summary,
24
+ }, default: "summary"
25
25
 
26
26
  def call
27
27
  if @options[:version]
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2020-2024, by Samuel Williams.
4
+ # Copyright, 2020-2025, by Samuel Williams.
5
5
 
6
- require_relative 'command/top'
6
+ require_relative "command/top"
7
7
 
8
8
  module Process
9
9
  module Metrics
@@ -1,21 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
 
6
- require_relative 'memory'
7
- require 'set'
8
- require 'json'
6
+ require_relative "memory"
7
+ require "set"
8
+ require "json"
9
9
 
10
10
  module Process
11
11
  module Metrics
12
12
  PS = "ps"
13
13
 
14
+ DURATION = /\A
15
+ (?:(?<days>\d+)-)? # Optional days (e.g., '2-')
16
+ (?:(?<hours>\d+):)? # Optional hours (e.g., '1:')
17
+ (?<minutes>\d{1,2}): # Minutes (always present, 1 or 2 digits)
18
+ (?<seconds>\d{2}) # Seconds (exactly 2 digits)
19
+ (?:\.(?<fraction>\d{1,2}))? # Optional fraction of a second (e.g., '.27')
20
+ \z/x
21
+
22
+
14
23
  # Parse a duration string into seconds.
15
24
  # According to the linux manual page specifications.
16
25
  def self.duration(value)
17
- if /((?<days>\d\d)\-)?((?<hours>\d\d):)?(?<minutes>\d\d):(?<seconds>\d\d)?/ =~ value
18
- (((days&.to_i || 0) * 24 + (hours&.to_i || 0)) * 60 + (minutes&.to_i || 0)) * 60 + seconds&.to_i
26
+ if match = DURATION.match(value)
27
+ days = match[:days].to_i
28
+ hours = match[:hours].to_i
29
+ minutes = match[:minutes].to_i
30
+ seconds = match[:seconds].to_i
31
+ fraction = match[:fraction].to_i
32
+
33
+ return days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds + fraction / 100.0
34
+ else
35
+ return 0.0
19
36
  end
20
37
  end
21
38
 
@@ -25,10 +42,10 @@ module Process
25
42
  ppid: ->(value){value.to_i}, # Parent Process ID
26
43
  pgid: ->(value){value.to_i}, # Process Group ID
27
44
  pcpu: ->(value){value.to_f}, # Percentage CPU
28
- time: self.method(:duration), # CPU Time
29
- vsz: ->(value){value.to_i}, # Virtual Size
30
- rss: ->(value){value.to_i}, # Resident Size
31
- etime: self.method(:duration), # Elapsed Time
45
+ vsz: ->(value){value.to_i}, # Virtual Size (KiB)
46
+ rss: ->(value){value.to_i}, # Resident Size (KiB)
47
+ time: self.method(:duration), # CPU Time (seconds)
48
+ etime: self.method(:duration), # Elapsed Time (seconds)
32
49
  command: ->(value){value}, # Command (name of the process)
33
50
  }
34
51
 
@@ -56,7 +73,7 @@ module Process
56
73
  as_json.to_json(*arguments)
57
74
  end
58
75
 
59
- # The general memory usage of the process using the best available information.
76
+ # The total size of the process in memory, in kilobytes.
60
77
  def total_size
61
78
  if memory = self.memory
62
79
  memory.proportional_size
@@ -105,18 +122,18 @@ module Process
105
122
  #
106
123
  # @parameter pid [Integer] The process ID to capture.
107
124
  # @parameter ppid [Integer] The parent process ID to capture.
108
- def self.capture(pid: nil, ppid: nil, ps: PS)
125
+ def self.capture(pid: nil, ppid: nil, ps: PS, memory: Memory.supported?)
109
126
  input, output = IO.pipe
110
127
 
111
128
  arguments = [ps]
112
129
 
113
130
  if pid && ppid.nil?
114
- arguments.push("-p", Array(pid).join(','))
131
+ arguments.push("-p", Array(pid).join(","))
115
132
  else
116
133
  arguments.push("ax")
117
134
  end
118
135
 
119
- arguments.push("-o", FIELDS.keys.join(','))
136
+ arguments.push("-o", FIELDS.keys.join(","))
120
137
 
121
138
  ps_pid = Process.spawn(*arguments, out: output, pgroup: true)
122
139
 
@@ -130,7 +147,6 @@ module Process
130
147
  record = FIELDS.
131
148
  zip(line.split(/\s+/, FIELDS.size)).
132
149
  map{|(key, type), value| type.call(value)}
133
-
134
150
  instance = self.new(*record)
135
151
 
136
152
  processes[instance.process_id] = instance
@@ -151,12 +167,8 @@ module Process
151
167
  end
152
168
  end
153
169
 
154
- if Memory.supported?
170
+ if memory
155
171
  self.capture_memory(processes)
156
-
157
- # if pid
158
- # self.compute_summary(pid, processes)
159
- # end
160
172
  end
161
173
 
162
174
  return processes
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ module Process
7
+ module Metrics
8
+ class Memory::Darwin
9
+ VMMAP = "/usr/bin/vmmap"
10
+
11
+ # Whether the memory usage can be captured on this system.
12
+ def self.supported?
13
+ File.executable?(VMMAP)
14
+ end
15
+
16
+ # Parse a size string into kilobytes.
17
+ def self.parse_size(string)
18
+ return 0 unless string
19
+
20
+ case string.strip
21
+ when /([\d\.]+)K/i then ($1.to_f).round
22
+ when /([\d\.]+)M/i then ($1.to_f * 1024).round
23
+ when /([\d\.]+)G/i then ($1.to_f * 1024 * 1024).round
24
+ else (string.to_f / 1024).ceil
25
+ end
26
+ end
27
+
28
+ LINE = /\A
29
+ \s*
30
+ (?<region_name>.+?)\s+
31
+ (?<start_address>[0-9a-fA-F]+)-(?<end_address>[0-9a-fA-F]+)\s+
32
+ \[\s*(?<virtual_size>[\d\.]+[KMG]?)\s+(?<resident_size>[\d\.]+[KMG]?)\s+(?<dirty_size>[\d\.]+[KMG]?)\s+(?<swap_size>[\d\.]+[KMG]?)\s*\]\s+
33
+ (?<permissions>[rwx\-\/]+)\s+
34
+ SM=(?<sharing_mode>\w+)
35
+ /x
36
+
37
+ # Capture memory usage for the given process IDs.
38
+ def self.capture(pids)
39
+ usage = Memory.zero
40
+
41
+ pids.each do |pid|
42
+ IO.popen(["vmmap", pid.to_s], "r") do |io|
43
+ io.each_line do |line|
44
+ if match = LINE.match(line)
45
+ virtual_size = parse_size(match[:virtual_size])
46
+ resident_size = parse_size(match[:resident_size])
47
+ dirty_size = parse_size(match[:dirty_size])
48
+ swap_size = parse_size(match[:swap_size])
49
+
50
+ # puts [match[:region_name], virtual_size, resident_size, dirty_size, swap_size, match[:permissions], match[:sharing_mode]].join(",")
51
+
52
+ # Update counts
53
+ usage.map_count += 1
54
+ usage.resident_size += resident_size
55
+ usage.swap_size += swap_size
56
+
57
+ # Private vs. Shared memory
58
+ # COW=copy_on_write PRV=private NUL=empty ALI=aliased
59
+ # SHM=shared ZER=zero_filled S/A=shared_alias
60
+ case match[:sharing_mode]
61
+ when "PRV"
62
+ usage.private_clean_size += resident_size - dirty_size
63
+ usage.private_dirty_size += dirty_size
64
+ when "COW", "SHM"
65
+ usage.shared_clean_size += resident_size - dirty_size
66
+ usage.shared_dirty_size += dirty_size
67
+ end
68
+
69
+ # Anonymous memory: no region detail path or special names
70
+ if match[:region_name] =~ /MALLOC|VM_ALLOCATE|Stack|STACK|anonymous/
71
+ usage.anonymous_size += resident_size
72
+ end
73
+ # else
74
+ # puts "Failed to match line: #{line}"
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ # On Darwin, we cannot compute the proportional size, so we just set it to the resident size.
81
+ usage.proportional_size = usage.resident_size
82
+ usage.proportional_swap_size = usage.swap_size
83
+
84
+ return usage
85
+ end
86
+ end
87
+
88
+ if Memory::Darwin.supported?
89
+ class << Memory
90
+ def supported?
91
+ return true
92
+ end
93
+
94
+ def capture(pids)
95
+ return Memory::Darwin.capture(pids)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ module Process
7
+ module Metrics
8
+ class Memory::Linux
9
+ # The fields that will be extracted from the `smaps` data.
10
+ SMAP = {
11
+ "Rss" => :resident_size,
12
+ "Pss" => :proportional_size,
13
+ "Shared_Clean" => :shared_clean_size,
14
+ "Shared_Dirty" => :shared_dirty_size,
15
+ "Private_Clean" => :private_clean_size,
16
+ "Private_Dirty" => :private_dirty_size,
17
+ "Referenced" => :referenced_size,
18
+ "Anonymous" => :anonymous_size,
19
+ "Swap" => :swap_size,
20
+ "SwapPss" => :proportional_swap_size,
21
+ }
22
+
23
+ if File.readable?("/proc/self/smaps_rollup")
24
+ # Whether the memory usage can be captured on this system.
25
+ def self.supported?
26
+ true
27
+ end
28
+
29
+ # Capture memory usage for the given process IDs.
30
+ def self.capture(pids)
31
+ usage = Memory.zero
32
+
33
+ pids.each do |pid|
34
+ File.foreach("/proc/#{pid}/smaps_rollup") do |line|
35
+ if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line
36
+ if key = SMAP[name]
37
+ usage[key] += value.to_i
38
+ end
39
+ end
40
+ end
41
+
42
+ usage.map_count += File.readlines("/proc/#{pid}/maps").size
43
+ rescue Errno::ENOENT => error
44
+ # Ignore.
45
+ end
46
+
47
+ return usage
48
+ end
49
+ elsif File.readable?("/proc/self/smaps")
50
+ # Whether the memory usage can be captured on this system.
51
+ def self.supported?
52
+ true
53
+ end
54
+
55
+ # Capture memory usage for the given process IDs.
56
+ def self.capture(pids)
57
+ usage = Memory.zero
58
+
59
+ pids.each do |pid|
60
+ File.foreach("/proc/#{pid}/smaps") do |line|
61
+ # The format of this is fixed according to:
62
+ # https://github.com/torvalds/linux/blob/351c8a09b00b5c51c8f58b016fffe51f87e2d820/fs/proc/task_mmu.c#L804-L814
63
+ if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line
64
+ if key = SMAP[name]
65
+ usage[key] += value.to_i
66
+ end
67
+ elsif /VmFlags:\s+(?<flags>.*)/ =~ line
68
+ # It should be possible to extract the number of fibers and each fiber's memory usage.
69
+ # flags = flags.split(/\s+/)
70
+ usage.map_count += 1
71
+ end
72
+ end
73
+ rescue Errno::ENOENT => error
74
+ # Ignore.
75
+ end
76
+
77
+ return usage
78
+ end
79
+ else
80
+ def self.supported?
81
+ false
82
+ end
83
+ end
84
+ end
85
+
86
+ if Memory::Linux.supported?
87
+ class << Memory
88
+ def supported?
89
+ return true
90
+ end
91
+
92
+ def capture(pids)
93
+ return Memory::Linux.capture(pids)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2019-2024, by Samuel Williams.
4
+ # Copyright, 2019-2025, by Samuel Williams.
5
5
 
6
- require 'json'
6
+ require "json"
7
7
 
8
8
  module Process
9
9
  module Metrics
10
+ # Represents memory usage for a process, sizes are in kilobytes.
10
11
  class Memory < Struct.new(:map_count, :resident_size, :proportional_size, :shared_clean_size, :shared_dirty_size, :private_clean_size, :private_dirty_size, :referenced_size, :anonymous_size, :swap_size, :proportional_swap_size)
11
12
 
12
13
  alias as_json to_h
@@ -26,87 +27,22 @@ module Process
26
27
  self.private_clean_size + self.private_dirty_size
27
28
  end
28
29
 
29
- # The fields that will be extracted from the `smaps` data.
30
- MAP = {
31
- "Rss" => :resident_size,
32
- "Pss" => :proportional_size,
33
- "Shared_Clean" => :shared_clean_size,
34
- "Shared_Dirty" => :shared_dirty_size,
35
- "Private_Clean" => :private_clean_size,
36
- "Private_Dirty" => :private_dirty_size,
37
- "Referenced" => :referenced_size,
38
- "Anonymous" => :anonymous_size,
39
- "Swap" => :swap_size,
40
- "SwapPss" => :proportional_swap_size,
41
- }
30
+ def self.zero
31
+ self.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
32
+ end
33
+
34
+ # Whether the memory usage can be captured on this system.
35
+ def self.supported?
36
+ false
37
+ end
42
38
 
43
- if File.readable?('/proc/self/smaps_rollup')
44
- # Whether the memory usage can be captured on this system.
45
- def self.supported?
46
- true
47
- end
48
-
49
- # Capture memory usage for the given process IDs.
50
- def self.capture(pids)
51
- usage = self.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
52
-
53
- pids.each do |pid|
54
- File.foreach("/proc/#{pid}/smaps_rollup") do |line|
55
- if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line
56
- if key = MAP[name]
57
- usage[key] += value.to_i
58
- end
59
- end
60
- end
61
-
62
- usage.map_count += File.readlines("/proc/#{pid}/maps").size
63
- rescue Errno::ENOENT => error
64
- # Ignore.
65
- end
66
-
67
- return usage
68
- end
69
- elsif File.readable?('/proc/self/smaps')
70
- # Whether the memory usage can be captured on this system.
71
- def self.supported?
72
- true
73
- end
74
-
75
- # Capture memory usage for the given process IDs.
76
- def self.capture(pids)
77
- usage = self.new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
78
-
79
- pids.each do |pid|
80
- File.foreach("/proc/#{pid}/smaps") do |line|
81
- # The format of this is fixed according to:
82
- # https://github.com/torvalds/linux/blob/351c8a09b00b5c51c8f58b016fffe51f87e2d820/fs/proc/task_mmu.c#L804-L814
83
- if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line
84
- if key = MAP[name]
85
- usage[key] += value.to_i
86
- end
87
- elsif /VmFlags:\s+(?<flags>.*)/ =~ line
88
- # It should be possible to extract the number of fibers and each fiber's memory usage.
89
- # flags = flags.split(/\s+/)
90
- usage.map_count += 1
91
- end
92
- end
93
- rescue Errno::ENOENT => error
94
- # Ignore.
95
- end
96
-
97
- return usage
98
- end
99
- else
100
- # Whether the memory usage can be captured on this system.
101
- def self.supported?
102
- false
103
- end
104
-
105
- # Capture memory usage for the given process IDs.
106
- def self.capture(pids)
107
- return self.new
108
- end
39
+ # Capture memory usage for the given process IDs.
40
+ def self.capture(pids)
41
+ return nil
109
42
  end
110
43
  end
111
44
  end
112
45
  end
46
+
47
+ require_relative "memory/linux"
48
+ require_relative "memory/darwin"
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Process
7
7
  module Metrics
8
- VERSION = "0.3.0"
8
+ VERSION = "0.4.0"
9
9
  end
10
10
  end
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2019-2024, by Samuel Williams.
3
+ Copyright, 2019-2025, by Samuel Williams.
4
4
  Copyright, 2024, by Adam Daniels.
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
data/readme.md CHANGED
@@ -24,8 +24,8 @@ We welcome contributions to this project.
24
24
 
25
25
  ### Developer Certificate of Origin
26
26
 
27
- This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
27
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
28
28
 
29
- ### Contributor Covenant
29
+ ### Community Guidelines
30
30
 
31
- This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
31
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,12 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: process-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  - Adam Daniels
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain:
12
11
  - |
@@ -38,7 +37,7 @@ cert_chain:
38
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
39
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
40
39
  -----END CERTIFICATE-----
41
- date: 2024-04-06 00:00:00.000000000 Z
40
+ date: 2025-02-21 00:00:00.000000000 Z
42
41
  dependencies:
43
42
  - !ruby/object:Gem::Dependency
44
43
  name: console
@@ -55,35 +54,33 @@ dependencies:
55
54
  - !ruby/object:Gem::Version
56
55
  version: '1.8'
57
56
  - !ruby/object:Gem::Dependency
58
- name: samovar
57
+ name: json
59
58
  requirement: !ruby/object:Gem::Requirement
60
59
  requirements:
61
60
  - - "~>"
62
61
  - !ruby/object:Gem::Version
63
- version: '2.1'
62
+ version: '2'
64
63
  type: :runtime
65
64
  prerelease: false
66
65
  version_requirements: !ruby/object:Gem::Requirement
67
66
  requirements:
68
67
  - - "~>"
69
68
  - !ruby/object:Gem::Version
70
- version: '2.1'
69
+ version: '2'
71
70
  - !ruby/object:Gem::Dependency
72
- name: json
71
+ name: samovar
73
72
  requirement: !ruby/object:Gem::Requirement
74
73
  requirements:
75
74
  - - "~>"
76
75
  - !ruby/object:Gem::Version
77
- version: '2'
76
+ version: '2.1'
78
77
  type: :runtime
79
78
  prerelease: false
80
79
  version_requirements: !ruby/object:Gem::Requirement
81
80
  requirements:
82
81
  - - "~>"
83
82
  - !ruby/object:Gem::Version
84
- version: '2'
85
- description:
86
- email:
83
+ version: '2.1'
87
84
  executables:
88
85
  - process-metrics
89
86
  extensions: []
@@ -96,6 +93,8 @@ files:
96
93
  - lib/process/metrics/command/top.rb
97
94
  - lib/process/metrics/general.rb
98
95
  - lib/process/metrics/memory.rb
96
+ - lib/process/metrics/memory/darwin.rb
97
+ - lib/process/metrics/memory/linux.rb
99
98
  - lib/process/metrics/version.rb
100
99
  - license.md
101
100
  - readme.md
@@ -106,7 +105,6 @@ metadata:
106
105
  documentation_uri: https://socketry.github.io/process-metrics/
107
106
  funding_uri: https://github.com/sponsors/ioquatix
108
107
  source_code_uri: https://github.com/socketry/process-metrics.git
109
- post_install_message:
110
108
  rdoc_options: []
111
109
  require_paths:
112
110
  - lib
@@ -114,15 +112,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
112
  requirements:
115
113
  - - ">="
116
114
  - !ruby/object:Gem::Version
117
- version: '0'
115
+ version: '3.1'
118
116
  required_rubygems_version: !ruby/object:Gem::Requirement
119
117
  requirements:
120
118
  - - ">="
121
119
  - !ruby/object:Gem::Version
122
120
  version: '0'
123
121
  requirements: []
124
- rubygems_version: 3.5.3
125
- signing_key:
122
+ rubygems_version: 3.6.2
126
123
  specification_version: 4
127
124
  summary: Provide detailed OS-specific process metrics.
128
125
  test_files: []
metadata.gz.sig CHANGED
@@ -1,3 +1,2 @@
1
- hn1��aZ��e0wv��Ѷ����)A�QjlX#���5Q��_F���|��b�ӎt�Q�&깆r���f�y-���cy�F�/J3��F��c��&e�:L�],p,��{o�h��#w$��3����7�1eǒ�����Yo�
2
- �7A�
3
- &&�{ _��Wl����J҂�5H��жѨ�v��~\G�Y͇ ���',<�⻺X��Z���S��I��Y|�Ѳ
1
+ <�)wGZ��5e�ݹ���qؿc��<��ˡR��v/�H��5 #^�� r��0����ٽB2k���G��WBc_=*Y���>[�| ��J�����[Q���j�]pY02jr�ʨ`�Q�+6��?�Ch%3J��R����&�A����� o'4$aƁpKQ4���v(�ގ������u=�f���h,(�� ���6��33�ӷo�
2
+ ig�kH(��#�0�nš�a�f����Ҙ(��i��C�Î\p�����Na��<�J+?N�:���ќ�>V-q�"��D �� `�K��z$!�W��N��N����Q�(��(D[\D����� �9`8u�NDK㏼Z����RNXn�~n