blob: f6745c52cc8b945a68e22bc91316215c82b0a2a8 [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Monitor various interface statistics and create a histogram
This script monitors data from various debugfs sources to generate
a time series histogram of device activity. The script can be set
up to take a certain number of samples, or to run "infinitely",
printing out a report when it receives a kill signal or the sample
count is acquired.
"""
import glob
import optparse
import re
import sys
import time
import signal
class SampleReader(object):
def __init__(self):
self.last_attributes = self.GetAttributes()
self.data = []
def GetDelta(self):
attributes = self.GetAttributes()
deltas = {}
for attr in attributes:
deltas[attr] = attributes[attr] - self.last_attributes[attr]
self.last_attributes = attributes
self.data.append(deltas)
def Summarize(self):
for attr in sorted(self.last_attributes.keys()):
lineparts = [attr]
for datum in self.data:
lineparts.append(str(datum[attr]))
print ','.join(lineparts)
class Ath9kSamplesReader(SampleReader):
def __init__(self):
dirs = glob.glob('/sys/kernel/debug/ieee80211/*/ath9k')
self.dir = dirs[0] if len(dirs) > 0 else None
self.files = {
'recv': {
'rx_crc': re.compile(' *CRC ERR : *(\d+)'),
'rx_decrypt_crc_err': re.compile(' *DECRYPT CRC ERR : *(\d+)'),
'rx_phy_err': re.compile(' *PHY ERR : *(\d+)'),
'rx_pkts': re.compile(' *RX-Pkts-All : *(\d+)'),
'rx_bytes': re.compile(' *RX-Bytes-All : *(\d+)'),
},
'xmit': {
'tx_pkts': re.compile(
' *TX-Pkts-All: *(\d+) *(\d+) *(\d+) *(\d+)'),
'tx_bytes': re.compile(
' *TX-Bytes-All: *(\d+) *(\d+) *(\d+) *(\d+)'),
}
}
SampleReader.__init__(self)
def IsValid(self):
return bool(self.dir)
def GetAttributes(self):
if not self.dir:
return
attrs = {}
for filename, re_hash in self.files.iteritems():
for line in file('%s/%s' % (self.dir, filename)):
for key, exp in re_hash.iteritems():
match = exp.match(line)
if match:
attrs[key] = sum(map(int, match.groups()))
return attrs
# Used for testing
class DummyReader(SampleReader):
def __init__(self):
self.x = 1
self.y = 1
SampleReader.__init__(self)
def IsValid(self):
return True
def GetAttributes(self):
self.x += 1
self.y *= 2
return {'x': self.x, 'y': self.y}
class SigHandler(object):
def __init__(self, reader):
self.reader = reader
self.printed = False
def trigger(self, signum, frame):
self.reader.Summarize()
sys.exit(0)
def main(argv):
parser = optparse.OptionParser('Usage: %prog [options...]')
parser.add_option('--count', dest='count', type='int',
default=-1, help='Number of samples (-1 == infinite)')
parser.add_option('--period', dest='period', type='int',
default=5, help='Period (in seconds) between samples')
(options, args) = parser.parse_args(argv[1:])
reader = None
for reader_class in [Ath9kSamplesReader]:
test_reader = reader_class()
if test_reader.IsValid():
reader = test_reader
break
if not reader:
print>>sys.stderr, 'No devices available for statistics capture'
return
signal.signal(signal.SIGINT, SigHandler(reader).trigger)
signal.signal(signal.SIGTERM, SigHandler(reader).trigger)
count = options.count
while count != 0:
time.sleep(options.period)
reader.GetDelta()
count -= 1
reader.Summarize()
if __name__ == '__main__':
main(sys.argv)