rdeadman 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 06ed0d7c99e169cc7b5190a1e01068949cd33a6ee8b0e3beac3487d185ec2e53
4
+ data.tar.gz: 892ea804556383e5220dc3b9ff39545eb65579e1d76b4ec0b51912a2d1d7b610
5
+ SHA512:
6
+ metadata.gz: fef13795c935006084cf61468477a235710b069a6333208fdf32e47d923dd5ce64dd99e2c5a6dd4905dd24f916a547d7a165a614e9d0362839fe7454a050ca14
7
+ data.tar.gz: fe5f16d0b514d8a6fd1f7a1dab6a87d442cfbf95c50c8cef855e0e42121876e9682103dbc471c88a4c73eee7e598c1c1d925e861e935ff64e3437d8e377a614c
data/bin/rdeadman ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ require "rdeadman/monitor"
3
+
4
+ if ARGV.length < 1
5
+ puts "Usage: rdeadman <config_file> [interval]"
6
+ exit
7
+ end
8
+
9
+ config_file = ARGV[0]
10
+ interval = ARGV[1] ? ARGV[1].to_i : 5
11
+
12
+ Rdeadman::MonitorHosts.run(config_file, interval)
@@ -0,0 +1,137 @@
1
+ # lib/rdeadman/monitor.rb
2
+ require 'net/ping'
3
+ require 'curses'
4
+ require 'socket'
5
+ require_relative 'version'
6
+
7
+ module Rdeadman
8
+ class HostMonitor
9
+ attr_reader :host, :address, :interval, :results, :sent_packets, :lost_packets
10
+
11
+ def initialize(host, interval = 5)
12
+ @host = host
13
+ @address = resolve_address(host)
14
+ @interval = interval
15
+ @results = []
16
+ @sent_packets = 0
17
+ @lost_packets = 0
18
+ end
19
+
20
+ def resolve_address(host)
21
+ IPSocket.getaddress(host)
22
+ rescue SocketError
23
+ "Unknown"
24
+ end
25
+
26
+ def monitor
27
+ pinger = Net::Ping::External.new(@host)
28
+ loop do
29
+ @sent_packets += 1
30
+ if pinger.ping
31
+ rtt = (pinger.duration * 1000).round(2) # msに変換
32
+ @results << rtt
33
+ else
34
+ @lost_packets += 1
35
+ @results << "X"
36
+ end
37
+ yield self if block_given?
38
+ sleep @interval
39
+ end
40
+ end
41
+
42
+ def loss_rate
43
+ (@lost_packets.to_f / @sent_packets * 100).round(2)
44
+ end
45
+
46
+ def avg_rtt
47
+ avg = @results.select { |r| r.is_a?(Numeric) }.sum.to_f / @results.size
48
+ avg.nan? ? 0 : avg.round(2)
49
+ end
50
+
51
+ def result_graph
52
+ @results.map { |r| r.is_a?(Numeric) ? "▁" : "X" }.join
53
+ end
54
+ end
55
+
56
+ class Display
57
+ def initialize
58
+ Curses.init_screen
59
+ Curses.curs_set(0) # Invisible cursor
60
+ Curses.start_color
61
+ Curses.use_default_colors
62
+ Curses.init_pair(1, Curses::COLOR_GREEN, -1)
63
+ Curses.init_pair(2, Curses::COLOR_RED, -1)
64
+ end
65
+
66
+ def close
67
+ Curses.close_screen
68
+ end
69
+
70
+ def draw(host_monitors)
71
+ Curses.clear
72
+ draw_title
73
+ draw_reference
74
+ host_monitors.each_with_index { |host_monitor, index| draw_host_status(host_monitor, index + 4) }
75
+ Curses.refresh
76
+ end
77
+
78
+ def draw_title
79
+ Curses.setpos(0, 0)
80
+ Curses.addstr(" From: #{Socket.gethostname} [ver #{Rdeadman::VERSION}]")
81
+ Curses.setpos(1, 0)
82
+ Curses.addstr(" RTT Scale 10ms. Keys: (r)efresh")
83
+ end
84
+
85
+ def draw_reference
86
+ Curses.setpos(3, 0)
87
+ Curses.addstr(" HOSTNAME ADDRESS LOSS RTT AVG SNT RESULT")
88
+ end
89
+
90
+ def draw_host_status(host_monitor, line)
91
+ Curses.setpos(line, 0)
92
+ status = [
93
+ host_monitor.host.ljust(16),
94
+ host_monitor.address.ljust(17),
95
+ "#{host_monitor.loss_rate}%".rjust(5),
96
+ "#{host_monitor.results.last}".rjust(5),
97
+ "#{host_monitor.avg_rtt}".rjust(5),
98
+ "#{host_monitor.sent_packets}".rjust(5),
99
+ "#{host_monitor.result_graph}"
100
+ ].join(" ")
101
+
102
+ Curses.addstr(status)
103
+ end
104
+ end
105
+
106
+ module MonitorHosts
107
+ def self.run(config_file, interval)
108
+ hosts = load_hosts_from_config(config_file)
109
+ host_monitors = hosts.map { |host| HostMonitor.new(host, interval) }
110
+ display = Display.new
111
+
112
+ begin
113
+ threads = host_monitors.map do |monitor|
114
+ Thread.new { monitor.monitor }
115
+ end
116
+
117
+ loop do
118
+ display.draw(host_monitors)
119
+ sleep interval
120
+ end
121
+ ensure
122
+ display.close
123
+ threads.each(&:kill)
124
+ end
125
+ end
126
+
127
+ def self.load_hosts_from_config(file)
128
+ hosts = []
129
+ File.readlines(file).each do |line|
130
+ line = line.strip
131
+ next if line.empty? || line.start_with?("#")
132
+ hosts << line
133
+ end
134
+ hosts
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,5 @@
1
+ # lib/rdeadman/version.rb
2
+ module Rdeadman
3
+ VERSION = "0.1.0"
4
+ end
5
+
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdeadman
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Takumi Ishihara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-05-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-ping
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: curses
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ description: A tool for monitoring the availability of multiple hosts using ping
42
+ email:
43
+ - takuan@wide.ad.jp
44
+ executables:
45
+ - rdeadman
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - bin/rdeadman
50
+ - lib/rdeadman/monitor.rb
51
+ - lib/rdeadman/version.rb
52
+ homepage: https://github.com/takuan517/rdeadman
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubygems_version: 3.4.6
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: A network monitoring tool
75
+ test_files: []