class Ddstat::Ddstat

Constants

DSTAT_PATH
PREFIX

Public Class Methods

new() click to toggle source
# File lib/ddstat/ddstat.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/ddstat/ddstat.rb, line 12
def run
  rows, cols = curr_rows_cols

  cmd = [
    "stty rows #{rows}",
    "stty cols #{cols}",
    "#{DSTAT_PATH} #{ARGV.join(' ')}"
  ].join(';')

  PTY.spawn(cmd) do |r, w, pid|
    while line = gets_with_print(r)
      line = line.gsub(/\e\[?7l?-/, '-')
      line = line.split("\e8").last
      parse_line(r, line)
    end
  end
end

Private Instance Methods

curr_rows_cols() click to toggle source
# File lib/ddstat/ddstat.rb, line 115
def curr_rows_cols
  `stty -a`.split("\n").first.split(';').values_at(1, 2).map do |nv|
    nv.strip.split(/\s+/, 2)[1]
  end
end
emit_points(field_values) click to toggle source
# File lib/ddstat/ddstat.rb, line 91
def emit_points(field_values)
  date_time = if field_values['system'] and field_values['system']['date_time']
                Time.parse(field_values['system'].delete('date_time'))
              else
                Time.now
              end

  field_values.each do |category, fields|
    fields.each do |name, value|
      metric_name = [PREFIX, category, name].join('.')

      Thread.start do
        @dog.emit_point(metric_name, expand_value(value), :timstamp => date_time)
      end
    end
  end
rescue Timeout::Error
  # nothing to do
end
expand_value(value) click to toggle source
# File lib/ddstat/ddstat.rb, line 121
def expand_value(value)
  n = 0

  case value
  when /k\Z/ then n = 1
  when /M\Z/ then n = 2
  when /G\Z/ then n = 3
  end

  value.to_f * (1024 ** n)
end
gets_with_print(dstat) click to toggle source
# File lib/ddstat/ddstat.rb, line 32
def gets_with_print(dstat)
  line = dstat.gets
  print line
  return remove_color(line)
end
parse_category_header(category_header) click to toggle source
# File lib/ddstat/ddstat.rb, line 52
def parse_category_header(category_header)
  categories = {}
  items = category_header.split('- -')

  items.each_with_index do |category, i|
    n = (i.zero? or i == items.length - 1) ? 2 : 3
    len = category.length + n
    category = category.strip.sub(/\A-+\s*/, '').sub(/\s*-+\Z/, '')
    category.gsub!(%r|[-/\s]+|, '_')
    categories[category] = len
  end

  return categories
end
parse_header(categories, header) click to toggle source
# File lib/ddstat/ddstat.rb, line 67
def parse_header(categories, header)
  fields = []

  categories.each do |category, len|
    names = header.slice!(0, len).split(/[\|\s]+/).select {|i| not i.empty? }.map {|i| i.gsub(%r|[-/\s]+|, '_') }
    fields << [category, names]
  end

  return fields
end
parse_line(dstat, line) click to toggle source
# File lib/ddstat/ddstat.rb, line 38
def parse_line(dstat, line)
  if line =~ /\A-/
    header = gets_with_print(dstat)

    unless @fields
      categories = parse_category_header(line)
      @fields = parse_header(categories, header)
    end
  else
    field_values = parse_values(line)
    emit_points(field_values)
  end
end
parse_values(line) click to toggle source
# File lib/ddstat/ddstat.rb, line 78
def parse_values(line)
  categorized_values = line.split(/\|/)
  field_values = {}

  @fields.each_with_index do |category_names, i|
    category, names = category_names
    values = categorized_values[i].strip.split(/\s+/, names.length)
    field_values[category] = Hash[*names.zip(values).flatten]
  end

  return field_values
end
remove_color(str) click to toggle source
# File lib/ddstat/ddstat.rb, line 111
def remove_color(str)
  str.gsub(/\e\[\d{1,2}(?:;\d{1,2})*[mK]/, '')
end