wifi-watch 1.0.1 → 1.0.2
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 +4 -4
- data/README.md +8 -7
- data/bin/wifi-watch +54 -37
- data/wifi-service/index.js +29 -0
- data/wifi-service/pinger.js +132 -0
- data/wifi-watch.gemspec +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9797d50586860cee6df38fdec51a3b14700bc21
|
4
|
+
data.tar.gz: b3b495a1b8ec39d7064493ffedff9995a0f79790
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6696aa3538b2673da41774062de6cd58dc3839e57bd337a56b8e07fe3b612df1fad66cb2021d89181d519f23b51d30caf8f750b085be321da741b8f2883e3b8d
|
7
|
+
data.tar.gz: a3759eafc8138bbaa6831326933cac144ba8aff3aab6e4004478300b38834b82a0ac141c7edbb0a07c5dca2bc554881b08ef2c86f7ff7f210f5902b93a33df53
|
data/README.md
CHANGED
@@ -60,9 +60,10 @@ sudo mv wifi-watch /usr/local/bin
|
|
60
60
|
|
61
61
|
```
|
62
62
|
-h, --host host Host to ping [ns.google.com].
|
63
|
-
-c, --count seconds Accounting period [600].
|
64
|
-
|
65
|
-
--
|
63
|
+
-c, --count seconds Accounting period length [600 seconds].
|
64
|
+
-p, --periods periods Accounting periods to run [infinite].
|
65
|
+
--ping-to file Write ping output to a file for debugging.
|
66
|
+
--ping-from file Read ping input from a file ('-' for stdin).
|
66
67
|
-v, --version Version.
|
67
68
|
--help This message.
|
68
69
|
```
|
@@ -173,7 +174,7 @@ It is easy to capture the raw ping output to a file for later
|
|
173
174
|
replay and testing.
|
174
175
|
|
175
176
|
```
|
176
|
-
wifi-watch --count 10 --
|
177
|
+
wifi-watch --count 10 --ping-to test1.log
|
177
178
|
PING ns.google.com (216.239.32.10): 56 data bytes
|
178
179
|
|
179
180
|
Time Ping Run Mode Failed Round Trip
|
@@ -189,7 +190,7 @@ so replaying the file later on should result in
|
|
189
190
|
identical appearing output.
|
190
191
|
|
191
192
|
```
|
192
|
-
wifi-watch --
|
193
|
+
wifi-watch --ping-from test1.log
|
193
194
|
PING ns.google.com (216.239.32.10): 56 data bytes
|
194
195
|
|
195
196
|
Time Ping Run Mode Failed Round Trip
|
@@ -200,7 +201,7 @@ Time Ping Run Mode Failed Round Trip
|
|
200
201
|
10:06 5 1 fail 20.0% 55.16 ms
|
201
202
|
```
|
202
203
|
|
203
|
-
Although the --
|
204
|
+
Although the --ping-from output should appear to be the same
|
204
205
|
as live ping monitoring there is a difference. Instead of emitting
|
205
206
|
every intermediate count on the current line, only the final
|
206
207
|
line is printed. This helps keep test cases short and readable.
|
@@ -213,7 +214,7 @@ Bug reports and pull requests are welcome on GitHub at
|
|
213
214
|
https://github.com/jgorman/wifi-watch.
|
214
215
|
|
215
216
|
If you discover a shortcoming capture the ping output
|
216
|
-
using --
|
217
|
+
using --ping-to and open an issue. Thanks!
|
217
218
|
|
218
219
|
## License
|
219
220
|
|
data/bin/wifi-watch
CHANGED
@@ -9,42 +9,46 @@ class WifiWatch
|
|
9
9
|
Default_host = "ns.google.com" # Ping target host.
|
10
10
|
Default_count = 600 # Accounting period in seconds.
|
11
11
|
Program = "wifi-watch"
|
12
|
-
Version = "1.0.
|
12
|
+
Version = "1.0.2"
|
13
13
|
|
14
14
|
def run
|
15
15
|
@shown_header = false # Have we shown the column headers yet?
|
16
16
|
@dns_failing = false # Are DNS lookups currently failing?
|
17
17
|
@display_line = nil # The current display line.
|
18
|
-
@
|
19
|
-
@
|
18
|
+
@ping_to = nil # Save timestamped ping output here.
|
19
|
+
@ping_from = nil # Read timestamped ping input here.
|
20
20
|
@options = get_options()
|
21
21
|
|
22
|
-
if @options.
|
22
|
+
if @options.ping_to
|
23
23
|
begin
|
24
|
-
@
|
24
|
+
@ping_to = File.open(@options.ping_to, "w")
|
25
25
|
rescue => e
|
26
26
|
puts
|
27
|
-
puts "
|
27
|
+
puts "ping_to=#{@options.ping_to}: #{e}"
|
28
28
|
puts
|
29
29
|
exit
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
if @options.
|
33
|
+
if @options.ping_from
|
34
34
|
|
35
|
-
# Debug mode simulates ping output from a captured --
|
35
|
+
# Debug mode simulates ping output from a captured --ping-to file.
|
36
36
|
begin
|
37
|
-
|
37
|
+
if @options.ping_from == "-"
|
38
|
+
@ping_from = STDIN
|
39
|
+
else
|
40
|
+
@ping_from = File.open(@options.ping_from, "r")
|
41
|
+
end
|
38
42
|
rescue => e
|
39
43
|
puts
|
40
|
-
puts "
|
44
|
+
puts "ping_from=#{@options.ping_from}: #{e}"
|
41
45
|
puts
|
42
46
|
exit
|
43
47
|
end
|
44
48
|
|
45
49
|
# Call ping_period() for each ping run section.
|
46
|
-
until @
|
47
|
-
ping_period(@
|
50
|
+
until @ping_from.eof?
|
51
|
+
ping_period(@ping_from) # Reads up to next "END_OF_PING" line.
|
48
52
|
end
|
49
53
|
if @dns_failing
|
50
54
|
commit_line() # Show that we ended up in dns failure mode.
|
@@ -53,12 +57,19 @@ class WifiWatch
|
|
53
57
|
else
|
54
58
|
|
55
59
|
# Run ping multiple times.
|
60
|
+
periods = 0
|
56
61
|
while true
|
57
62
|
count = beautiful_times()
|
58
63
|
cmd = "ping -c #{count} #{@options.host}"
|
59
64
|
stdin, stdout, pid = PTY.spawn( cmd )
|
60
65
|
ping_period(stdin) # Run one accounting period.
|
61
66
|
Process.waitall() # Soak up any zombie pings.
|
67
|
+
if @options.periods > 0
|
68
|
+
periods += 1
|
69
|
+
if periods >= @options.periods
|
70
|
+
break
|
71
|
+
end
|
72
|
+
end
|
62
73
|
end
|
63
74
|
|
64
75
|
end
|
@@ -66,15 +77,16 @@ class WifiWatch
|
|
66
77
|
rescue Interrupt
|
67
78
|
commit_line()
|
68
79
|
ensure
|
69
|
-
if @
|
70
|
-
@
|
80
|
+
if @ping_to
|
81
|
+
@ping_to.close
|
71
82
|
end
|
72
83
|
end
|
73
84
|
|
74
85
|
def get_options
|
75
|
-
options
|
76
|
-
options.host
|
77
|
-
options.count
|
86
|
+
options = OpenStruct.new
|
87
|
+
options.host = Default_host
|
88
|
+
options.count = Default_count
|
89
|
+
options.periods = 0
|
78
90
|
|
79
91
|
opt_parser = OptionParser.new do |opt|
|
80
92
|
opt.banner = "Usage: #{Program} [OPTIONS]"
|
@@ -85,19 +97,24 @@ class WifiWatch
|
|
85
97
|
end
|
86
98
|
|
87
99
|
opt.on("-c", "--count seconds", Integer,
|
88
|
-
"Accounting period [#{options.count}].") do |count|
|
100
|
+
"Accounting period length [#{options.count} seconds].") do |count|
|
89
101
|
raise "--count must be positive" unless count > 0
|
90
102
|
options.count = count
|
91
103
|
end
|
92
104
|
|
93
|
-
opt.on("
|
94
|
-
"
|
95
|
-
options.
|
105
|
+
opt.on("-p", "--periods periods", Integer,
|
106
|
+
"Accounting periods to run [infinite].") do |periods|
|
107
|
+
options.periods = periods
|
108
|
+
end
|
109
|
+
|
110
|
+
opt.on("--ping-to file",
|
111
|
+
"Write ping output to a file for debugging.") do |ping_to|
|
112
|
+
options.ping_to = ping_to
|
96
113
|
end
|
97
114
|
|
98
|
-
opt.on("--
|
99
|
-
"Read ping input from a file for
|
100
|
-
options.
|
115
|
+
opt.on("--ping-from file",
|
116
|
+
"Read ping input from a file ('-' for stdin).") do |ping_from|
|
117
|
+
options.ping_from = ping_from
|
101
118
|
end
|
102
119
|
|
103
120
|
opt.on("-v", "--version", "Version.") do
|
@@ -158,9 +175,9 @@ class WifiWatch
|
|
158
175
|
now = Time.now
|
159
176
|
if now - last_notified >= 1
|
160
177
|
hhmmss_line(now, "Waiting for dns lookup of #{@options.host} ...")
|
161
|
-
if @
|
162
|
-
@
|
163
|
-
@
|
178
|
+
if @ping_to
|
179
|
+
@ping_to.puts "#{now.to_i} DNS_LOOKUP #{@display_line}"
|
180
|
+
@ping_to.flush
|
164
181
|
end
|
165
182
|
last_notified = now
|
166
183
|
end
|
@@ -188,7 +205,7 @@ class WifiWatch
|
|
188
205
|
first_byte = nil
|
189
206
|
end
|
190
207
|
|
191
|
-
if @
|
208
|
+
if @ping_from
|
192
209
|
# Read from the debugging source file up to the end of this ping run.
|
193
210
|
if line == "END_OF_PING"
|
194
211
|
break # End this ping accounting period run.
|
@@ -200,17 +217,17 @@ class WifiWatch
|
|
200
217
|
line_time = Time.now
|
201
218
|
end
|
202
219
|
|
203
|
-
if @
|
220
|
+
if @ping_to
|
204
221
|
# Capture this ping output line with the timestamp for later debugging.
|
205
|
-
@
|
206
|
-
@
|
222
|
+
@ping_to.puts "#{line_time.to_i} #{line}"
|
223
|
+
@ping_to.flush
|
207
224
|
end
|
208
225
|
|
209
226
|
# DNS failure modes.
|
210
227
|
if line =~ /cannot resolve/
|
211
228
|
# ping: cannot resolve ns.google.com: Unknown host
|
212
229
|
hhmmss_line(line_time, line)
|
213
|
-
sleep 1 unless @
|
230
|
+
sleep 1 unless @ping_from # Speed up testing.
|
214
231
|
@dns_failing = true
|
215
232
|
elsif line =~ /DNS_LOOKUP (.*)/
|
216
233
|
# Waiting for dns lookup of ns.google.com ...
|
@@ -301,10 +318,10 @@ class WifiWatch
|
|
301
318
|
|
302
319
|
end
|
303
320
|
|
304
|
-
if @
|
321
|
+
if @ping_to
|
305
322
|
# Insert a ping run separator line into the debugging file.
|
306
|
-
@
|
307
|
-
@
|
323
|
+
@ping_to.puts "END_OF_PING"
|
324
|
+
@ping_to.flush
|
308
325
|
end
|
309
326
|
|
310
327
|
# Final summary line.
|
@@ -379,7 +396,7 @@ class WifiWatch
|
|
379
396
|
# Rewrite the current display line or save it for final debugging result.
|
380
397
|
def display_line(line)
|
381
398
|
@display_line = line
|
382
|
-
unless @
|
399
|
+
unless @ping_from
|
383
400
|
# Display this current line.
|
384
401
|
STDOUT.write "\r" # Move to the start of this line.
|
385
402
|
STDOUT.write line # Write over it.
|
@@ -389,7 +406,7 @@ class WifiWatch
|
|
389
406
|
# If there is a current display line, commit it to history.
|
390
407
|
def commit_line()
|
391
408
|
if @display_line
|
392
|
-
if @
|
409
|
+
if @ping_from
|
393
410
|
# Debug mode show final line value as history.
|
394
411
|
puts @display_line
|
395
412
|
else
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env node
|
2
|
+
|
3
|
+
const http = require("http");
|
4
|
+
const Pinger = require("./pinger");
|
5
|
+
|
6
|
+
const pinger = Pinger();
|
7
|
+
pinger.start();
|
8
|
+
|
9
|
+
const server = http.createServer();
|
10
|
+
server.on("request", (req, res) => {
|
11
|
+
const start_time = Date.now();
|
12
|
+
if (req.url === "/summary") {
|
13
|
+
pinger.summary().pipe(res)
|
14
|
+
} else if (req.url === "/pings") {
|
15
|
+
pinger.pings().pipe(res)
|
16
|
+
} else if (req.url === "/stop") {
|
17
|
+
pinger.stop();
|
18
|
+
res.end("Stopped\n")
|
19
|
+
} else if (req.url === "/start") {
|
20
|
+
pinger.start();
|
21
|
+
res.end("Started\n")
|
22
|
+
} else {
|
23
|
+
res.end("Okay\n")
|
24
|
+
}
|
25
|
+
const end_time = Date.now();
|
26
|
+
console.log(`Ran ${req.url} in ${end_time - start_time} ms.`);
|
27
|
+
});
|
28
|
+
|
29
|
+
server.listen(3000);
|
@@ -0,0 +1,132 @@
|
|
1
|
+
/*
|
2
|
+
* Gather ping logs.
|
3
|
+
*
|
4
|
+
* import Pinger from "./pinger";
|
5
|
+
* pinger = Pinger();
|
6
|
+
* pinger.start({ count: 600, logs: 6 });
|
7
|
+
* ping_stream = pinger.ping_stream();
|
8
|
+
* ping_stream.pipe(process.stdout);
|
9
|
+
* pinger.stop();
|
10
|
+
*
|
11
|
+
*/
|
12
|
+
|
13
|
+
const { spawn } = require("child_process");
|
14
|
+
const { Readable } = require('stream');
|
15
|
+
|
16
|
+
const Pinger = () => {
|
17
|
+
|
18
|
+
const default_options = {
|
19
|
+
host: "ns.google.com",
|
20
|
+
count: 600,
|
21
|
+
logs: 6
|
22
|
+
};
|
23
|
+
let options = default_options;
|
24
|
+
let ping_proc;
|
25
|
+
const ping_logs = [];
|
26
|
+
|
27
|
+
const start = (opts = {}) => {
|
28
|
+
if (!ping_proc) {
|
29
|
+
options = { ...default_options, ...opts};
|
30
|
+
run();
|
31
|
+
}
|
32
|
+
};
|
33
|
+
|
34
|
+
const stop = () => {
|
35
|
+
if (ping_proc) {
|
36
|
+
ping_proc.kill();
|
37
|
+
ping_proc = undefined;
|
38
|
+
ping_logs.splice(0, ping_logs.length);
|
39
|
+
}
|
40
|
+
};
|
41
|
+
|
42
|
+
const run = () => {
|
43
|
+
const ping_log = [];
|
44
|
+
let pushed = false;
|
45
|
+
|
46
|
+
// Spawn a ping process.
|
47
|
+
ping_proc = spawn("ping", [ "-c", options.count, options.host ]);
|
48
|
+
|
49
|
+
// Catch any errors and exit.
|
50
|
+
ping_proc.on("error", (err) => {
|
51
|
+
console.error("spawn ping:", err.code, err.path, err.spawnargs);
|
52
|
+
process.exit(2);
|
53
|
+
});
|
54
|
+
|
55
|
+
// On ping close start a new one.
|
56
|
+
ping_proc.on("close", () => {
|
57
|
+
ping_log.push("END_OF_PING\n");
|
58
|
+
if (ping_proc) {
|
59
|
+
run();
|
60
|
+
}
|
61
|
+
});
|
62
|
+
|
63
|
+
// Capture each new ping line.
|
64
|
+
ping_proc.stdout.on("data", (data) => {
|
65
|
+
now = Math.round(Date.now() / 1000);
|
66
|
+
data_s = data.toString().trim();
|
67
|
+
lines = data_s.split("\n");
|
68
|
+
lines.forEach( (line) => {
|
69
|
+
timed_line = `${now} ${line}\n`;
|
70
|
+
ping_log.push(timed_line);
|
71
|
+
});
|
72
|
+
|
73
|
+
// Now that we have some data remove old logs and append this log.
|
74
|
+
if (!pushed) {
|
75
|
+
while (ping_logs.length >= options.logs) {
|
76
|
+
ping_logs.shift();
|
77
|
+
}
|
78
|
+
ping_logs.push(ping_log);
|
79
|
+
pushed = true;
|
80
|
+
}
|
81
|
+
});
|
82
|
+
}
|
83
|
+
|
84
|
+
// Create a new ping log stream.
|
85
|
+
const pings = () => {
|
86
|
+
let next_log = 0;
|
87
|
+
|
88
|
+
const reader = new Readable({
|
89
|
+
read(size) {
|
90
|
+
// Get the next log.
|
91
|
+
ping_log = ping_logs[next_log];
|
92
|
+
if (ping_log == undefined) {
|
93
|
+
this.push(null);
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
next_log += 1;
|
97
|
+
|
98
|
+
// If there are multiple lines, compact them.
|
99
|
+
if (ping_log.length > 0) {
|
100
|
+
compacted = ping_log.join('');
|
101
|
+
ping_log.splice(0, ping_log.length, compacted);
|
102
|
+
}
|
103
|
+
|
104
|
+
// Send out the log.
|
105
|
+
this.push(ping_log[0]);
|
106
|
+
}
|
107
|
+
});
|
108
|
+
|
109
|
+
return reader;
|
110
|
+
}
|
111
|
+
|
112
|
+
// Create a new ping summary stream.
|
113
|
+
const summary = () => {
|
114
|
+
const wifi_watch = spawn("wifi-watch", ["--ping-from=-"]);
|
115
|
+
wifi_watch.on("error", (err) => {
|
116
|
+
console.error("spawn wifi-watch:", err.code, err.path, err.spawnargs);
|
117
|
+
process.exit(2);
|
118
|
+
});
|
119
|
+
|
120
|
+
pings().pipe(wifi_watch.stdin);
|
121
|
+
return wifi_watch.stdout;
|
122
|
+
};
|
123
|
+
|
124
|
+
return {
|
125
|
+
start: start,
|
126
|
+
stop: stop,
|
127
|
+
pings: pings,
|
128
|
+
summary: summary
|
129
|
+
};
|
130
|
+
};
|
131
|
+
|
132
|
+
module.exports = Pinger;
|
data/wifi-watch.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wifi-watch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Gorman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Run wifi-watch in a terminal so that you can easily check your network
|
14
14
|
quality at this moment and how it has been holding up since you began recording
|
@@ -35,6 +35,8 @@ files:
|
|
35
35
|
- test/ping_logs/fail-mode.log
|
36
36
|
- test/ping_logs/wifi-login.log
|
37
37
|
- test/run_tests
|
38
|
+
- wifi-service/index.js
|
39
|
+
- wifi-service/pinger.js
|
38
40
|
- wifi-watch.gemspec
|
39
41
|
homepage: https://github.com/jgorman/wifi-watch
|
40
42
|
licenses:
|