wifi-watch 1.0.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 +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: []
|