Module: Process

Defined in:
lib/sixarm_ruby_ramp/process.rb

Overview

Process extensions to help debug Ruby programs.

Examples

p = Process.ps
puts p
=> the results of the 'ps' command for the current process id

p = Process.ps(1234)
puts p
=> the results of the 'ps' command for process id 1234

p = Process.pss
p['%cpu'] => percentage of cpu use, as a float
p['%mem'] => percentage of memory use, as a float

Constant Summary collapse

PS_TO_I =

Get the ‘ps’ command as a hash of keys and values.

- OPTIMIZE: add dates, times

Examples:

pid = 100
Process.pss(pid)
=> {"cp"=>0.0, "esp"=>"bfd86194", "etime"=>"21:14:51", ...  }

Returns:

%w(c egid egroup uid fgid lwp ni nlwp pgid pid ppid rgid rss ruid sid sgid suid)
PS_TO_F =
%w(cp pcpu pmem)
PS_ALIASES_DEFAULT =

Get the list of process alias keywords as typically defined by the shell.

For example, a shell may consider “%cpu” and “pcpu” to be identical.

Examples:

Process::PS_ALIASES_DEFAULT
=> {"%cpu"=>"pcpu", "sigmask"=>"blocked", "class"=>"cls", ... }

Returns:

{
  '%cpu'=>'pcpu',
  '%mem'=>'pmem',
  'sig_block'=>'blocked',
  'sigmask'=>'blocked',
  'sig_catch'=>'caught',
  'sigcatch'=>'caught',
  'class'=>'cls',
  'policy'=>'pol',
  'cputime'=>'time',
  'gid'=>'egid',
  'group'=>'egroup',
  'uid'=>'euid',
  'uname'=>'euser',
  'user'=>'euser',
  'flag'=>'f',
  'flags'=>'f',
  'fsuid'=>'fuid',
  'sig_ignore'=>'ignored',
  'sigignore'=>'ignored',
  'spid'=>'lwp',
  'tid'=>'lwp',
  'nice'=>'ni',
  'thcount'=>'nlwp',
  'sig'=>'pending',
  'sig_pend'=>'pending',
  'pgrp'=>'pgid',
  'rssize'=>'rss',
  'rsz'=>'rss',
  'state'=>'s',
  'sess'=>'sid',
  'session'=>'sid',
  'svgid'=>'sgid',
  'tt'=>'tname',
  'tty'=>'tname',
  'vsz'=>'vsize'
}
PS_KEYS_DEFAULT =

The list of process keywords.

Omit:

* pstime, putime, wq, wqb, wql, wqr: not available on travis-ci.org
%w'%cpu %mem acflag acflg args blocked comm command cpu cputime etime f flags gid group inblk inblock jobc ktrace ktracep lim login logname lstart majflt minflt msgrcv msgsnd ni nice nivcsw nsignals nsigs nswap nvcsw nwchan oublk oublock p_ru paddr pagein pcpu pending pgid pid pmem ppid pri rgid rgroup rss ruid ruser sess sig sigmask sl start stat state stime svgid svuid tdev time tpgid tsess tsiz tt tty ucomm uid upr user usrpri utime vsize vsz wchan xstat'
PS_COMMAND_DEFAULT =

The process command, i.e. what the sytem will call for the “ps” command.

The goal is to use command that works on all platforms, that gets data without headers and with the widest output.

Linux can use e.g.:

ps hww -o pid,%cpu

Note the “h” is less portable; we prefer “–no-headers”.

Note the “ww” is less portable; we prefer “-w -w”.

OSX doesn’t have “h” or “–no-headers”. Instead, OSX uses a format string to set each column header to blank, e.g. ‘ps -o ’pid=,%cpu=‘`.

A workaroud is to delete the header row by using ‘sed 1d`; we prefer a pure `ps` solution so we don’t depend on ‘sed`.

The solution we use seems to work in practice: we use multiple ‘-o` output fields, and set each output field to use a blank string as a header. This makes the `ps` command skip the header row.

Example that succeeds on all our known systems:

ps -o pid='' -o %cpu='' -o %mem=''
"ps " + ps_keys.map{|k| "-o #{k}=''"}.join(" ")

Class Method Summary collapse

Class Method Details

.ps(pid = Process.pid) ⇒ String

Get the ‘ps’ command as one long text string.

This is typically useful for logging to a text file.

Examples:

pid = 100
Process.ps(pid)
=> "0.0 bfd86194 21:14:51 ..."

Returns:

  • (String)

    lots of data about the process



33
34
35
# File 'lib/sixarm_ruby_ramp/process.rb', line 33

def self.ps(pid=Process.pid)
  `#{self.ps_command} #{pid.to_i}`
end

.ps_aliasesHash<String,String>

Get the list of process alias keywords as typically defined by the shell.

For example, a shell may consider “%cpu” and “pcpu” to be identical.

Examples:

Process.ps_aliases
=> {"%cpu"=>"pcpu", "sigmask"=>"blocked", "class"=>"cls", ... }

Returns:



118
119
120
# File 'lib/sixarm_ruby_ramp/process.rb', line 118

def self.ps_aliases
  @@ps_aliases||=PS_ALIASES_DEFAULT
end

.ps_aliases=(aliases) ⇒ Hash<String,String>

Set the list of process alias keywords.

For example, a shell may consider “%cpu” and “pcpu” to be identical.

Examples:

Process::ps_aliases={ {"%cpu"=>"pcpu", "sigmask"=>"blocked", "class"=>"cls" }
=> {"%cpu"=>"pcpu", "sigmask"=>"blocked", "class"=>"cls"}

Parameters:

Returns:



133
134
135
# File 'lib/sixarm_ruby_ramp/process.rb', line 133

def self.ps_aliases=(aliases)
  @@ps_aliases=aliases
end

.ps_commandString

Get the process command, i.e. what the sytem will call for the “ps” command.

Examples:

Process.ps_command
=> "ps -o blocked='' -o group='' -o pending='' -o size=''"

Returns:

  • (String)

    the process command



207
208
209
# File 'lib/sixarm_ruby_ramp/process.rb', line 207

def self.ps_command
  @@ps_command||=PS_COMMAND_DEFAULT
end

.ps_command=(command) ⇒ String

Set the process command, i.e. what the sytem will call for the “ps” command.

Examples:

Process.ps_command = "ps h ww -o blocked,group,pending,size"

Parameters:

  • the (String)

    process command

Returns:

  • (String)

    the process command



219
220
221
# File 'lib/sixarm_ruby_ramp/process.rb', line 219

def self.ps_command=(command)
  @@ps_command=command
end

.ps_keysArray<String>

Get the list of process keywords.

Examples:

Process.ps_keys
=> ["blocked","group","pending","size"]

Returns:



153
154
155
# File 'lib/sixarm_ruby_ramp/process.rb', line 153

def self.ps_keys
  @@ps_keys||=PS_KEYS_DEFAULT
end

.ps_keys=(keys) ⇒ Array<String>

Set the list of process keywords.

Examples:

Process.ps_keys = ["blocked","group","pending","size"]

Parameters:

Returns:



165
166
167
# File 'lib/sixarm_ruby_ramp/process.rb', line 165

def self.ps_keys=(keys)
  @@ps_keys=keys
end

.pss(pid = Process.pid) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/sixarm_ruby_ramp/process.rb', line 51

def self.pss(pid=Process.pid)
  ps=self.ps(pid)
  h=Hash[*self.ps_keys.zip(ps.split).flatten]
  PS_TO_I.each{|x| h[x]=h[x].to_i}
  PS_TO_F.each{|x| h[x]=h[x].to_f}
  self.ps_aliases.each_pair{|key,val| h[key]=h[val]}
  return h
end