class CadvisorInput

Public Class Methods

new() click to toggle source
Calls superclass method
# File lib/fluent/plugin/in_cadvisor.rb, line 31
def initialize
  super
  require 'socket'

  Docker.url = @docker_url
  @hostname = Socket.gethostname
  @dict     = {}
end

Public Instance Methods

configure(conf) click to toggle source
Calls superclass method
# File lib/fluent/plugin/in_cadvisor.rb, line 40
def configure(conf)
  super
end
emit_container_info(obj) click to toggle source
# File lib/fluent/plugin/in_cadvisor.rb, line 81
def emit_container_info(obj)
  container_json = obj.json
  config = container_json['Config']

  id   = container_json['Id']
  name = config['Image']
  env  = config['Hostname'].split('--')[2] || '' # app--version--env

  response = RestClient.get(@cadvisorEP + "/containers/docker/" + id)
  res = JSON.parse(response.body)

  # Set max memory
  memory_limit = @machine['memory_capacity'] < res['spec']['memory']['limit'] ? @machine['memory_capacity'] : res['spec']['memory']['limit']

  latest_timestamp = @dict[id] ||= 0

  # Remove already sent elements
  res['stats'].reject! do | stats |
    Time.parse(stats['timestamp']).to_i <= latest_timestamp
  end

  res['stats'].each_with_index do | stats, index |
    timestamp = Time.parse(stats['timestamp']).to_i
    # Break on last element
    # We need 2 elements to create the percentage, in this case the prev will be
    # out of the array
    if index == (res['stats'].count - 1)
      @dict[id] = timestamp
      break
    end

    num_cores = stats['cpu']['usage']['per_cpu_usage'].count

    # CPU percentage variables
    prev           = res['stats'][index + 1];
    raw_usage      = stats['cpu']['usage']['total'] - prev['cpu']['usage']['total']
    interval_in_ns = get_interval(stats['timestamp'], prev['timestamp'])

    record = {
      'id'                 => Digest::SHA1.hexdigest("#{name}#{id}#{timestamp.to_s}"),
      'container_id'       => id,
      'image'              => name,
      'environment'        => env,
      'memory_current'     => stats['memory']['usage'],
      'memory_limit'       => memory_limit,
      'cpu_usage'          => raw_usage,
      'cpu_usage_pct'      => (((raw_usage / interval_in_ns ) / num_cores ) * 100).round(2),
      'cpu_num_cores'      => num_cores,
      'network_rx_bytes'   => stats['network']['rx_bytes'],
      'network_rx_packets' => stats['network']['rx_packets'],
      'network_rx_errors'  => stats['network']['rx_errors'],
      'network_rx_dropped' => stats['network']['rx_dropped'],
      'network_tx_bytes'   => stats['network']['tx_bytes'],
      'network_tx_packets' => stats['network']['tx_packets'],
      'network_tx_errors'  => stats['network']['tx_errors'],
      'network_tx_dropped' => stats['network']['tx_dropped'],
    }

    Fluent::Engine.emit("#{tag_prefix}stats", timestamp, record)
  end
end
get_interval(current, previous) click to toggle source
# File lib/fluent/plugin/in_cadvisor.rb, line 61
def get_interval (current, previous)
  cur  = Time.parse(current).to_f
  prev = Time.parse(previous).to_f

  # to nano seconds
  (cur - prev) * 1000000000
end
get_metrics() click to toggle source

Metrics collection methods

# File lib/fluent/plugin/in_cadvisor.rb, line 75
def get_metrics
  Docker::Container.all.each do |obj|
    emit_container_info(obj)
  end
end
get_spec() click to toggle source
# File lib/fluent/plugin/in_cadvisor.rb, line 69
def get_spec
  response = RestClient.get(@cadvisorEP + "/machine")
  JSON.parse(response.body)
end
run() click to toggle source
# File lib/fluent/plugin/in_cadvisor.rb, line 54
def run
  @loop.run
rescue
  log.error "unexpected error", :error=>$!.to_s
  log.error_backtrace
end
shutdown() click to toggle source
# File lib/fluent/plugin/in_cadvisor.rb, line 143
def shutdown
  @loop.stop
  @thread.join
end
start() click to toggle source
# File lib/fluent/plugin/in_cadvisor.rb, line 44
def start
  @cadvisorEP ||= "http://#{@host}:#{@port}/api/v#{@api_version}"
  @machine    ||= get_spec

  @loop = Coolio::Loop.new
  tw = TimerWatcher.new(@stats_interval, true, @log, &method(:get_metrics))
  tw.attach(@loop)
  @thread = Thread.new(&method(:run))
end