# frozen_string_literal: true require_relative 'icmp' class Array def avg reduce(:+) / count end end module Netchk class TcpPingVerifier def initialize @hosts = %w[1.1.1.1 8.8.8.8] @count = 20 @interval = 0.2 end def verify stats = @hosts.map do |host| host_stats = ping(host, @count) average = host_stats[:durations].empty? ? "N/A" : (host_stats[:durations].avg * 1000).round(2) errors = host_stats[:failures].to_f / (host_stats[:failures] + host_stats[:durations].count) * 100 puts "Stats for #{host} ping - average: #{average} ms, error rate: #{errors.round(2)}%" [host, host_stats] end.to_h all_durations = stats.values.flat_map { |host_stats| host_stats[:durations] } overall_average = all_durations.empty? ? "N/A" : (all_durations.avg * 1000).round(2) overall_errors = stats.values.flat_map { |host_stats| host_stats[:failures].to_f / host_stats[:count] * 100 }.avg puts "Overall stats for ping - average: #{overall_average} ms, errors: #{overall_errors.round(2)}%" end private def ping(host, count) stats = { durations: [], failures: 0, count: count } ping = ::Netchk::ICMP.new(host, nil, 1) count.times do sleep @interval if ping.ping stats[:durations] << ping.duration else $stderr.puts "pinging #{host} failed: #{ping.exception || "Unknown error"}" stats[:failures] += 1 end end stats end end end