Add the --use_interface_counters option.
This commit is contained in:
parent
93951f1154
commit
e31dd2700a
|
@ -97,6 +97,11 @@ Usage
|
||||||
--timeout TIMEOUT HTTP timeout in seconds. Default 10
|
--timeout TIMEOUT HTTP timeout in seconds. Default 10
|
||||||
--secure Use HTTPS instead of HTTP when communicating with
|
--secure Use HTTPS instead of HTTP when communicating with
|
||||||
speedtest.net operated servers
|
speedtest.net operated servers
|
||||||
|
--use_interface_counters USE_INTERFACE_COUNTERS
|
||||||
|
Use the kernel counters for the specified network
|
||||||
|
interface to calculate the total number of bytes
|
||||||
|
transmitted/received (Linux only).
|
||||||
|
--version Show the version number and exit
|
||||||
--version Show the version number and exit
|
--version Show the version number and exit
|
||||||
|
|
||||||
Inconsistency
|
Inconsistency
|
||||||
|
|
|
@ -58,6 +58,15 @@ URL of the Speedtest Mini server
|
||||||
Source IP address to bind to
|
Source IP address to bind to
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
\fB\-\-use_interface_counters INTF\fR
|
||||||
|
.RS
|
||||||
|
With this option the program uses the kernel counters for interface
|
||||||
|
"intf" to calculate the number of bytes transferred. This option is
|
||||||
|
useful when running this program on a computer that is the gateway
|
||||||
|
to the Internet, as it will include the bandwidth used by every user
|
||||||
|
of the system and thus provide more accurate bandwidth figures.
|
||||||
|
.RE
|
||||||
|
|
||||||
\fB\-\-version\fR
|
\fB\-\-version\fR
|
||||||
.RS
|
.RS
|
||||||
Show the version number and exit
|
Show the version number and exit
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import os.path
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import math
|
import math
|
||||||
|
@ -233,6 +234,28 @@ def catch_request(request):
|
||||||
return None, e
|
return None, e
|
||||||
|
|
||||||
|
|
||||||
|
def get_interface_counter(intf, counter):
|
||||||
|
"""Retrieve a specific interface counter for interface 'intf'.
|
||||||
|
This requires a mounted /sys filesystem and is linux specific.
|
||||||
|
Will raise IOError if the /sys file cannot be opened."""
|
||||||
|
|
||||||
|
sysfile = os.path.join('/sys/class/net', intf, 'statistics', counter)
|
||||||
|
fd = open(sysfile)
|
||||||
|
val = int(fd.readline().rstrip())
|
||||||
|
fd.close()
|
||||||
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
def counter_diff(start, end):
|
||||||
|
"""Returns the difference between end and start, considering counter
|
||||||
|
wrap-arounds. Values are assumed to wrap at 64-bit boundaries."""
|
||||||
|
|
||||||
|
if end > start:
|
||||||
|
return end - start
|
||||||
|
else:
|
||||||
|
return ((2**64) - start) + end
|
||||||
|
|
||||||
|
|
||||||
class FileGetter(threading.Thread):
|
class FileGetter(threading.Thread):
|
||||||
"""Thread class for retrieving a URL"""
|
"""Thread class for retrieving a URL"""
|
||||||
|
|
||||||
|
@ -257,11 +280,14 @@ class FileGetter(threading.Thread):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def downloadSpeed(files, quiet=False):
|
def downloadSpeed(files, quiet=False, net_interface=None):
|
||||||
"""Function to launch FileGetter threads and calculate download speeds"""
|
"""Function to launch FileGetter threads and calculate download speeds"""
|
||||||
|
|
||||||
start = timeit.default_timer()
|
start = timeit.default_timer()
|
||||||
|
|
||||||
|
if net_interface:
|
||||||
|
start_bytes = get_interface_counter(net_interface, 'rx_bytes')
|
||||||
|
|
||||||
def producer(q, files):
|
def producer(q, files):
|
||||||
for file in files:
|
for file in files:
|
||||||
thread = FileGetter(file, start)
|
thread = FileGetter(file, start)
|
||||||
|
@ -291,7 +317,17 @@ def downloadSpeed(files, quiet=False):
|
||||||
prod_thread.join(timeout=0.1)
|
prod_thread.join(timeout=0.1)
|
||||||
while cons_thread.isAlive():
|
while cons_thread.isAlive():
|
||||||
cons_thread.join(timeout=0.1)
|
cons_thread.join(timeout=0.1)
|
||||||
return (sum(finished) / (timeit.default_timer() - start))
|
|
||||||
|
elapsed = timeit.default_timer() - start
|
||||||
|
|
||||||
|
# If 'net_interface' is set, calculate the total bytes received
|
||||||
|
# based on the interface counters. Otherwise, use the total
|
||||||
|
# number of bytes in 'finished'.
|
||||||
|
if net_interface:
|
||||||
|
end_bytes = get_interface_counter(net_interface, 'rx_bytes')
|
||||||
|
return counter_diff(start_bytes, end_bytes) / elapsed
|
||||||
|
else:
|
||||||
|
return sum(finished) / elapsed
|
||||||
|
|
||||||
|
|
||||||
class FilePutter(threading.Thread):
|
class FilePutter(threading.Thread):
|
||||||
|
@ -322,11 +358,14 @@ class FilePutter(threading.Thread):
|
||||||
self.result = 0
|
self.result = 0
|
||||||
|
|
||||||
|
|
||||||
def uploadSpeed(url, sizes, quiet=False):
|
def uploadSpeed(url, sizes, quiet=False, net_interface=None):
|
||||||
"""Function to launch FilePutter threads and calculate upload speeds"""
|
"""Function to launch FilePutter threads and calculate upload speeds"""
|
||||||
|
|
||||||
start = timeit.default_timer()
|
start = timeit.default_timer()
|
||||||
|
|
||||||
|
if net_interface:
|
||||||
|
start_bytes = get_interface_counter(net_interface, 'tx_bytes')
|
||||||
|
|
||||||
def producer(q, sizes):
|
def producer(q, sizes):
|
||||||
for size in sizes:
|
for size in sizes:
|
||||||
thread = FilePutter(url, start, size)
|
thread = FilePutter(url, start, size)
|
||||||
|
@ -356,7 +395,17 @@ def uploadSpeed(url, sizes, quiet=False):
|
||||||
prod_thread.join(timeout=0.1)
|
prod_thread.join(timeout=0.1)
|
||||||
while cons_thread.isAlive():
|
while cons_thread.isAlive():
|
||||||
cons_thread.join(timeout=0.1)
|
cons_thread.join(timeout=0.1)
|
||||||
return (sum(finished) / (timeit.default_timer() - start))
|
|
||||||
|
elapsed = timeit.default_timer() - start
|
||||||
|
|
||||||
|
# If 'net_interface' is set, calculate the total bytes transmitted
|
||||||
|
# based on the interface counters. Otherwise, use the total
|
||||||
|
# number of bytes in 'finished'.
|
||||||
|
if net_interface:
|
||||||
|
end_bytes = get_interface_counter(net_interface, 'tx_bytes')
|
||||||
|
return counter_diff(start_bytes, end_bytes) / elapsed
|
||||||
|
else:
|
||||||
|
return sum(finished) / elapsed
|
||||||
|
|
||||||
|
|
||||||
def getAttributesByTagName(dom, tagName):
|
def getAttributesByTagName(dom, tagName):
|
||||||
|
@ -590,6 +639,11 @@ def speedtest():
|
||||||
parser.add_argument('--secure', action='store_true',
|
parser.add_argument('--secure', action='store_true',
|
||||||
help='Use HTTPS instead of HTTP when communicating '
|
help='Use HTTPS instead of HTTP when communicating '
|
||||||
'with speedtest.net operated servers')
|
'with speedtest.net operated servers')
|
||||||
|
parser.add_argument('--use_interface_counters',
|
||||||
|
help='Use the kernel counters for the specified '
|
||||||
|
'network interface to calculate the total '
|
||||||
|
'number of bytes transmitted/received '
|
||||||
|
'(Linux only).')
|
||||||
parser.add_argument('--version', action='store_true',
|
parser.add_argument('--version', action='store_true',
|
||||||
help='Show the version number and exit')
|
help='Show the version number and exit')
|
||||||
|
|
||||||
|
@ -716,7 +770,7 @@ def speedtest():
|
||||||
(os.path.dirname(best['url']), size, size))
|
(os.path.dirname(best['url']), size, size))
|
||||||
if not args.simple:
|
if not args.simple:
|
||||||
print_('Testing download speed', end='')
|
print_('Testing download speed', end='')
|
||||||
dlspeed = downloadSpeed(urls, args.simple)
|
dlspeed = downloadSpeed(urls, args.simple, args.use_interface_counters)
|
||||||
if not args.simple:
|
if not args.simple:
|
||||||
print_()
|
print_()
|
||||||
print_('Download: %0.2f M%s/s' %
|
print_('Download: %0.2f M%s/s' %
|
||||||
|
@ -729,7 +783,8 @@ def speedtest():
|
||||||
sizes.append(size)
|
sizes.append(size)
|
||||||
if not args.simple:
|
if not args.simple:
|
||||||
print_('Testing upload speed', end='')
|
print_('Testing upload speed', end='')
|
||||||
ulspeed = uploadSpeed(best['url'], sizes, args.simple)
|
ulspeed = uploadSpeed(best['url'], sizes,
|
||||||
|
args.simple, args.use_interface_counters)
|
||||||
if not args.simple:
|
if not args.simple:
|
||||||
print_()
|
print_()
|
||||||
print_('Upload: %0.2f M%s/s' %
|
print_('Upload: %0.2f M%s/s' %
|
||||||
|
|
Loading…
Reference in New Issue