Skip to content

Instantly share code, notes, and snippets.

@hrs
Created January 16, 2015 22:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hrs/ee403b14956300a8b120 to your computer and use it in GitHub Desktop.
Save hrs/ee403b14956300a8b120 to your computer and use it in GitHub Desktop.
Generate a graph of the process tree
#!/usr/bin/env ruby
class UnixProcess
attr_reader :uid, :pid, :ppid, :cmd
def initialize(uid:, pid:, ppid:, cmd:)
@uid = uid
@pid = pid
@ppid = ppid
@cmd = cmd
end
def to_s
"#{pid}: #{cmd}"
end
end
class ProcessTree
def initialize(processes)
@processes_hash = processes.inject({}) do |hash, process|
hash[process.pid] = process
hash
end
end
def processes
@processes_hash.values
end
def parent(process)
@processes_hash[process.ppid]
end
end
class ProcessGraphGenerator
def generate(filetype, filename)
File.open(dot_filename, "w") do |file|
write_dot_graph(file, processes(ps_output))
end
`dot -T#{filetype} #{dot_filename} > #{filename}`
end
private
def ps_output
`ps -e -f`.lines[1..-1]
end
def processes(ps_output)
procs = ps_output.map do |process_line|
fields = process_line.split
UnixProcess.new(
uid: fields[0].to_i,
pid: fields[1].to_i,
ppid: fields[2].to_i,
cmd: fields[7..-1].join(" "),
)
end
ProcessTree.new(procs)
end
def write_dot_graph(file, process_tree)
file.puts "digraph G {"
file.puts " graph [rankdir=LR];"
file.puts " node [shape=rectangle];"
process_tree.processes.each do |process|
if process.pid != 1
file.puts " \"#{process_tree.parent(process)}\" -> \"#{process}\";"
end
end
file.puts "}"
end
def dot_filename
"/tmp/graph.dot"
end
end
ProcessGraphGenerator.new.generate(:pdf, "graph.pdf")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment