tddium-sys-proctable 0.9.2-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ ########################################################################
2
+ # bench_ps.rb
3
+ #
4
+ # Benchmark program to show overall speed and compare the block form
5
+ # versus the non-block form. You should run this benchmark via the
6
+ # 'rake bench' Rake task.
7
+ ########################################################################
8
+ require 'benchmark'
9
+ require 'sys/proctable'
10
+
11
+ MAX = 10
12
+
13
+ Benchmark.bm do |bench|
14
+ bench.report("Block form"){
15
+ MAX.times{ Sys::ProcTable.ps{} }
16
+ }
17
+
18
+ bench.report("Non-block form"){
19
+ MAX.times{ Sys::ProcTable.ps }
20
+ }
21
+ end
data/doc/top.txt ADDED
@@ -0,0 +1,47 @@
1
+ = Description
2
+ A simple 'top' interface for Ruby
3
+
4
+ = Prerequisites
5
+ Requires the "sys/proctable" package (which should be installed along
6
+ with this package).
7
+
8
+ = Synopsis
9
+ require "sys/top"
10
+
11
+ Sys::Top.top(5).each{ |ps|
12
+ p ps
13
+ }
14
+
15
+ = Constants
16
+ VERSION
17
+ Returns the version number of this package as a String.
18
+
19
+ = Class Methods
20
+ Sys::Top.top(number=10, field="pctcpu")
21
+ Returns an array of ProcTableStruct's. The size of the array (i.e. the
22
+ number of processes) that it returns is based on +number+, and sorted by
23
+ +pctcpu+. By default, the size and field values are 10 and "pctcpu",
24
+ respectively.
25
+
26
+ = Notes
27
+ Not all fields are available on all platforms. Please check your
28
+ platform specific documentation for which fields are available.
29
+
30
+ = Bugs
31
+ None that I'm aware of. Please log bug reports on the project page at
32
+ http://www.rubyforge.org/projects/sysutils
33
+
34
+ = License
35
+ Artistic 2.0
36
+
37
+ = Copyright
38
+ (C) 2004-2009 Daniel J. Berger
39
+ All Rights Reserved.
40
+
41
+ = Warranty
42
+ This package is provided "as is" and without any express or
43
+ implied warranties, including, without limitation, the implied
44
+ warranties of merchantability and fitness for a particular purpose.
45
+
46
+ = Author
47
+ Daniel J. Berger
@@ -0,0 +1,20 @@
1
+ #######################################################################
2
+ # example_ps.rb
3
+ #
4
+ # Generic test program that demonstrates the use of ProcTable.ps. You
5
+ # can run this via the 'rake example' task.
6
+ #
7
+ # Modify as you see fit
8
+ #######################################################################
9
+ require 'sys/proctable'
10
+ include Sys
11
+
12
+ puts "VERSION: " + ProcTable::VERSION
13
+ sleep 2
14
+
15
+ ProcTable.ps{ |s|
16
+ ProcTable.fields.each{ |field|
17
+ puts "#{field}: " + s.send(field).to_s
18
+ }
19
+ puts '=' * 30
20
+ }
@@ -0,0 +1,281 @@
1
+ # The Sys module serves as a namespace only.
2
+ module Sys
3
+
4
+ # The ProcTable class encapsulates process table information.
5
+ class ProcTable
6
+
7
+ # Error typically raised if the ProcTable.ps method fails.
8
+ class Error < StandardError; end
9
+
10
+ # There is no constructor
11
+ private_class_method :new
12
+
13
+ # The version of the sys-proctable library
14
+ VERSION = '0.9.1'
15
+
16
+ private
17
+
18
+ @mem_total = IO.read("/proc/meminfo")[/MemTotal.*/].split[1].to_i * 1024 rescue nil
19
+ @boot_time = IO.read("/proc/stat")[/btime.*/].split.last.to_i rescue nil
20
+
21
+ @fields = [
22
+ 'cmdline', # Complete command line
23
+ 'cwd', # Current working directory
24
+ 'environ', # Environment
25
+ 'exe', # Actual pathname of the executed command
26
+ 'fd', # File descriptors open by process
27
+ 'root', # Root directory of process
28
+ 'pid', # Process ID
29
+ 'comm', # Filename of executable
30
+ 'state', # Single character state abbreviation
31
+ 'ppid', # Parent process ID
32
+ 'pgrp', # Process group
33
+ 'session', # Session ID
34
+ 'tty_nr', # TTY (terminal) associated with the process
35
+ 'tpgid', # Group ID of the TTY
36
+ 'flags', # Kernel flags
37
+ 'minflt', # Number of minor faults
38
+ 'cminflt', # Number of minor faults of waited-for children
39
+ 'majflt', # Number of major faults
40
+ 'cmajflt', # Number of major faults of waited-for children
41
+ 'utime', # Number of user mode jiffies
42
+ 'stime', # Number of kernel mode jiffies
43
+ 'cutime', # Number of children's user mode jiffies
44
+ 'cstime', # Number of children's kernel mode jiffies
45
+ 'priority', # Nice value plus 15
46
+ 'nice', # Nice value
47
+ 'itrealvalue', # Time in jiffies before next SIGALRM
48
+ 'starttime', # Time in jiffies since system boot
49
+ 'vsize', # Virtual memory size in bytes
50
+ 'rss', # Resident set size
51
+ 'rlim', # Current limit on the rss in bytes
52
+ 'startcode', # Address above which program text can run
53
+ 'endcode', # Address below which program text can run
54
+ 'startstack', # Address of the startstack
55
+ 'kstkesp', # Kernel stack page address
56
+ 'kstkeip', # Kernel instruction pointer
57
+ 'signal', # Bitmap of pending signals
58
+ 'blocked', # Bitmap of blocked signals
59
+ 'sigignore', # Bitmap of ignored signals
60
+ 'sigcatch', # Bitmap of caught signals
61
+ 'wchan', # Channel in which the process is waiting
62
+ 'nswap', # Number of pages swapped
63
+ 'cnswap', # Cumulative nswap for child processes
64
+ 'exit_signal', # Signal to be sent to parent when process dies
65
+ 'processor', # CPU number last executed on
66
+ 'rt_priority', # Real time scheduling priority
67
+ 'policy', # Scheduling policy
68
+ 'name', # Process name
69
+ 'uid', # Real user ID
70
+ 'euid', # Effective user ID
71
+ 'gid', # Real group ID
72
+ 'egid', # Effective group ID
73
+ 'pctcpu', # Percent of CPU usage (custom field)
74
+ 'pctmem' # Percent of Memory usage (custom field)
75
+ ]
76
+
77
+ public
78
+
79
+ ProcTableStruct = Struct.new('ProcTableStruct', *@fields)
80
+
81
+ # In block form, yields a ProcTableStruct for each process entry that you
82
+ # have rights to. This method returns an array of ProcTableStruct's in
83
+ # non-block form.
84
+ #
85
+ # If a +pid+ is provided, then only a single ProcTableStruct is yielded or
86
+ # returned, or nil if no process information is found for that +pid+.
87
+ #
88
+ # Example:
89
+ #
90
+ # # Iterate over all processes
91
+ # ProcTable.ps do |proc_info|
92
+ # p proc_info
93
+ # end
94
+ #
95
+ # # Print process table information for only pid 1001
96
+ # p ProcTable.ps(1001)
97
+ #
98
+ #--
99
+ # It's possible that a process could terminate while gathering
100
+ # information for that process. When that happens, this library
101
+ # will simply skip to the next record. In short, this library will
102
+ # either return all information for a process, or none at all.
103
+ #
104
+ def self.ps(pid=nil)
105
+ array = block_given? ? nil : []
106
+ struct = nil
107
+
108
+ raise TypeError unless pid.is_a?(Fixnum) if pid
109
+
110
+ Dir.foreach("/proc"){ |file|
111
+ next if file =~ /\D/ # Skip non-numeric directories
112
+ next unless file.to_i == pid if pid
113
+
114
+ struct = ProcTableStruct.new
115
+
116
+ # Get /proc/<pid>/cmdline information. Strip out embedded nulls.
117
+ begin
118
+ data = IO.read("/proc/#{file}/cmdline").tr("\000", ' ').strip
119
+ struct.cmdline = data
120
+ rescue
121
+ next # Process terminated, on to the next process
122
+ end
123
+
124
+ # Get /proc/<pid>/cwd information
125
+ struct.cwd = File.readlink("/proc/#{file}/cwd") rescue nil
126
+
127
+ # Get /proc/<pid>/environ information. Environment information
128
+ # is represented as a Hash, with the environment variable as the
129
+ # key and its value as the hash value.
130
+ struct.environ = {}
131
+
132
+ begin
133
+ IO.read("/proc/#{file}/environ").split("\0").each{ |str|
134
+ key, value = str.split('=')
135
+ struct.environ[key] = value
136
+ }
137
+ rescue Errno::EACCES
138
+ # Ignore and move on.
139
+ end
140
+
141
+ # Get /proc/<pid>/exe information
142
+ struct.exe = File.readlink("/proc/#{file}/exe") rescue nil
143
+
144
+ # Get /proc/<pid>/fd information. File descriptor information
145
+ # is represented as a Hash, with the fd as the key, and its
146
+ # symlink as the value.
147
+ struct.fd = {}
148
+
149
+ begin
150
+ Dir["/proc/#{file}/fd/*"].each do |fd|
151
+ struct.fd[File.basename(fd)] = File.readlink(fd) rescue nil
152
+ end
153
+ rescue
154
+ # Ignore and move on
155
+ end
156
+
157
+ # Get /proc/<pid>/root information
158
+ struct.root = File.readlink("/proc/#{file}/root") rescue nil
159
+
160
+ # Get /proc/<pid>/stat information
161
+ stat = IO.read("/proc/#{file}/stat") rescue next
162
+
163
+ # Deal with spaces in comm name. Courtesy of Ara Howard.
164
+ re = %r/\([^\)]+\)/
165
+ comm = stat[re]
166
+ comm.tr!(' ', '-')
167
+ stat[re] = comm
168
+
169
+ stat = stat.split
170
+
171
+ struct.pid = stat[0].to_i
172
+ struct.comm = stat[1].tr('()','') # Remove parens
173
+ struct.state = stat[2]
174
+ struct.ppid = stat[3].to_i
175
+ struct.pgrp = stat[4].to_i
176
+ struct.session = stat[5].to_i
177
+ struct.tty_nr = stat[6].to_i
178
+ struct.tpgid = stat[7].to_i
179
+ struct.flags = stat[8].to_i
180
+ struct.minflt = stat[9].to_i
181
+ struct.cminflt = stat[10].to_i
182
+ struct.majflt = stat[11].to_i
183
+ struct.cmajflt = stat[12].to_i
184
+ struct.utime = stat[13].to_i
185
+ struct.stime = stat[14].to_i
186
+ struct.cutime = stat[15].to_i
187
+ struct.cstime = stat[16].to_i
188
+ struct.priority = stat[17].to_i
189
+ struct.nice = stat[18].to_i
190
+ # Skip 19
191
+ struct.itrealvalue = stat[20].to_i
192
+ struct.starttime = stat[21].to_i
193
+ struct.vsize = stat[22].to_i
194
+ struct.rss = stat[23].to_i
195
+ struct.rlim = stat[24].to_i
196
+ struct.startcode = stat[25].to_i
197
+ struct.endcode = stat[26].to_i
198
+ struct.startstack = stat[27].to_i
199
+ struct.kstkesp = stat[28].to_i
200
+ struct.kstkeip = stat[29].to_i
201
+ struct.signal = stat[30].to_i
202
+ struct.blocked = stat[31].to_i
203
+ struct.sigignore = stat[32].to_i
204
+ struct.sigcatch = stat[33].to_i
205
+ struct.wchan = stat[34].to_i
206
+ struct.nswap = stat[35].to_i
207
+ struct.cnswap = stat[36].to_i
208
+ struct.exit_signal = stat[37].to_i
209
+ struct.processor = stat[38].to_i
210
+ struct.rt_priority = stat[39].to_i
211
+ struct.policy = stat[40].to_i
212
+
213
+ # Get /proc/<pid>/status information (name, uid, euid, gid, egid)
214
+ IO.foreach("/proc/#{file}/status") do |line|
215
+ case line
216
+ when /Name:\s*?(\w+)/
217
+ struct.name = $1
218
+ when /Uid:\s*?(\d+)\s*?(\d+)/
219
+ struct.uid = $1.to_i
220
+ struct.euid = $2.to_i
221
+ when /Gid:\s*?(\d+)\s*?(\d+)/
222
+ struct.gid = $1.to_i
223
+ struct.egid = $2.to_i
224
+ end
225
+ end
226
+
227
+ # If cmdline is empty use comm instead
228
+ struct.cmdline = struct.comm if struct.cmdline.empty?
229
+
230
+ # Manually calculate CPU and memory usage
231
+ struct.pctcpu = get_pctcpu(struct.utime, struct.starttime)
232
+ struct.pctmem = get_pctmem(struct.rss)
233
+
234
+ struct.freeze # This is read-only data
235
+
236
+ if block_given?
237
+ yield struct
238
+ else
239
+ array << struct
240
+ end
241
+ }
242
+
243
+ pid ? struct : array
244
+ end
245
+
246
+ # Returns an array of fields that each ProcTableStruct will contain. This
247
+ # may be useful if you want to know in advance what fields are available
248
+ # without having to perform at least one read of the /proc table.
249
+ #
250
+ # Example:
251
+ #
252
+ # Sys::ProcTable.fields.each{ |field|
253
+ # puts "Field: #{field}"
254
+ # }
255
+ #
256
+ def self.fields
257
+ @fields
258
+ end
259
+
260
+ private
261
+
262
+ # Calculate the percentage of memory usage for the given process.
263
+ #
264
+ def self.get_pctmem(rss)
265
+ return nil unless @mem_total
266
+ page_size = 4096
267
+ rss_total = rss * page_size
268
+ sprintf("%3.2f", (rss_total.to_f / @mem_total) * 100).to_f
269
+ end
270
+
271
+ # Calculate the percentage of CPU usage for the given process.
272
+ #
273
+ def self.get_pctcpu(utime, start_time)
274
+ return nil unless @boot_time
275
+ hertz = 100.0
276
+ utime = (utime * 10000).to_f
277
+ stime = (start_time.to_f / hertz) + @boot_time
278
+ sprintf("%3.2f", (utime / 10000.0) / (Time.now.to_i - stime)).to_f
279
+ end
280
+ end
281
+ end
data/lib/sys/top.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'sys/proctable'
2
+ require 'rbconfig'
3
+
4
+ # The Sys module serves as a namespace only
5
+ module Sys
6
+
7
+ # The Top class serves as a toplevel name for the 'top' method.
8
+ class Top
9
+
10
+ # The version of the sys-top library
11
+ VERSION = '1.0.3'
12
+
13
+ # Returns an array of Struct::ProcTableStruct elements containing up
14
+ # to +num+ elements, sorted by +field+. The default number of elements
15
+ # is 10, while the default field is 'pctcpu'.
16
+ #
17
+ # Exception: the default sort field is 'pid' on Linux and Windows.
18
+ #
19
+ def self.top(num=10, field='pctcpu')
20
+ field = field.to_s if field.is_a?(Symbol)
21
+
22
+ windows = /mswin|win32|windows|dos|cygwin|mingw/i
23
+
24
+ # Sort by pid on Windows by default
25
+ if Config::CONFIG['host_os'].match(windows) && field == 'pctcpu'
26
+ field = 'pid'
27
+ end
28
+
29
+ Sys::ProcTable.ps.sort_by{ |obj| obj.send(field) || '' }[0..num-1]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'rbconfig'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'tddium-sys-proctable'
6
+ spec.version = '0.9.2'
7
+ spec.author = 'Daniel J. Berger'
8
+ spec.license = 'Artistic 2.0'
9
+ spec.email = 'info@tddium.com'
10
+ spec.homepage = 'http://www.rubyforge.org/projects/sysutils'
11
+ spec.platform = Gem::Platform::CURRENT
12
+ spec.summary = 'An interface for providing process table information'
13
+ spec.has_rdoc = true
14
+ spec.test_files = ['test/test_sys_proctable_all.rb']
15
+
16
+ # Additional files for your platform are added by the 'rake gem' task.
17
+ spec.files = [
18
+ 'benchmarks/bench_ps.rb',
19
+ 'examples/example_ps.rb',
20
+ 'lib/sys/top.rb',
21
+ 'CHANGES',
22
+ 'MANIFEST',
23
+ 'Rakefile',
24
+ 'README',
25
+ 'sys-proctable.gemspec'
26
+ ]
27
+
28
+ spec.rubyforge_project = 'sysutils'
29
+ spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST', 'doc/top.txt']
30
+
31
+ spec.add_development_dependency('test-unit', '>= 2.1.2')
32
+
33
+ spec.description = <<-EOF
34
+ Testing a separate publish to see if I can get the mac install to work with bundler.
35
+
36
+ The sys-proctable library provides an interface for gathering information
37
+ about processes on your system, i.e. the process table. Most major
38
+ platforms are supported and, while different platforms may return
39
+ different information, the external interface is identical across
40
+ platforms.
41
+ EOF
42
+ end