process-metrics 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21b2cec0ce445dbf8e7401a91b2ef3698c2b2d0dc1faa497e6c5e18cbb80efbe
4
- data.tar.gz: 0d7004039c130aa4c13aafcf3bbe867fbded7a9968bb5cf1f1f64e8e153c518c
3
+ metadata.gz: 43c70d72392b299b8219b1bb1d5762de8d4ee116568ebd4ada928ba946d3ae96
4
+ data.tar.gz: d0c5a4ab4a3fd2935e95667fff758c20c87f14165776dec5b908f544cc24a590
5
5
  SHA512:
6
- metadata.gz: a368497ef8239069aadbbbdf507892f516d7109325f5e5363b6c666abf4df2fac788b4406e2f596af2151d67f3cb433a937ca9a55c63ba1289874427a3bb5763
7
- data.tar.gz: 1022c8a322daf3b779324d8a8ec04daf2014336c80e9feb3f4686eefd0ff918d08b24f1fd4d626fa7df69732fdae93199a320c4769654ac75dbece2ad12c0225
6
+ metadata.gz: 91961040cacd7a310a28ab42b76ff4f73386bdbd77a36138b7e5e4a3704fed2e6184ad493629ad501e45473c0013bbe675a4c159d74efc723a1cdb138b1a1df7
7
+ data.tar.gz: 9de09390fbc96a7dc208914fd18aeed8d0380f49fb3bc4ab8bf33ec1e15dba671d48921eb71460a33aba779d409cd4180c7f811f42ff736ddd4bf48d2971958e
checksums.yaml.gz.sig CHANGED
Binary file
@@ -51,18 +51,18 @@ module Process
51
51
 
52
52
  # Capture memory usage for the given process IDs.
53
53
  def self.capture(pid, count: 1, **options)
54
- usage = Memory.zero
55
-
56
54
  IO.popen(["vmmap", pid.to_s], "r") do |io|
55
+ usage = Memory.zero
56
+
57
57
  io.each_line do |line|
58
58
  if match = LINE.match(line)
59
+ usage.map_count += 1
60
+
59
61
  virtual_size = parse_size(match[:virtual_size])
60
62
  resident_size = parse_size(match[:resident_size])
61
63
  dirty_size = parse_size(match[:dirty_size])
62
64
  swap_size = parse_size(match[:swap_size])
63
65
 
64
- # Update counts
65
- usage.map_count += 1
66
66
  usage.resident_size += resident_size
67
67
  usage.swap_size += swap_size
68
68
 
@@ -84,13 +84,21 @@ module Process
84
84
  end
85
85
  end
86
86
  end
87
+
88
+ if usage.map_count.zero?
89
+ # vmap might not fail, but also might not return any data.
90
+ return nil
91
+ end
92
+
93
+ # Darwin does not expose proportional memory usage, so we guess based on the number of processes. Yes, this is a terrible hack, but it's the most reasonable thing to do given the constraints:
94
+ usage.proportional_size = usage.resident_size / count
95
+ usage.proportional_swap_size = usage.swap_size / count
96
+
97
+ return usage
87
98
  end
88
-
89
- # Darwin does not expose proportional memory usage, so we guess based on the number of processes. Yes, this is a terrible hack, but it's the most reasonable thing to do given the constraints:
90
- usage.proportional_size = usage.resident_size / count
91
- usage.proportional_swap_size = usage.swap_size / count
92
-
93
- return usage
99
+ rescue Errno::ESRCH
100
+ # Process doesn't exist.
101
+ return nil
94
102
  end
95
103
  end
96
104
 
@@ -20,7 +20,7 @@ module Process
20
20
  usage.minor_faults = fields[10-3].to_i
21
21
  usage.major_faults = fields[12-3].to_i
22
22
  rescue
23
- # Be robust to unexpected formats; ignore errors silently.
23
+ # Ignore.
24
24
  end
25
25
 
26
26
  # @returns [Numeric] Total memory size in kilobytes.
@@ -54,10 +54,10 @@ module Process
54
54
 
55
55
  # Capture memory usage for the given process IDs.
56
56
  def self.capture(pid, **options)
57
- usage = Memory.zero
58
-
59
- begin
60
- File.foreach("/proc/#{pid}/smaps_rollup") do |line|
57
+ File.open("/proc/#{pid}/smaps_rollup") do |file|
58
+ usage = Memory.zero
59
+
60
+ file.each_line do |line|
61
61
  if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line
62
62
  if key = SMAP[name]
63
63
  usage[key] += value.to_i
@@ -68,11 +68,12 @@ module Process
68
68
  usage.map_count += File.readlines("/proc/#{pid}/maps").size
69
69
  # Also capture fault counters:
70
70
  self.capture_faults(pid, usage)
71
- rescue Errno::ENOENT, Errno::ESRCH
72
- # Ignore, process may have ended.
71
+
72
+ return usage
73
73
  end
74
-
75
- return usage
74
+ rescue Errno::ENOENT, Errno::ESRCH
75
+ # Process doesn't exist.
76
+ return nil
76
77
  end
77
78
  elsif File.readable?("/proc/self/smaps")
78
79
  # Whether the memory usage can be captured on this system.
@@ -82,10 +83,10 @@ module Process
82
83
 
83
84
  # Capture memory usage for the given process IDs.
84
85
  def self.capture(pid, **options)
85
- usage = Memory.zero
86
-
87
- begin
88
- File.foreach("/proc/#{pid}/smaps") do |line|
86
+ File.open("/proc/#{pid}/smaps") do |file|
87
+ usage = Memory.zero
88
+
89
+ file.each_line do |line|
89
90
  # The format of this is fixed according to:
90
91
  # https://github.com/torvalds/linux/blob/351c8a09b00b5c51c8f58b016fffe51f87e2d820/fs/proc/task_mmu.c#L804-L814
91
92
  if /(?<name>.*?):\s+(?<value>\d+) kB/ =~ line
@@ -98,13 +99,15 @@ module Process
98
99
  usage.map_count += 1
99
100
  end
100
101
  end
102
+
101
103
  # Also capture fault counters:
102
104
  self.capture_faults(pid, usage)
103
- rescue Errno::ENOENT, Errno::ESRCH
104
- # Ignore, process may have ended.
105
+
106
+ return usage
105
107
  end
106
-
107
- return usage
108
+ rescue Errno::ENOENT, Errno::ESRCH
109
+ # Process doesn't exist.
110
+ return nil
108
111
  end
109
112
  else
110
113
  def self.supported?
@@ -7,6 +7,6 @@
7
7
  module Process
8
8
  # @namespace
9
9
  module Metrics
10
- VERSION = "0.6.1"
10
+ VERSION = "0.7.0"
11
11
  end
12
12
  end
data/readme.md CHANGED
@@ -16,6 +16,10 @@ Please see the [project documentation](https://socketry.github.io/process-metric
16
16
 
17
17
  Please see the [project releases](https://socketry.github.io/process-metrics/releases/index) for all releases.
18
18
 
19
+ ### v0.7.0
20
+
21
+ - Be more proactive about returning nil if memory capture failed.
22
+
19
23
  ### v0.6.1
20
24
 
21
25
  - Handle `Errno::ESRCH: No such process @ io_fillbuf - fd:xxx /proc/xxx/smaps_rollup` by ignoring it.
@@ -69,14 +73,6 @@ Please see the [project releases](https://socketry.github.io/process-metrics/rel
69
73
  - Fixed process metrics to exclude the `ps` command itself from measurements.
70
74
  - Fixed documentation formatting issues.
71
75
 
72
- ### v0.1.0
73
-
74
- - Initial release with support for process and memory metrics on Linux and Darwin (macOS).
75
- - Support for selecting processes based on PID or PPID (process group).
76
- - Implementation of memory statistics collection using `/proc` filesystem on Linux.
77
- - Better handling of process hierarchies.
78
- - Support for older Ruby versions.
79
-
80
76
  ## Contributing
81
77
 
82
78
  We welcome contributions to this project.
data/releases.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Releases
2
2
 
3
+ ## v0.7.0
4
+
5
+ - Be more proactive about returning nil if memory capture failed.
6
+
3
7
  ## v0.6.1
4
8
 
5
9
  - Handle `Errno::ESRCH: No such process @ io_fillbuf - fd:xxx /proc/xxx/smaps_rollup` by ignoring it.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: process-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
metadata.gz.sig CHANGED
Binary file