class Fluent::ZabbixOutput

Constants

ZBXD

Public Class Methods

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

Public Instance Methods

configure(conf) click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_zabbix.rb, line 30
def configure(conf)
  super

  if @zabbix_server.nil?
    raise Fluent::ConfigError, "missing zabbix_server"
  end

  if @name_keys.nil? and @name_key_pattern.nil?
    raise Fluent::ConfigError, "missing both of name_keys and name_key_pattern"
  end
  if not @name_keys.nil? and not @name_key_pattern.nil?
    raise Fluent::ConfigError, "cannot specify both of name_keys and name_key_pattern"
  end
  if @name_keys
    @name_keys = @name_keys.split(/ *, */)
  end
  if @name_key_pattern
    @name_key_pattern = Regexp.new(@name_key_pattern)
  end
end
emit(tag, es, chain) click to toggle source
# File lib/fluent/plugin/out_zabbix.rb, line 78
def emit(tag, es, chain)
  if @name_keys
    es.each {|time,record|
      host = gen_host(record)
      bulk = []
      @name_keys.each {|key|
        if record[key]
          bulk.push({ :key => format_key(tag, key, record),
                      :value => format_value(record[key]),
                      :host => host,
                      :time => time.to_i,
                    })
        end
      }
      send(time, bulk) if bulk.size > 0
    }
  else # for name_key_pattern
    es.each {|time,record|
      host = gen_host(record)
      bulk = []
      record.keys.each {|key|
        if @name_key_pattern.match(key) && record[key]
          bulk.push({ :key => format_key(tag, key, record),
                      :value => format_value(record[key]),
                      :host => host,
                      :time => time.to_i,
                    })
        end
      }
      send(time, bulk) if bulk.size > 0
    }
  end
  chain.next
end
format_key(tag, key, record) click to toggle source
# File lib/fluent/plugin/out_zabbix.rb, line 127
def format_key(tag, key, record)
  if @prefix_key
    if record[@prefix_key]
      key = "#{record[@prefix_key]}.#{key}"
    end
  end
  if @add_key_prefix
    if @add_key_prefix == '${tag}'
      "#{tag}.#{key}"
    else
      "#{@add_key_prefix}.#{key}"
    end
  else
    key
  end
end
format_value(value) click to toggle source
# File lib/fluent/plugin/out_zabbix.rb, line 144
def format_value(value)
  if value.kind_of? Float
      # https://www.zabbix.com/documentation/2.4/manual/config/items/item
      # > Allowed range (for MySQL): -999999999999.9999 to 999999999999.9999 (double(16,4)).
      # > Starting with Zabbix 2.2, receiving values in scientific notation is also supported. E.g. 1e+70, 1e-70.
    value.round(4).to_s
  else
    value.to_s
  end
end
gen_host(record) click to toggle source
# File lib/fluent/plugin/out_zabbix.rb, line 113
def gen_host(record)
  if @host_key
    if record[@host_key]
      host = record[@host_key]
    else
      log.warn "plugin-zabbix: host_key is configured '#{@host_key}', but this record has no such key. use host '#{@host}'"
      host = @host
    end
  else
    host = @host
  end
  return host
end
send(time, bulk) click to toggle source
# File lib/fluent/plugin/out_zabbix.rb, line 59
def send(time, bulk)
  bulk.each do |d|
  end
  begin
    sock = TCPSocket.open(@zabbix_server, @port)
    log.debug("zabbix: #{sock} #{bulk}, ts: #{time}")
    status = send_to_zabbix(sock, time, bulk)
  rescue => e
    log.warn "plugin-zabbix: raises exception: #{e}"
    status = false
  ensure
    sock.close if sock
  end

  unless status
    log.warn "plugin-zabbix: failed to send to zabbix_server: #{@zabbix_server}:#{@port} #{bulk}"
  end
end
send_to_zabbix(sock, time, bulk) click to toggle source
# File lib/fluent/plugin/out_zabbix.rb, line 155
def send_to_zabbix(sock, time, bulk)
  req = Yajl::Encoder.encode({
    :request => 'agent data',
    :clock => time.to_i,
    :data => bulk,
  })
  sock.write(ZBXD + [ req.size ].pack('q') + req)
  sock.flush

  header = sock.read(5)
  if header != ZBXD
    return false
  end
  len = sock.read(8).unpack('q')[0]
  res = Yajl::Parser.parse(sock.read(len))
  return res['response'] == "success"
end
shutdown() click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_zabbix.rb, line 55
def shutdown
  super
end
start() click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_zabbix.rb, line 51
def start
  super
end