wifi-watch 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +206 -0
- data/Rakefile +8 -0
- data/bin/wifi-watch +396 -0
- data/test/expected/dns-down.out +11 -0
- data/test/expected/dns-slow.out +9 -0
- data/test/expected/fail-mode.out +6 -0
- data/test/expected/wifi-login.out +7 -0
- data/test/ping_logs/dns-down.log +129 -0
- data/test/ping_logs/dns-slow.log +47 -0
- data/test/ping_logs/fail-mode.log +30 -0
- data/test/ping_logs/wifi-login.log +24 -0
- data/test/results/dns-down.out +11 -0
- data/test/results/fail-mode.out +6 -0
- data/test/results/wifi-login.out +7 -0
- data/test/run_tests +39 -0
- data/wifi-watch.gemspec +17 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 697446ea552c7a3457679d63683eca662ffb8f3a
|
4
|
+
data.tar.gz: cbb35fe686254583710005731b65469fb9118eaf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba64b8fa9cb33a576390acaaf3807c12b3a47a6b23a2a7babe9dd1527412a4d80033c7e86b5f6f9fa457701f8ff3597740e6c13d38b11d649343945a607cbba3
|
7
|
+
data.tar.gz: 426294ddb194941801ff65d1ca5969595b9b8311d4d67e866ec1febcd38054ac6e3817cf6e623f6b79aa4663398e64373162eb61605708373e72f421f08698d5
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2018 John Gorman
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
# wifi-watch
|
2
|
+
|
3
|
+
Continuously monitor your network speed and quality!
|
4
|
+
|
5
|
+
```
|
6
|
+
$ wifi-watch
|
7
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
8
|
+
|
9
|
+
Time Ping Run Mode Failed Round Trip
|
10
|
+
----- ---- ---- ---- ------ ----------
|
11
|
+
16:55 300 298 good 0.7% 250.83 ms
|
12
|
+
17:00 300 296 good 1.3% 219.14 ms
|
13
|
+
17:03 136 67 good 1.5% 676.17 ms
|
14
|
+
```
|
15
|
+
|
16
|
+
Run wifi-watch in a terminal so that you can easily check
|
17
|
+
your network quality at this moment and how it has been
|
18
|
+
holding up since you began recording hours or days ago.
|
19
|
+
|
20
|
+
wifi-watch will run ping every second and refresh the
|
21
|
+
current line with the current counts. At the end of
|
22
|
+
an accounting period the current counts are saved
|
23
|
+
as a history line and a new accounting period begins.
|
24
|
+
|
25
|
+
This can be invaluable in monitoring your home internet
|
26
|
+
for systematic service degradation. Service technicians
|
27
|
+
pay attention when you can give them exact ping times
|
28
|
+
and packet loss history!
|
29
|
+
|
30
|
+
It is also a very helpful in public wifi environments
|
31
|
+
to be able to see how the shared bandwidth is holding up
|
32
|
+
on a moment to moment basis.
|
33
|
+
|
34
|
+
### Installation
|
35
|
+
|
36
|
+
wifi-watch is a stand alone ruby script which will run with
|
37
|
+
any ruby version and has no dependencies. Clone the repository
|
38
|
+
and copy wifi-watch into your path.
|
39
|
+
|
40
|
+
```
|
41
|
+
git clone https://github.com/jgorman/wifi-watch.git
|
42
|
+
sudo cp wifi-watch/bin/wifi-watch /usr/local/bin
|
43
|
+
```
|
44
|
+
|
45
|
+
### Usage: wifi-watch [options]
|
46
|
+
|
47
|
+
```
|
48
|
+
-h, --host host Host to ping [ns.google.com].
|
49
|
+
-c, --count seconds Accounting period [600].
|
50
|
+
--debug-to file Write ping output to a file for debugging.
|
51
|
+
--debug-from file Read ping input from a file for testing.
|
52
|
+
-v, --version Version.
|
53
|
+
--help This message.
|
54
|
+
```
|
55
|
+
|
56
|
+
### Current Period Status Counts
|
57
|
+
|
58
|
+
The current output line shows counts for the current period.
|
59
|
+
|
60
|
+
```
|
61
|
+
Time Ping Run Mode Failed Round Trip
|
62
|
+
----- ---- ---- ---- ------ ----------
|
63
|
+
17:03 136 67 good 1.5% 676.17 ms
|
64
|
+
```
|
65
|
+
|
66
|
+
- Current time.
|
67
|
+
- 136 pings attempted so far in the current period.
|
68
|
+
- Run of 67 good pings in a row!
|
69
|
+
- Status of the last ping: "good" or "fail".
|
70
|
+
- Packet loss percentage so far.
|
71
|
+
- Round trip time of the last successful ping.
|
72
|
+
|
73
|
+
### History Lines
|
74
|
+
|
75
|
+
Here is the past half hour of my network quality history.
|
76
|
+
|
77
|
+
In this example things were going great, then my
|
78
|
+
connection slowed down over the last 15 minutes.
|
79
|
+
I am working in a crowded coffee shop right now
|
80
|
+
and perhaps a few of us are watching videos.
|
81
|
+
|
82
|
+
```
|
83
|
+
Time Ping Run Mode Failed Round Trip
|
84
|
+
----- ---- ---- ---- ------ ----------
|
85
|
+
16:30 300 298 good 0.7% 63.84 ms
|
86
|
+
16:35 300 300 good 0.0% 76.28 ms
|
87
|
+
16:40 300 300 good 0.0% 74.45 ms
|
88
|
+
16:45 300 297 good 1.0% 129.55 ms
|
89
|
+
16:50 300 296 good 1.3% 233.94 ms
|
90
|
+
16:55 300 298 good 0.7% 250.83 ms
|
91
|
+
17:00 300 296 good 1.3% 219.14 ms
|
92
|
+
17:03 136 67 good 1.5% 676.17 ms
|
93
|
+
```
|
94
|
+
|
95
|
+
- History lines show the end time for each period.
|
96
|
+
- Count of good pings over the period.
|
97
|
+
- Packet loss percentage.
|
98
|
+
- Average round trip time over the entire period.
|
99
|
+
|
100
|
+
### Failure Reporting
|
101
|
+
|
102
|
+
#### Ping success or failure run length.
|
103
|
+
|
104
|
+
On the current bottom line the run length count resets to 1
|
105
|
+
on every transition between "good" and "fail" modes. This way
|
106
|
+
we can tell at a glance how long we have been in the current
|
107
|
+
state. In a still connected high packet loss environment
|
108
|
+
the runs will be short and switch modes often.
|
109
|
+
|
110
|
+
Here we have lost our internet connection for the last 39 seconds.
|
111
|
+
|
112
|
+
```
|
113
|
+
Time Ping Run Mode Failed Round Trip
|
114
|
+
----- ---- ---- ---- ------ ----------
|
115
|
+
17:59 207 39 fail 19.3% 62.55 ms
|
116
|
+
```
|
117
|
+
|
118
|
+
#### Slow DNS lookup.
|
119
|
+
|
120
|
+
At the beginning of an accounting period ping does a DNS lookup
|
121
|
+
to find your target host ip address. Sometimes this can take
|
122
|
+
quite a while to either succeed or fail. If the wait is more
|
123
|
+
than one second you will see a status message.
|
124
|
+
|
125
|
+
```
|
126
|
+
Time Ping Run Mode Failed Round Trip
|
127
|
+
----- ---- ---- ---- ------ ----------
|
128
|
+
14:38 10 4 good 60.0% 35.69 ms
|
129
|
+
14:38:52 Waiting for dns lookup of ns.google.com ...
|
130
|
+
14:39 10 10 good 0.0% 49.52 ms
|
131
|
+
```
|
132
|
+
|
133
|
+
#### Failing DNS lookup.
|
134
|
+
|
135
|
+
When the network is not connected at the beginning of an
|
136
|
+
accounting period the host DNS lookup will fail to resolve.
|
137
|
+
|
138
|
+
```
|
139
|
+
Time Ping Run Mode Failed Round Trip
|
140
|
+
----- ---- ---- ---- ------ ----------
|
141
|
+
08:40 300 51 good 83.0% 68.65 ms
|
142
|
+
08:41:06 ping: cannot resolve ns.google.com: Unknown host
|
143
|
+
08:42 62 17 fail 27.4% 187.30 ms
|
144
|
+
```
|
145
|
+
|
146
|
+
#### Wifi login timeout.
|
147
|
+
|
148
|
+
Sometimes your coffee shop wifi login will time out and you will
|
149
|
+
need to login again. Wifi-watch will let you know by showing the
|
150
|
+
response message.
|
151
|
+
|
152
|
+
```
|
153
|
+
10:45:43 92 bytes from 10.128.128.128: Communication prohibited by filter
|
154
|
+
```
|
155
|
+
|
156
|
+
## Testing and Debugging
|
157
|
+
|
158
|
+
It is easy to capture the raw ping output to a file for later
|
159
|
+
replay and testing.
|
160
|
+
|
161
|
+
```
|
162
|
+
wifi-watch --count 10 --debug-to test1.log
|
163
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
164
|
+
|
165
|
+
Time Ping Run Mode Failed Round Trip
|
166
|
+
----- ---- ---- ---- ------ ----------
|
167
|
+
10:06 10 10 good 0.0% 127.41 ms
|
168
|
+
10:06 10 3 good 70.0% 34.28 ms
|
169
|
+
10:06:34 ping: cannot resolve ns.google.com: Unknown host
|
170
|
+
10:06 5 1 fail 20.0% 55.16 ms^C
|
171
|
+
```
|
172
|
+
|
173
|
+
The ping output file includes the timestamp for each line
|
174
|
+
so replaying the file later on should result in
|
175
|
+
identical appearing output.
|
176
|
+
|
177
|
+
```
|
178
|
+
wifi-watch --debug-from test1.log
|
179
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
180
|
+
|
181
|
+
Time Ping Run Mode Failed Round Trip
|
182
|
+
----- ---- ---- ---- ------ ----------
|
183
|
+
10:06 10 10 good 0.0% 127.41 ms
|
184
|
+
10:06 10 3 good 70.0% 34.28 ms
|
185
|
+
10:06:34 ping: cannot resolve ns.google.com: Unknown host
|
186
|
+
10:06 5 1 fail 20.0% 55.16 ms
|
187
|
+
```
|
188
|
+
|
189
|
+
Although the --debug-from output should appear to be the same
|
190
|
+
as live ping monitoring there is a difference. Instead of emitting
|
191
|
+
every intermediate count on the current line, only the final
|
192
|
+
line is printed. This helps keep test cases short and readable.
|
193
|
+
|
194
|
+
You can run the current test suite with rake test.
|
195
|
+
|
196
|
+
## Contributing
|
197
|
+
|
198
|
+
Bug reports and pull requests are welcome on GitHub at
|
199
|
+
https://github.com/jgorman/wifi-watch.
|
200
|
+
|
201
|
+
If you discover a shortcoming capture the ping output
|
202
|
+
using --debug-to and open an issue. Thanks!
|
203
|
+
|
204
|
+
## License
|
205
|
+
|
206
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/wifi-watch
ADDED
@@ -0,0 +1,396 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'pty'
|
6
|
+
|
7
|
+
class WifiWatch
|
8
|
+
|
9
|
+
Default_host = "ns.google.com" # Ping target host.
|
10
|
+
Default_count = 600 # Accounting period in seconds.
|
11
|
+
Program = "wifi-watch"
|
12
|
+
Version = "1.0.0"
|
13
|
+
|
14
|
+
def run
|
15
|
+
@shown_header = false # Have we shown the column headers yet?
|
16
|
+
@dns_failing = false # Are DNS lookups currently failing?
|
17
|
+
@display_line = nil # The current display line.
|
18
|
+
@debug_to = nil # Save timestamped ping output here.
|
19
|
+
@debug_from = nil # Read timestamped ping input here.
|
20
|
+
@options = get_options()
|
21
|
+
|
22
|
+
if @options.debug_to
|
23
|
+
begin
|
24
|
+
@debug_to = File.open(@options.debug_to, "w")
|
25
|
+
rescue => e
|
26
|
+
puts
|
27
|
+
puts "debug_to=#{@options.debug_to}: #{e}"
|
28
|
+
puts
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if @options.debug_from
|
34
|
+
|
35
|
+
# Debug mode simulates ping output from a captured --debug-to file.
|
36
|
+
begin
|
37
|
+
@debug_from = File.open(@options.debug_from, "r")
|
38
|
+
rescue => e
|
39
|
+
puts
|
40
|
+
puts "debug_from=#{@options.debug_from}: #{e}"
|
41
|
+
puts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
# Call ping_period() for each ping run section.
|
46
|
+
until @debug_from.eof?
|
47
|
+
ping_period(@debug_from) # Reads up to next "END_OF_PING" line.
|
48
|
+
end
|
49
|
+
if @dns_failing
|
50
|
+
commit_line() # Show that we ended up in dns failure mode.
|
51
|
+
end
|
52
|
+
|
53
|
+
else
|
54
|
+
|
55
|
+
# Run ping multiple times.
|
56
|
+
while true
|
57
|
+
count = beautiful_times()
|
58
|
+
cmd = "ping -c #{count} #{@options.host}"
|
59
|
+
stdin, stdout, pid = PTY.spawn( cmd )
|
60
|
+
ping_period(stdin) # Run one accounting period.
|
61
|
+
Process.waitall() # Soak up any zombie pings.
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
rescue Interrupt
|
67
|
+
commit_line()
|
68
|
+
ensure
|
69
|
+
if @debug_to
|
70
|
+
@debug_to.close
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_options
|
75
|
+
options = OpenStruct.new
|
76
|
+
options.host = Default_host
|
77
|
+
options.count = Default_count
|
78
|
+
|
79
|
+
opt_parser = OptionParser.new do |opt|
|
80
|
+
opt.banner = "Usage: #{Program} [OPTIONS]"
|
81
|
+
opt.separator ""
|
82
|
+
|
83
|
+
opt.on("-h", "--host host", "Host to ping [#{options.host}].") do |host|
|
84
|
+
options.host = host
|
85
|
+
end
|
86
|
+
|
87
|
+
opt.on("-c", "--count seconds", Integer,
|
88
|
+
"Accounting period [#{options.count}].") do |count|
|
89
|
+
options.count = count
|
90
|
+
end
|
91
|
+
|
92
|
+
opt.on("--debug-to file",
|
93
|
+
"Write ping output to a file for debugging.") do |debug_to|
|
94
|
+
options.debug_to = debug_to
|
95
|
+
end
|
96
|
+
|
97
|
+
opt.on("--debug-from file",
|
98
|
+
"Read ping input from a file for testing.") do |debug_from|
|
99
|
+
options.debug_from = debug_from
|
100
|
+
end
|
101
|
+
|
102
|
+
opt.on("-v", "--version", "Version.") do
|
103
|
+
puts Version
|
104
|
+
exit
|
105
|
+
end
|
106
|
+
|
107
|
+
opt.on("--help", "This message.") do
|
108
|
+
puts
|
109
|
+
puts opt_parser
|
110
|
+
puts
|
111
|
+
exit
|
112
|
+
end
|
113
|
+
|
114
|
+
opt.separator ""
|
115
|
+
opt.separator "Documentation at https://github.com/jgorman/wifi-watch"
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
begin
|
120
|
+
opt_parser.parse!
|
121
|
+
rescue => e
|
122
|
+
puts
|
123
|
+
puts e
|
124
|
+
puts
|
125
|
+
puts opt_parser
|
126
|
+
puts
|
127
|
+
exit
|
128
|
+
end
|
129
|
+
|
130
|
+
return options
|
131
|
+
end
|
132
|
+
|
133
|
+
# Run ping for one accounting period.
|
134
|
+
def ping_period(stdin)
|
135
|
+
|
136
|
+
current_mode = nil # Are we currently "good" or "fail"?
|
137
|
+
mode_count = 0 # For how long in a row?
|
138
|
+
total_count = 0 # Pings so far.
|
139
|
+
totally_good = 0 # Successful pings.
|
140
|
+
ping_ms = 0.0 # Latest successful ping time in milliseconds.
|
141
|
+
packets_line = '' # Ping packets received summary line.
|
142
|
+
round_trip_line = '' # Ping round-trip milliseconds summary line.
|
143
|
+
filter_mode = false # Wifi login filter is active.
|
144
|
+
line_time = nil # Latest line timestamp.
|
145
|
+
first_byte = nil # DNS lookup complete read test byte.
|
146
|
+
|
147
|
+
# Long DNS lookups can effectively freeze ping for a while.
|
148
|
+
# To reproduce: turn VPN off and then on, then turn WiFi off.
|
149
|
+
# This logic is impractical to simulate in a meaningful way
|
150
|
+
# so we just pass the messages on for later debugging display.
|
151
|
+
waiting_start = Time.now
|
152
|
+
last_notified = waiting_start
|
153
|
+
until first_byte
|
154
|
+
begin
|
155
|
+
first_byte = stdin.read_nonblock(1)
|
156
|
+
rescue IO::EAGAINWaitReadable
|
157
|
+
now = Time.now
|
158
|
+
if now - last_notified >= 1
|
159
|
+
hhmmss_line(now, "Waiting for dns lookup of #{@options.host} ...")
|
160
|
+
if @debug_to
|
161
|
+
@debug_to.puts "#{now.to_i} DNS_LOOKUP #{@display_line}"
|
162
|
+
@debug_to.flush
|
163
|
+
end
|
164
|
+
last_notified = now
|
165
|
+
end
|
166
|
+
sleep 0.2 # Be nice to the cpu.
|
167
|
+
end
|
168
|
+
end
|
169
|
+
if last_notified > waiting_start
|
170
|
+
commit_line()
|
171
|
+
end
|
172
|
+
|
173
|
+
# Process each line of ping output.
|
174
|
+
stdin.each do |line|
|
175
|
+
|
176
|
+
line.chomp!
|
177
|
+
if first_byte
|
178
|
+
line = first_byte + line
|
179
|
+
first_byte = nil
|
180
|
+
end
|
181
|
+
|
182
|
+
if @debug_from
|
183
|
+
# Read from the debugging source file up to the end of this ping run.
|
184
|
+
if line == "END_OF_PING"
|
185
|
+
break # End this ping accounting period run.
|
186
|
+
end
|
187
|
+
# Simulate the past by loading the effective time for this line.
|
188
|
+
time, line = line.split(" ", 2)
|
189
|
+
line_time = Time.at(time.to_i)
|
190
|
+
else
|
191
|
+
line_time = Time.now
|
192
|
+
end
|
193
|
+
|
194
|
+
if @debug_to
|
195
|
+
# Capture this ping output line with the timestamp for later debugging.
|
196
|
+
@debug_to.puts "#{line_time.to_i} #{line}"
|
197
|
+
@debug_to.flush
|
198
|
+
end
|
199
|
+
|
200
|
+
# DNS failure modes.
|
201
|
+
if line =~ /cannot resolve/
|
202
|
+
# ping: cannot resolve ns.google.com: Unknown host
|
203
|
+
hhmmss_line(line_time, line)
|
204
|
+
sleep 1 unless @debug_from # Speed up testing.
|
205
|
+
@dns_failing = true
|
206
|
+
elsif line =~ /DNS_LOOKUP (.*)/
|
207
|
+
# Waiting for dns lookup of ns.google.com ...
|
208
|
+
display_line($1)
|
209
|
+
@dns_failing = true
|
210
|
+
elsif @dns_failing
|
211
|
+
# If DNS was previously failing, pop to a fresh line.
|
212
|
+
commit_line()
|
213
|
+
@dns_failing = false
|
214
|
+
end
|
215
|
+
|
216
|
+
# This indicates a ping success or failure line. Nil means neither.
|
217
|
+
new_mode = nil
|
218
|
+
|
219
|
+
# Parse the line.
|
220
|
+
if line =~ /PING/
|
221
|
+
#
|
222
|
+
# The first ping output line shows the destination host and ip.
|
223
|
+
#
|
224
|
+
# PING ns.google.com (216.239.32.10): 56 data bytes
|
225
|
+
#
|
226
|
+
unless @shown_header
|
227
|
+
puts line # Show the destination name and ip.
|
228
|
+
puts
|
229
|
+
puts "Time Ping Run Mode Failed Round Trip"
|
230
|
+
puts "----- ---- ---- ---- ------ ----------"
|
231
|
+
@shown_header = true # Only show these once per wifi-watch.
|
232
|
+
end
|
233
|
+
|
234
|
+
elsif line =~ /bytes from/
|
235
|
+
if line =~ /time=(\S+)/
|
236
|
+
#
|
237
|
+
# Success! Record the round trip time.
|
238
|
+
#
|
239
|
+
# 64 bytes from 104.27.146.148: icmp_seq=48 ttl=61 time=24.780 ms
|
240
|
+
#
|
241
|
+
ping_ms = $1.to_f
|
242
|
+
new_mode = 'good'
|
243
|
+
if filter_mode
|
244
|
+
commit_line() # Keep the filter message line.
|
245
|
+
filter_mode = false
|
246
|
+
end
|
247
|
+
else
|
248
|
+
#
|
249
|
+
# Here the wifi login has timed out and is blocking packets.
|
250
|
+
# Multi line ping output shows both the timeout and filter message
|
251
|
+
# lines plus some additional diagnostic lines that we ignore.
|
252
|
+
#
|
253
|
+
# Request timeout for icmp_seq 5
|
254
|
+
# 92 bytes from 10.128.128.128: Communication prohibited by filter
|
255
|
+
# Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
|
256
|
+
# 4 5 00 5400 6dea 0 0000 40 01 21dd 10.57.228.249 104.27.147.148
|
257
|
+
#
|
258
|
+
unless filter_mode
|
259
|
+
commit_line() # Keep the last unfiltered status line.
|
260
|
+
filter_mode = true
|
261
|
+
end
|
262
|
+
hhmmss_line(line_time, line)
|
263
|
+
end
|
264
|
+
|
265
|
+
elsif line =~ /timeout/
|
266
|
+
# Request timeout for icmp_seq 3
|
267
|
+
new_mode = 'fail'
|
268
|
+
|
269
|
+
elsif line =~ /transmitted/
|
270
|
+
# 5 packets transmitted, 5 packets received, 0.0% packet loss
|
271
|
+
packets_line = line
|
272
|
+
|
273
|
+
elsif line =~ /round-trip/
|
274
|
+
# round-trip min/avg/max/stddev = 0.063/0.082/0.122/0.022 ms
|
275
|
+
round_trip_line = line
|
276
|
+
end
|
277
|
+
|
278
|
+
if new_mode
|
279
|
+
# Update the counts with success or failure.
|
280
|
+
if new_mode != current_mode
|
281
|
+
current_mode = new_mode
|
282
|
+
mode_count = 0
|
283
|
+
end
|
284
|
+
mode_count += 1
|
285
|
+
totally_good += 1 if current_mode == 'good'
|
286
|
+
total_count += 1
|
287
|
+
unless filter_mode
|
288
|
+
show_stats(line_time, total_count, totally_good,
|
289
|
+
current_mode, mode_count, ping_ms)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
if @debug_to
|
296
|
+
# Insert a ping run separator line into the debugging file.
|
297
|
+
@debug_to.puts "END_OF_PING"
|
298
|
+
@debug_to.flush
|
299
|
+
end
|
300
|
+
|
301
|
+
# Final summary line.
|
302
|
+
if packets_line =~ /(\d+) packets transmitted, (\d+) packets received/
|
303
|
+
total_count = $1.to_i
|
304
|
+
totally_good = $2.to_i
|
305
|
+
if round_trip_line =~ / (\S+) ms/
|
306
|
+
avg_ms = $1.split('/')[1].to_f # Extract the average time.
|
307
|
+
end
|
308
|
+
show_stats(line_time, total_count, totally_good,
|
309
|
+
'good', totally_good, avg_ms)
|
310
|
+
end
|
311
|
+
|
312
|
+
unless @dns_failing
|
313
|
+
commit_line() # Leave this summary line as history.
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Show the statistics.
|
318
|
+
def show_stats(line_time, total_count, totally_good,
|
319
|
+
current_mode, mode_count, ms)
|
320
|
+
loss = ((total_count - totally_good) * 100.0) / total_count
|
321
|
+
line = sprintf("%4d %4d %s %5.1f%% %7.2f ms",
|
322
|
+
total_count, mode_count, current_mode, loss, ms)
|
323
|
+
hhmm_line(line_time, line)
|
324
|
+
end
|
325
|
+
|
326
|
+
# Make history lines pretty.
|
327
|
+
# We want the history minutes to be modulo the accounting minutes.
|
328
|
+
# Where possible we want to let the ping counts to be the same.
|
329
|
+
# Ping can drift backward by one second and forward by a few seconds each run.
|
330
|
+
# Overall the drift is usually forward so when we need to make an adjustment
|
331
|
+
# we aim for 10 seconds into the next aligned minute.
|
332
|
+
def beautiful_times()
|
333
|
+
count = @options.count
|
334
|
+
|
335
|
+
# Is the target count minute aligned?
|
336
|
+
if count % 60 != 0
|
337
|
+
return count # Not minute aligned.
|
338
|
+
end
|
339
|
+
|
340
|
+
# Is the target count hour aligned?
|
341
|
+
minutes = count / 60
|
342
|
+
if 60 % minutes != 0 || minutes < 2
|
343
|
+
return count # Not hour aligned and multiple minutes.
|
344
|
+
end
|
345
|
+
|
346
|
+
# See if we are already suitable aligned right now.
|
347
|
+
now = Time.now
|
348
|
+
mm = now.min
|
349
|
+
ss = now.sec
|
350
|
+
if mm % minutes == 0 && 1 <= ss && ss <= 50
|
351
|
+
return count # Now is minute aligned and within minute drift limits.
|
352
|
+
end
|
353
|
+
|
354
|
+
# Target 10 seconds into the next aligned minute.
|
355
|
+
short_mm = minutes - (mm % minutes)
|
356
|
+
count = (short_mm * 60) + 10 - ss
|
357
|
+
return count
|
358
|
+
end
|
359
|
+
|
360
|
+
def hhmm_line(time, line)
|
361
|
+
line = "#{time.strftime('%H:%M')} #{line}"
|
362
|
+
display_line(line)
|
363
|
+
end
|
364
|
+
|
365
|
+
def hhmmss_line(time, line)
|
366
|
+
line = "#{time.strftime('%H:%M:%S')} #{line}"
|
367
|
+
display_line(line)
|
368
|
+
end
|
369
|
+
|
370
|
+
# Rewrite the current display line or save it for final debugging result.
|
371
|
+
def display_line(line)
|
372
|
+
@display_line = line
|
373
|
+
unless @debug_from
|
374
|
+
# Display this current line.
|
375
|
+
STDOUT.write "\r" # Move to the start of this line.
|
376
|
+
STDOUT.write line # Write over it.
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
# If there is a current display line, commit it to history.
|
381
|
+
def commit_line()
|
382
|
+
if @display_line
|
383
|
+
if @debug_from
|
384
|
+
# Debug mode show final line value as history.
|
385
|
+
puts @display_line
|
386
|
+
else
|
387
|
+
# Normal mode advance to the next line leaving this line as history.
|
388
|
+
puts
|
389
|
+
end
|
390
|
+
@display_line = nil
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
end
|
395
|
+
|
396
|
+
WifiWatch.new.run
|
@@ -0,0 +1,11 @@
|
|
1
|
+
09:47:38 ping: cannot resolve ns.google.com: Unknown host
|
2
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
3
|
+
|
4
|
+
Time Ping Run Mode Failed Round Trip
|
5
|
+
----- ---- ---- ---- ------ ----------
|
6
|
+
09:47 10 10 good 0.0% 54.45 ms
|
7
|
+
09:47 10 5 good 50.0% 76.66 ms
|
8
|
+
09:48:06 ping: cannot resolve ns.google.com: Unknown host
|
9
|
+
09:48 10 10 good 0.0% 72.06 ms
|
10
|
+
09:48 10 3 good 70.0% 82.17 ms
|
11
|
+
09:48:34 ping: cannot resolve ns.google.com: Unknown host
|
@@ -0,0 +1,9 @@
|
|
1
|
+
17:42:00 Waiting for dns lookup of ns.google.com ...
|
2
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
3
|
+
|
4
|
+
Time Ping Run Mode Failed Round Trip
|
5
|
+
----- ---- ---- ---- ------ ----------
|
6
|
+
17:42 10 6 good 40.0% 76.50 ms
|
7
|
+
17:42:18 Waiting for dns lookup of ns.google.com ...
|
8
|
+
17:42 10 4 good 60.0% 76.68 ms
|
9
|
+
17:42:33 Waiting for dns lookup of ns.google.com ...
|
@@ -0,0 +1,7 @@
|
|
1
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
2
|
+
|
3
|
+
Time Ping Run Mode Failed Round Trip
|
4
|
+
----- ---- ---- ---- ------ ----------
|
5
|
+
10:45 5 1 fail 20.0% 68.06 ms
|
6
|
+
10:45:43 92 bytes from 10.128.128.128: Communication prohibited by filter
|
7
|
+
10:45 11 3 good 36.4% 61.58 ms
|
@@ -0,0 +1,129 @@
|
|
1
|
+
1520606847 ping: cannot resolve ns.google.com: Unknown host
|
2
|
+
END_OF_PING
|
3
|
+
1520606848 ping: cannot resolve ns.google.com: Unknown host
|
4
|
+
END_OF_PING
|
5
|
+
1520606849 ping: cannot resolve ns.google.com: Unknown host
|
6
|
+
END_OF_PING
|
7
|
+
1520606850 ping: cannot resolve ns.google.com: Unknown host
|
8
|
+
END_OF_PING
|
9
|
+
1520606851 ping: cannot resolve ns.google.com: Unknown host
|
10
|
+
END_OF_PING
|
11
|
+
1520606852 ping: cannot resolve ns.google.com: Unknown host
|
12
|
+
END_OF_PING
|
13
|
+
1520606853 ping: cannot resolve ns.google.com: Unknown host
|
14
|
+
END_OF_PING
|
15
|
+
1520606854 ping: cannot resolve ns.google.com: Unknown host
|
16
|
+
END_OF_PING
|
17
|
+
1520606855 ping: cannot resolve ns.google.com: Unknown host
|
18
|
+
END_OF_PING
|
19
|
+
1520606856 ping: cannot resolve ns.google.com: Unknown host
|
20
|
+
END_OF_PING
|
21
|
+
1520606857 ping: cannot resolve ns.google.com: Unknown host
|
22
|
+
END_OF_PING
|
23
|
+
1520606858 ping: cannot resolve ns.google.com: Unknown host
|
24
|
+
END_OF_PING
|
25
|
+
1520606859 PING ns.google.com (216.239.32.10): 56 data bytes
|
26
|
+
1520606859 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=36.533 ms
|
27
|
+
1520606860 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=47.722 ms
|
28
|
+
1520606861 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=35.427 ms
|
29
|
+
1520606862 64 bytes from 216.239.32.10: icmp_seq=3 ttl=44 time=64.084 ms
|
30
|
+
1520606863 64 bytes from 216.239.32.10: icmp_seq=4 ttl=44 time=69.815 ms
|
31
|
+
1520606864 64 bytes from 216.239.32.10: icmp_seq=5 ttl=44 time=40.960 ms
|
32
|
+
1520606865 64 bytes from 216.239.32.10: icmp_seq=6 ttl=44 time=106.540 ms
|
33
|
+
1520606866 64 bytes from 216.239.32.10: icmp_seq=7 ttl=44 time=34.226 ms
|
34
|
+
1520606867 64 bytes from 216.239.32.10: icmp_seq=8 ttl=44 time=39.930 ms
|
35
|
+
1520606868 64 bytes from 216.239.32.10: icmp_seq=9 ttl=44 time=69.299 ms
|
36
|
+
1520606868
|
37
|
+
1520606868 --- ns.google.com ping statistics ---
|
38
|
+
1520606868 10 packets transmitted, 10 packets received, 0.0% packet loss
|
39
|
+
1520606868 round-trip min/avg/max/stddev = 34.226/54.454/106.540/21.892 ms
|
40
|
+
END_OF_PING
|
41
|
+
1520606868 PING ns.google.com (216.239.32.10): 56 data bytes
|
42
|
+
1520606868 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=35.391 ms
|
43
|
+
1520606869 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=141.665 ms
|
44
|
+
1520606870 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=131.141 ms
|
45
|
+
1520606871 64 bytes from 216.239.32.10: icmp_seq=3 ttl=44 time=35.320 ms
|
46
|
+
1520606872 64 bytes from 216.239.32.10: icmp_seq=4 ttl=44 time=39.757 ms
|
47
|
+
1520606873 ping: sendto: No route to host
|
48
|
+
1520606874 ping: sendto: No route to host
|
49
|
+
1520606874 Request timeout for icmp_seq 5
|
50
|
+
1520606875 ping: sendto: No route to host
|
51
|
+
1520606875 Request timeout for icmp_seq 6
|
52
|
+
1520606876 ping: sendto: No route to host
|
53
|
+
1520606876 Request timeout for icmp_seq 7
|
54
|
+
1520606877 ping: sendto: No route to host
|
55
|
+
1520606877 Request timeout for icmp_seq 8
|
56
|
+
1520606879
|
57
|
+
1520606879 --- ns.google.com ping statistics ---
|
58
|
+
1520606879 10 packets transmitted, 5 packets received, 50.0% packet loss
|
59
|
+
1520606879 round-trip min/avg/max/stddev = 35.320/76.655/141.665/48.924 ms
|
60
|
+
END_OF_PING
|
61
|
+
1520606879 ping: cannot resolve ns.google.com: Unknown host
|
62
|
+
END_OF_PING
|
63
|
+
1520606880 ping: cannot resolve ns.google.com: Unknown host
|
64
|
+
END_OF_PING
|
65
|
+
1520606881 ping: cannot resolve ns.google.com: Unknown host
|
66
|
+
END_OF_PING
|
67
|
+
1520606882 ping: cannot resolve ns.google.com: Unknown host
|
68
|
+
END_OF_PING
|
69
|
+
1520606883 ping: cannot resolve ns.google.com: Unknown host
|
70
|
+
END_OF_PING
|
71
|
+
1520606884 ping: cannot resolve ns.google.com: Unknown host
|
72
|
+
END_OF_PING
|
73
|
+
1520606885 ping: cannot resolve ns.google.com: Unknown host
|
74
|
+
END_OF_PING
|
75
|
+
1520606886 ping: cannot resolve ns.google.com: Unknown host
|
76
|
+
END_OF_PING
|
77
|
+
1520606887 PING ns.google.com (216.239.32.10): 56 data bytes
|
78
|
+
1520606887 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=40.028 ms
|
79
|
+
1520606888 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=44.796 ms
|
80
|
+
1520606889 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=43.484 ms
|
81
|
+
1520606890 64 bytes from 216.239.32.10: icmp_seq=3 ttl=44 time=238.342 ms
|
82
|
+
1520606891 64 bytes from 216.239.32.10: icmp_seq=4 ttl=44 time=161.573 ms
|
83
|
+
1520606892 64 bytes from 216.239.32.10: icmp_seq=5 ttl=44 time=57.327 ms
|
84
|
+
1520606893 64 bytes from 216.239.32.10: icmp_seq=6 ttl=44 time=36.289 ms
|
85
|
+
1520606894 64 bytes from 216.239.32.10: icmp_seq=7 ttl=44 time=31.354 ms
|
86
|
+
1520606895 64 bytes from 216.239.32.10: icmp_seq=8 ttl=44 time=32.630 ms
|
87
|
+
1520606896 64 bytes from 216.239.32.10: icmp_seq=9 ttl=44 time=34.819 ms
|
88
|
+
1520606896
|
89
|
+
1520606896 --- ns.google.com ping statistics ---
|
90
|
+
1520606896 10 packets transmitted, 10 packets received, 0.0% packet loss
|
91
|
+
1520606896 round-trip min/avg/max/stddev = 31.354/72.064/238.342/66.591 ms
|
92
|
+
END_OF_PING
|
93
|
+
1520606896 PING ns.google.com (216.239.32.10): 56 data bytes
|
94
|
+
1520606896 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=38.382 ms
|
95
|
+
1520606897 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=120.228 ms
|
96
|
+
1520606898 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=87.912 ms
|
97
|
+
1520606899 ping: sendto: No route to host
|
98
|
+
1520606900 ping: sendto: No route to host
|
99
|
+
1520606900 Request timeout for icmp_seq 3
|
100
|
+
1520606901 ping: sendto: No route to host
|
101
|
+
1520606901 Request timeout for icmp_seq 4
|
102
|
+
1520606902 ping: sendto: No route to host
|
103
|
+
1520606902 Request timeout for icmp_seq 5
|
104
|
+
1520606903 ping: sendto: No route to host
|
105
|
+
1520606903 Request timeout for icmp_seq 6
|
106
|
+
1520606904 ping: sendto: No route to host
|
107
|
+
1520606904 Request timeout for icmp_seq 7
|
108
|
+
1520606905 ping: sendto: No route to host
|
109
|
+
1520606905 Request timeout for icmp_seq 8
|
110
|
+
1520606907
|
111
|
+
1520606907 --- ns.google.com ping statistics ---
|
112
|
+
1520606907 10 packets transmitted, 3 packets received, 70.0% packet loss
|
113
|
+
1520606907 round-trip min/avg/max/stddev = 38.382/82.174/120.228/33.659 ms
|
114
|
+
END_OF_PING
|
115
|
+
1520606907 ping: cannot resolve ns.google.com: Unknown host
|
116
|
+
END_OF_PING
|
117
|
+
1520606908 ping: cannot resolve ns.google.com: Unknown host
|
118
|
+
END_OF_PING
|
119
|
+
1520606909 ping: cannot resolve ns.google.com: Unknown host
|
120
|
+
END_OF_PING
|
121
|
+
1520606910 ping: cannot resolve ns.google.com: Unknown host
|
122
|
+
END_OF_PING
|
123
|
+
1520606911 ping: cannot resolve ns.google.com: Unknown host
|
124
|
+
END_OF_PING
|
125
|
+
1520606912 ping: cannot resolve ns.google.com: Unknown host
|
126
|
+
END_OF_PING
|
127
|
+
1520606913 ping: cannot resolve ns.google.com: Unknown host
|
128
|
+
END_OF_PING
|
129
|
+
1520606914 ping: cannot resolve ns.google.com: Unknown host
|
@@ -0,0 +1,47 @@
|
|
1
|
+
1520635313 DNS_LOOKUP 17:41:53 Waiting for dns lookup of ns.google.com ...
|
2
|
+
1520635314 DNS_LOOKUP 17:41:54 Waiting for dns lookup of ns.google.com ...
|
3
|
+
1520635315 DNS_LOOKUP 17:41:55 Waiting for dns lookup of ns.google.com ...
|
4
|
+
1520635317 DNS_LOOKUP 17:41:57 Waiting for dns lookup of ns.google.com ...
|
5
|
+
1520635318 DNS_LOOKUP 17:41:58 Waiting for dns lookup of ns.google.com ...
|
6
|
+
1520635319 DNS_LOOKUP 17:41:59 Waiting for dns lookup of ns.google.com ...
|
7
|
+
1520635320 DNS_LOOKUP 17:42:00 Waiting for dns lookup of ns.google.com ...
|
8
|
+
1520635320 PING ns.google.com (216.239.32.10): 56 data bytes
|
9
|
+
1520635320 64 bytes from 216.239.32.10: icmp_seq=0 ttl=46 time=34.544 ms
|
10
|
+
1520635321 64 bytes from 216.239.32.10: icmp_seq=1 ttl=46 time=31.144 ms
|
11
|
+
1520635322 64 bytes from 216.239.32.10: icmp_seq=2 ttl=46 time=61.392 ms
|
12
|
+
1520635323 64 bytes from 216.239.32.10: icmp_seq=3 ttl=46 time=29.985 ms
|
13
|
+
1520635324 64 bytes from 216.239.32.10: icmp_seq=4 ttl=46 time=152.010 ms
|
14
|
+
1520635325 64 bytes from 216.239.32.10: icmp_seq=5 ttl=46 time=149.945 ms
|
15
|
+
1520635327 Request timeout for icmp_seq 6
|
16
|
+
1520635328 Request timeout for icmp_seq 7
|
17
|
+
1520635329 Request timeout for icmp_seq 8
|
18
|
+
1520635331
|
19
|
+
1520635331 --- ns.google.com ping statistics ---
|
20
|
+
1520635331 10 packets transmitted, 6 packets received, 40.0% packet loss
|
21
|
+
1520635331 round-trip min/avg/max/stddev = 29.985/76.503/152.010/53.705 ms
|
22
|
+
END_OF_PING
|
23
|
+
1520635332 DNS_LOOKUP 17:42:12 Waiting for dns lookup of ns.google.com ...
|
24
|
+
1520635333 DNS_LOOKUP 17:42:13 Waiting for dns lookup of ns.google.com ...
|
25
|
+
1520635334 DNS_LOOKUP 17:42:14 Waiting for dns lookup of ns.google.com ...
|
26
|
+
1520635335 DNS_LOOKUP 17:42:15 Waiting for dns lookup of ns.google.com ...
|
27
|
+
1520635336 DNS_LOOKUP 17:42:16 Waiting for dns lookup of ns.google.com ...
|
28
|
+
1520635337 DNS_LOOKUP 17:42:17 Waiting for dns lookup of ns.google.com ...
|
29
|
+
1520635338 DNS_LOOKUP 17:42:18 Waiting for dns lookup of ns.google.com ...
|
30
|
+
1520635339 PING ns.google.com (216.239.32.10): 56 data bytes
|
31
|
+
1520635339 64 bytes from 216.239.32.10: icmp_seq=0 ttl=46 time=36.815 ms
|
32
|
+
1520635340 64 bytes from 216.239.32.10: icmp_seq=1 ttl=46 time=26.418 ms
|
33
|
+
1520635341 64 bytes from 216.239.32.10: icmp_seq=2 ttl=46 time=92.105 ms
|
34
|
+
1520635342 64 bytes from 216.239.32.10: icmp_seq=3 ttl=46 time=151.393 ms
|
35
|
+
1520635344 Request timeout for icmp_seq 4
|
36
|
+
1520635345 Request timeout for icmp_seq 5
|
37
|
+
1520635346 Request timeout for icmp_seq 6
|
38
|
+
1520635347 Request timeout for icmp_seq 7
|
39
|
+
1520635348 Request timeout for icmp_seq 8
|
40
|
+
1520635350
|
41
|
+
1520635350 --- ns.google.com ping statistics ---
|
42
|
+
1520635350 10 packets transmitted, 4 packets received, 60.0% packet loss
|
43
|
+
1520635350 round-trip min/avg/max/stddev = 26.418/76.683/151.393/49.838 ms
|
44
|
+
END_OF_PING
|
45
|
+
1520635351 DNS_LOOKUP 17:42:31 Waiting for dns lookup of ns.google.com ...
|
46
|
+
1520635352 DNS_LOOKUP 17:42:32 Waiting for dns lookup of ns.google.com ...
|
47
|
+
1520635353 DNS_LOOKUP 17:42:33 Waiting for dns lookup of ns.google.com ...
|
@@ -0,0 +1,30 @@
|
|
1
|
+
1520609460 PING ns.google.com (216.239.32.10): 56 data bytes
|
2
|
+
1520609460 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=36.094 ms
|
3
|
+
1520609461 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=28.811 ms
|
4
|
+
1520609462 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=51.550 ms
|
5
|
+
1520609463 64 bytes from 216.239.32.10: icmp_seq=3 ttl=44 time=43.548 ms
|
6
|
+
1520609464 64 bytes from 216.239.32.10: icmp_seq=4 ttl=44 time=137.129 ms
|
7
|
+
1520609465 64 bytes from 216.239.32.10: icmp_seq=5 ttl=44 time=55.223 ms
|
8
|
+
1520609466 64 bytes from 216.239.32.10: icmp_seq=6 ttl=44 time=157.352 ms
|
9
|
+
1520609467 64 bytes from 216.239.32.10: icmp_seq=7 ttl=44 time=32.181 ms
|
10
|
+
1520609468 64 bytes from 216.239.32.10: icmp_seq=8 ttl=44 time=215.623 ms
|
11
|
+
1520609469 64 bytes from 216.239.32.10: icmp_seq=9 ttl=44 time=47.139 ms
|
12
|
+
1520609469
|
13
|
+
1520609469 --- ns.google.com ping statistics ---
|
14
|
+
1520609469 10 packets transmitted, 10 packets received, 0.0% packet loss
|
15
|
+
1520609469 round-trip min/avg/max/stddev = 28.811/80.465/215.623/61.891 ms
|
16
|
+
END_OF_PING
|
17
|
+
1520609469 PING ns.google.com (216.239.32.10): 56 data bytes
|
18
|
+
1520609469 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=124.769 ms
|
19
|
+
1520609470 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=121.649 ms
|
20
|
+
1520609471 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=32.698 ms
|
21
|
+
1520609473 ping: sendto: No route to host
|
22
|
+
1520609473 Request timeout for icmp_seq 3
|
23
|
+
1520609474 ping: sendto: No route to host
|
24
|
+
1520609474 Request timeout for icmp_seq 4
|
25
|
+
1520609475 ping: sendto: No route to host
|
26
|
+
1520609475 Request timeout for icmp_seq 5
|
27
|
+
1520609476 ping: sendto: No route to host
|
28
|
+
1520609476 Request timeout for icmp_seq 6
|
29
|
+
1520609477 ping: sendto: No route to host
|
30
|
+
1520609477 Request timeout for icmp_seq 7
|
@@ -0,0 +1,24 @@
|
|
1
|
+
1520610336 PING ns.google.com (216.239.32.10): 56 data bytes
|
2
|
+
1520610336 64 bytes from 216.239.32.10: icmp_seq=0 ttl=44 time=45.126 ms
|
3
|
+
1520610337 64 bytes from 216.239.32.10: icmp_seq=1 ttl=44 time=142.804 ms
|
4
|
+
1520610338 64 bytes from 216.239.32.10: icmp_seq=2 ttl=44 time=34.206 ms
|
5
|
+
1520610339 64 bytes from 216.239.32.10: icmp_seq=3 ttl=44 time=68.064 ms
|
6
|
+
1520610340 Request timeout for icmp_seq 4
|
7
|
+
1520610340 92 bytes from 10.128.128.128: Communication prohibited by filter
|
8
|
+
1520610340 Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
|
9
|
+
1520610340 4 5 00 5400 6dea 0 0000 40 01 21dd 10.57.228.249 104.27.147.148
|
10
|
+
1520610341 Request timeout for icmp_seq 5
|
11
|
+
1520610341 92 bytes from 10.128.128.128: Communication prohibited by filter
|
12
|
+
1520610341 Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
|
13
|
+
1520610341 4 5 00 5400 6dea 0 0000 40 01 21dd 10.57.228.249 104.27.147.148
|
14
|
+
1520610342 Request timeout for icmp_seq 6
|
15
|
+
1520610342 92 bytes from 10.128.128.128: Communication prohibited by filter
|
16
|
+
1520610342 Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
|
17
|
+
1520610342 4 5 00 5400 6dea 0 0000 40 01 21dd 10.57.228.249 104.27.147.148
|
18
|
+
1520610343 Request timeout for icmp_seq 7
|
19
|
+
1520610343 92 bytes from 10.128.128.128: Communication prohibited by filter
|
20
|
+
1520610343 Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
|
21
|
+
1520610343 4 5 00 5400 6dea 0 0000 40 01 21dd 10.57.228.249 104.27.147.148
|
22
|
+
1520610344 64 bytes from 216.239.32.10: icmp_seq=8 ttl=44 time=184.792 ms
|
23
|
+
1520610345 64 bytes from 216.239.32.10: icmp_seq=9 ttl=44 time=103.312 ms
|
24
|
+
1520610346 64 bytes from 216.239.32.10: icmp_seq=10 ttl=44 time=61.582 ms
|
@@ -0,0 +1,11 @@
|
|
1
|
+
09:47:38 ping: cannot resolve ns.google.com: Unknown host
|
2
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
3
|
+
|
4
|
+
Time Ping Run Mode Failed Round Trip
|
5
|
+
----- ---- ---- ---- ------ ----------
|
6
|
+
09:47 10 10 good 0.0% 54.45 ms
|
7
|
+
09:47 10 5 good 50.0% 76.66 ms
|
8
|
+
09:48:06 ping: cannot resolve ns.google.com: Unknown host
|
9
|
+
09:48 10 10 good 0.0% 72.06 ms
|
10
|
+
09:48 10 3 good 70.0% 82.17 ms
|
11
|
+
09:48:34 ping: cannot resolve ns.google.com: Unknown host
|
@@ -0,0 +1,7 @@
|
|
1
|
+
PING ns.google.com (216.239.32.10): 56 data bytes
|
2
|
+
|
3
|
+
Time Ping Run Mode Failed Round Trip
|
4
|
+
----- ---- ---- ---- ------ ----------
|
5
|
+
10:45 5 1 fail 20.0% 68.06 ms
|
6
|
+
10:45:43 92 bytes from 10.128.128.128: Communication prohibited by filter
|
7
|
+
10:45 11 3 good 36.4% 61.58 ms
|
data/test/run_tests
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
dir=`dirname $0`
|
4
|
+
wifiwatch="$dir/../bin/wifi-watch"
|
5
|
+
ping_logs="$dir/ping_logs"
|
6
|
+
expected="$dir/expected"
|
7
|
+
results="$dir/results"
|
8
|
+
|
9
|
+
tests=0
|
10
|
+
fail=0
|
11
|
+
mkdir -p $results
|
12
|
+
rm -f $results/*
|
13
|
+
|
14
|
+
echo
|
15
|
+
for test_path in $ping_logs/*.log; do
|
16
|
+
test_name=`basename $test_path .log`
|
17
|
+
|
18
|
+
echo -n "Running $test_name ... "
|
19
|
+
$wifiwatch --debug-from $test_path >$results/$test_name.out
|
20
|
+
tests=$(expr $tests + 1)
|
21
|
+
|
22
|
+
if cmp -s $expected/$test_name.out $results/$test_name.out; then
|
23
|
+
echo "Success!"
|
24
|
+
else
|
25
|
+
fail=$(expr $fail + 1)
|
26
|
+
echo "Failed!"
|
27
|
+
echo "diff $expected/$test_name.out $results/$test_name.out"
|
28
|
+
diff $expected/$test_name.out $results/$test_name.out
|
29
|
+
echo
|
30
|
+
fi
|
31
|
+
|
32
|
+
done
|
33
|
+
|
34
|
+
echo
|
35
|
+
echo "$tests tests, $fail errors"
|
36
|
+
echo
|
37
|
+
|
38
|
+
[ "$fail" = 0 ]
|
39
|
+
|
data/wifi-watch.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = "wifi-watch"
|
4
|
+
spec.version = "1.0.0"
|
5
|
+
spec.authors = ["John Gorman"]
|
6
|
+
spec.email = ["johngorman2@gmail.com"]
|
7
|
+
|
8
|
+
spec.summary = %q{Continuously monitor your network speed and quality!}
|
9
|
+
spec.description = %q{Run wifi-watch in a terminal so that you can easily check your network quality at this moment and how it has been holding up since you began recording hours or days ago.}
|
10
|
+
spec.homepage = "https://github.com/jgorman/wifi-watch"
|
11
|
+
spec.license = "MIT"
|
12
|
+
|
13
|
+
spec.files = `git ls-files`.split
|
14
|
+
spec.bindir = "bin"
|
15
|
+
spec.executables = ["wifi-watch"]
|
16
|
+
spec.require_paths = ["lib"]
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wifi-watch
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Gorman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Run wifi-watch in a terminal so that you can easily check your network
|
14
|
+
quality at this moment and how it has been holding up since you began recording
|
15
|
+
hours or days ago.
|
16
|
+
email:
|
17
|
+
- johngorman2@gmail.com
|
18
|
+
executables:
|
19
|
+
- wifi-watch
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- ".gitignore"
|
24
|
+
- Gemfile
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- bin/wifi-watch
|
29
|
+
- test/expected/dns-down.out
|
30
|
+
- test/expected/dns-slow.out
|
31
|
+
- test/expected/fail-mode.out
|
32
|
+
- test/expected/wifi-login.out
|
33
|
+
- test/ping_logs/dns-down.log
|
34
|
+
- test/ping_logs/dns-slow.log
|
35
|
+
- test/ping_logs/fail-mode.log
|
36
|
+
- test/ping_logs/wifi-login.log
|
37
|
+
- test/results/dns-down.out
|
38
|
+
- test/results/fail-mode.out
|
39
|
+
- test/results/wifi-login.out
|
40
|
+
- test/run_tests
|
41
|
+
- wifi-watch.gemspec
|
42
|
+
homepage: https://github.com/jgorman/wifi-watch
|
43
|
+
licenses:
|
44
|
+
- MIT
|
45
|
+
metadata: {}
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 2.4.5.4
|
63
|
+
signing_key:
|
64
|
+
specification_version: 4
|
65
|
+
summary: Continuously monitor your network speed and quality!
|
66
|
+
test_files: []
|