lib/hotwired/core.rb in hotwired-0.0.3 vs lib/hotwired/core.rb in hotwired-0.0.4
- old
+ new
@@ -19,11 +19,11 @@
Core.new opts
end
# 轮询 host 数据
def poll(opts = {})
- host = opts.delete :host
+ host = opts.delete(:host)
raise HotwiredError, "'host' not given" unless host
hotwire = new(opts)
result = hotwire.poll Resolv.getaddress(host)
# 数据转储
hotwire.make_record result if result
@@ -39,92 +39,124 @@
end
# 类对象外部调用函数入口
def run
# 解析变量
- cidr = @opts.delete :cidr
+ cidr = @opts.delete(:cidr)
# @output = @opts.delete :output
# 设置缺省 logger 输出
# unless @output
# @output = Logger.new $stdout
# @output.formatter = proc { |_, _, _, msg| "#{msg}\n" }
# end
# 初始化变量及遍历 CIDR
- poll, ignores = resolve_networks cidr
+ poll, ignores = resolve_networks(cidr)
# 实例化线程和数据库联结
@mutex = Mutex.new
@db = DB.new
threads = []
# 线程遇到异常及时终止
- Thread.abort_on_exception = true
+ Thread.abort_on_exception = false
# 遍历待轮询的 IPAddr
poll.each do |net|
net.to_range.each do |ip|
# 检查当前地址是否需要被忽略
next if ignores.any? { |ignore| ignore.include? ip }
# 清除空闲线程
while threads.size >= CFG.threads
threads.delete_if { |thread| not thread.alive? }
- sleep 0.01
+ sleep 0.02
end
# 线程不够则主动添加线程
threads << Thread.new do
- result = poll ip
+ result = poll(ip)
@mutex.synchronize { process result } if result
end
end
end
# 激活线程,开始干活
threads.each { |thread| thread.join }
end
+ # 解析 cidr
+ def resolve_networks(cidr)
+ # 如未接收外部变量则使用缺省值
+ cidr = cidr ? [cidr].flatten : CFG.poll
+
+ # 从 CIDR 中剔除排除清单
+ # 支持数组以及文本形式,数据返回包含2个数组对象的数组
+ [cidr, CFG.ignore].map do |nets|
+ if nets.respond_to? :each
+ nets.map { |net| IPAddr.new net }
+ else
+ out = []
+ File.read(nets).each_line do |net|
+ # 模糊的 IP 地址正则表达式
+ net = net.match(/^([\d.\/]+)$/)
+ out << IPAddr.new(net[1]) if net
+ end
+ out
+ end
+ end
+ end
+
# 轮询单个 IP 设备信息
def poll(ip)
result = nil
# 实例化 SNMP 对象,批量获取相关监控数据
snmp = SNMP.new(ip.to_s, @community)
+ # 如有异常则返回 false
oids = snmp.dbget
if oids
# 早期异常拦截
Log.debug "SNMP::NoSuchObject #{ip}" if oids[:sysDescr] == ::SNMP::NoSuchObject
return nil if oids[:sysDescr] == ::SNMP::NoSuchObject
# 初始化变量,并尝试刷新接口描述信息
result = { oids: oids, ip: ip, int: "n/a" }
# 联机查询数据
index = snmp.ip2index(ip.to_s)
- int = snmp.ifdescr(index)
# 逻辑处理
- if index
- if int
- result[:int] = int.downcase
- else
+ if index.nil?
+ Log.debug "no ifIndex for #{ip}"
+ else
+ int = snmp.ifdescr(index)
+ if int.nil?
Log.debug "no ifDescr for #{index} at #{ip}"
+ else
+ result[:int] = int.downcase
end
- else
- Log.debug "no ifIndex for #{ip}"
end
end
# 关闭 SNMP 会话并返回结果
snmp.close
result
end
+ # 解析 IP 关联的主机名
+ def ip2name(ip)
+ Resolv.getname ip rescue ip
+ end
+
# 新增表记录
def make_record(opt)
+ # 判断是否存在 sysObjectID,不存在则设置为 nil
+ sys_object_id = opt[:oids][:sysObjectID].empty? ? nil : opt[:oids][:sysObjectID].join(".")
+
+ # 返回数据结构
{
ip: opt[:ip].to_s,
ptr: ip2name(opt[:ip].to_s),
model: Model.map(opt[:oids][:sysDescr], opt[:oids][:sysObjectID]),
oid_ifDescr: opt[:int],
oid_sysName: opt[:oids][:sysName],
oid_sysLocation: opt[:oids][:sysLocation],
oid_sysDescr: opt[:oids][:sysDescr],
- oid_sysObjectID: opt[:oids][:sysObjectID].join("."),
+ oid_sysObjectID: sys_object_id
}
end
private
def process(opt)
@@ -203,35 +235,8 @@
# 序列化 opt 参数
def normalize_opt(opt)
opt[:oids][:sysName].sub!(/-re[1-9]\./, "-re0.")
opt
- end
-
- # 解析 IP 关联的主机名
- def ip2name(ip)
- Resolv.getname ip rescue ip
- end
-
- # 解析 cidr
- def resolve_networks(cidr)
- # 如未接收外部变量则使用缺省值
- cidr = cidr ? [cidr].flatten : CFG.poll
-
- # 从 CIDR 中剔除排除清单
- # 支持数组以及文本形式,数据返回包含2个数组对象的数组
- [cidr, CFG.ignore].map do |nets|
- if nets.respond_to? :each
- nets.map { |net| IPAddr.new net }
- else
- out = []
- File.read(nets).each_line do |net|
- # 模糊的 IP 地址正则表达式
- net = net.match(/^([\d.\/]+)$/)
- out << IPAddr.new(net[1]) if net
- end
- out
- end
- end
end
end
end