class Ddtop::Ddtop
Constants
- PREFIX
- TOP_CMD
Public Class Methods
new()
click to toggle source
# File lib/ddtop/ddtop.rb, line 5 def initialize api_key = ENV['DD_API_KEY'] host = %x[hostname -f 2> /dev/null].strip host = Socket.gethostname if host.empty? @dog = Dogapi::Client.new(api_key, nil, host) end
Public Instance Methods
run()
click to toggle source
# File lib/ddtop/ddtop.rb, line 12 def run clear_screen emits = get_emits(ARGV) summary, fields = nil values = [] head_hook = proc do if summary and not values.empty? emit_points(summary, fields, values, emits) values.clear end end top_each_lien(head_hook) do |top, line| if head?(line) summary, fields = parse_header(top, line) elsif not line.empty? values << line.split(/\s+/, fields.length) end end end
Private Instance Methods
aggregate_fields(names, values, emits)
click to toggle source
# File lib/ddtop/ddtop.rb, line 145 def aggregate_fields(names, values, emits) aggregated = {} values.map {|v| h = Hash[*names.zip(v).flatten] %w(PID USER PR NI S).each {|k| h.delete(k) } h['TIME+'] = parse_time_plus(h['TIME+']) h }.select {|h| emits.empty? || emits.include?(h['COMMAND']) }.sort_by {|h| h['COMMAND'] }.chunk {|h| h['COMMAND'] }.each {|cmd, hs| total = {} hs.each do |h| h.delete('COMMAND') h.each do |k, v| total[k] ||= 0.0 total[k] += v.to_f end end aggregated['process.' + cmd] = total } return aggregated end
clear_screen()
click to toggle source
# File lib/ddtop/ddtop.rb, line 188 def clear_screen print "\e[2J" end
emit_points(summary, names, values, emits)
click to toggle source
# File lib/ddtop/ddtop.rb, line 124 def emit_points(summary, names, values, emits) time = summary.delete(:time) fields = aggregate_fields(names, values, emits) emit_points0(time, summary) emit_points0(time, fields) end
emit_points0(time, metrics)
click to toggle source
# File lib/ddtop/ddtop.rb, line 131 def emit_points0(time, metrics) metrics.each do |category, items| items.each do |name, value| metric_name = [PREFIX, category, name].join('.') Thread.start do @dog.emit_point(metric_name, expand_value(value), :timstamp => time) end end end rescue Timeout::Error # nothing to do end
expand_value(value)
click to toggle source
# File lib/ddtop/ddtop.rb, line 196 def expand_value(value) n = 0 case value when /m\Z/ then n = 1 end value.to_f * (1024 ** n) end
get_emits(args)
click to toggle source
# File lib/ddtop/ddtop.rb, line 38 def get_emits(args) i = args.index('--emits') emits = [] if i and args[i + 1] and args[i + 1] !~ /\A-/ emits = args[i + 1].split(/,/).map {|i| i.strip }.select {|i| not i.empty? } args.delete_at(i + 1) args.delete_at(i) end return emits end
get_winsize()
click to toggle source
# File lib/ddtop/ddtop.rb, line 182 def get_winsize `stty -a`.split("\n").first.split(';').values_at(1, 2).map do |nv| nv.strip.split(/\s+/, 2)[1].to_i end end
gets_with_print(top, esq = nil) { || ... }
click to toggle source
# File lib/ddtop/ddtop.rb, line 61 def gets_with_print(top, esq = nil) line = top.gets if head?(line) @win_rows, @win_cols = get_winsize @curr_row = 0 yield if block_given? reset_cursor end @curr_row += 1 if @curr_row <= @win_rows pline = line.chomp delta = @win_cols - pline.length pline += ' ' * (@win_cols - pline.length) if delta > 0 pline = pline[0, @win_cols] pline = esq + pline + "\e[0m" if esq print pline puts if @curr_row != @win_rows end return line.strip end
head?(line)
click to toggle source
# File lib/ddtop/ddtop.rb, line 86 def head?(line) line =~ /\Atop\b/ end
line_to_items(line) { |split(/[\s,:]+/).slice(1..-1)| ... }
click to toggle source
# File lib/ddtop/ddtop.rb, line 119 def line_to_items(line) items = yield(line.split(/[\s,:]+/).slice(1..-1)) Hash[*items.flatten] end
parse_header(top, line)
click to toggle source
# File lib/ddtop/ddtop.rb, line 90 def parse_header(top, line) summary_lines = [line] + (1..4).map { gets_with_print(top) } gets_with_print(top) fields_line = gets_with_print(top, "\e[7m") summary = parse_summary(summary_lines) fields = fields_line.split(/\s+/) [summary, fields] end
parse_summary(lines)
click to toggle source
# File lib/ddtop/ddtop.rb, line 101 def parse_summary(lines) summary = {} first_line = lines[0].split(/[\s,]+/) summary[:time] = parse_time(first_line[2]) load_avg = first_line.values_at(-3, -2, -1) summary[:load_avg] = Hash[*['1m', '5m', '15m'].zip(load_avg).flatten] summary[:tasks] = line_to_items(lines[1]) {|i| i.each_slice(2).map {|i, j| [j, i] } } summary[:cpu] = line_to_items(lines[2]) {|i| i.map {|j| j.split('%').values_at(1, 0) } } summary[:mem] = line_to_items(lines[3]) {|i| i.each_slice(2).map {|i, j| [j, i] } } summary[:swap] = line_to_items(lines[4]) {|i| i.each_slice(2).map {|i, j| [j, i] } } return summary end
parse_time(time)
click to toggle source
# File lib/ddtop/ddtop.rb, line 114 def parse_time(time) now = Time.now Time.mktime(now.year, now.mon, now.day, *time.split(':').map {|i| i.to_i }) end
parse_time_plus(time)
click to toggle source
# File lib/ddtop/ddtop.rb, line 177 def parse_time_plus(time) t = time.split(/[.:]/).map {|i| i.to_f } t[0] * 60 + t[1] + t[2] / 100 end
reset_cursor()
click to toggle source
# File lib/ddtop/ddtop.rb, line 192 def reset_cursor print "\e[0;0H" end
top_each_lien(head_hook) { |top, line| ... }
click to toggle source
# File lib/ddtop/ddtop.rb, line 51 def top_each_lien(head_hook) cmd = [TOP_CMD, ARGV].flatten.join(' ') IO.popen(cmd) do |top| while line = gets_with_print(top, &head_hook) yield(top, line) end end end