Skip to content
This repository was archived by the owner on Jan 10, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion sar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
"""I/O usage part of SAR file"""
PART_IO = 3

"""IFACE usage part of SAR file"""
PART_IFACE = 4

"""CPU regexp pattern for detecting SAR section header"""
PATTERN_CPU = ".*CPU.*(usr|user).*nice.*sys.*"

Expand Down Expand Up @@ -71,6 +74,23 @@

}

"""IFACE pattern for detecting the IFACE section"""
#10:18:01 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
PATTERN_IFACE = ".*IFACE.*rxpck\/s.*txpck\/s.*rxkB\/s.*txkB\/s.*rxcmp\/s.*txcmp\/s.*rxmcst\/s.*"

"""Regexp terms for finding fields in SAR parts for IFACE"""
FIELDS_IFACE = [
'rxpck\/s', 'txpck\/s','rxkB\/s','txkB\/s','rxcmp/s','txcmp\/s','rxmcst\/s'
]

"""Pair regexp terms with field names in IFACE output dictionary"""
FIELD_PAIRS_IFACE = {

"rxpcks":FIELDS_IFACE[0], "txpcks":FIELDS_IFACE[1], 'rxkbs':FIELDS_IFACE[2],
'txkbs':FIELDS_IFACE[3], 'rxcmps':FIELDS_IFACE[4], 'txcmps':FIELDS_IFACE[5],
'rxmcsts':FIELDS_IFACE[6]
}

"""Restart time regexp pattern for detecting SAR restart notices"""
PATTERN_RESTART = ".*LINUX\ RESTART.*"

Expand All @@ -83,5 +103,5 @@
__all__ = [
"PART_CPU", "PART_MEM", "PART_SWP", "PART_IO",
"PATTERN_CPU", "PATTERN_MEM", "PATTERN_SWP", "PATTERN_IO",
"PATTERN_RESTART", "PATTERN_MULTISPLIT", "PATTERN_DATE"
"PATTERN_RESTART", "PATTERN_MULTISPLIT", "PATTERN_DATE","PATTERN_IFACE"
]
6 changes: 4 additions & 2 deletions sar/multiparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,21 @@ def load_file(self):
chunk = self.__get_chunk(start, end)

parser = sarparse.Parser()
cpu_usage, mem_usage, swp_usage, io_usage = \
cpu_usage, mem_usage, swp_usage, io_usage,iface_usage = \
parser._parse_file(parser._split_file(chunk))

self.__sarinfos[self.__get_part_date(chunk)] = {
"cpu": cpu_usage,
"mem": mem_usage,
"swap": swp_usage,
"io": io_usage
"io": io_usage,
"iface":iface_usage
}
del(cpu_usage)
del(mem_usage)
del(swp_usage)
del(io_usage)
del(iface_usage)
del(parser)

return(True)
Expand Down
61 changes: 53 additions & 8 deletions sar/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
Parses SAR ASCII output only, not binary files!
'''

from sar import PART_CPU, PART_MEM, PART_SWP, PART_IO, \
from __init__ import PART_CPU, PART_MEM, PART_SWP, PART_IO,PART_IFACE, \
PATTERN_CPU, PATTERN_MEM, PATTERN_SWP, PATTERN_IO, PATTERN_RESTART, \
PATTERN_IFACE,\
FIELDS_CPU, FIELD_PAIRS_CPU, FIELDS_MEM, FIELD_PAIRS_MEM, FIELDS_SWP, \
FIELD_PAIRS_SWP, FIELDS_IO, FIELD_PAIRS_IO
FIELD_PAIRS_SWP, FIELDS_IO, FIELD_PAIRS_IO,FIELDS_IFACE,FIELD_PAIRS_IFACE
import mmap
import os
import re
Expand Down Expand Up @@ -46,6 +47,8 @@ def __init__(self, filename=''):
self.__io_fields = None
'''I/O usage indexes'''

self.__iface_fields = None

return None

def load_file(self):
Expand All @@ -57,11 +60,12 @@ def load_file(self):

# We first split file into pieces
searchunks = self._split_file()
# print len(searchunks)

if (searchunks):

# And then we parse pieces into meaningful data
cpu_usage, mem_usage, swp_usage, io_usage = \
cpu_usage, mem_usage, swp_usage, io_usage, iface_usage = \
self._parse_file(searchunks)

if (cpu_usage is False):
Expand All @@ -71,12 +75,14 @@ def load_file(self):
"cpu": cpu_usage,
"mem": mem_usage,
"swap": swp_usage,
"io": io_usage
"io": io_usage,
"iface":iface_usage
}
del(cpu_usage)
del(mem_usage)
del(swp_usage)
del(io_usage)
del(iface_usage)

return True

Expand Down Expand Up @@ -128,7 +134,6 @@ def _split_file(self, data=''):
the type of info they contain (SAR file sections) without
parsing what is exactly what at this point
'''

# Filename passed checks through __init__
if ((self.__filename and os.access(self.__filename, os.R_OK))
or data != ''):
Expand Down Expand Up @@ -246,6 +251,7 @@ def _parse_file(self, sar_parts):
mem_usage = ''
swp_usage = ''
io_usage = ''
iface_usage = ''

# If sar_parts is a list
if (type(sar_parts) is ListType):
Expand All @@ -255,6 +261,7 @@ def _parse_file(self, sar_parts):
mem_pattern = re.compile(PATTERN_MEM)
swp_pattern = re.compile(PATTERN_SWP)
io_pattern = re.compile(PATTERN_IO)
iface_pattern = re.compile(PATTERN_IFACE)
restart_pattern = re.compile(PATTERN_RESTART)

''' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! '''
Expand Down Expand Up @@ -329,21 +336,39 @@ def _parse_file(self, sar_parts):
self.__restart_times.append(pieces[0])
del(pieces)

if (iface_pattern.search(part)):
if (iface_usage == ''):
iface_usage = part
try:
first_line = part.split("\n")[0]
except IndexError:
first_line = part

self.__iface_fields = \
self.__find_column(FIELDS_IFACE, first_line)

else:
iface_usage += "\n" + part


del(sar_parts)

# Now we have parts pulled out and combined, do further
# processing.
cpu_output = self.__split_info(cpu_usage, PART_CPU)

mem_output = self.__split_info(mem_usage, PART_MEM)
swp_output = self.__split_info(swp_usage, PART_SWP)
io_output = self.__split_info(io_usage, PART_IO)
iface_output = self.__split_info(iface_usage,PART_IFACE)

del(cpu_usage)
del(mem_usage)
del(swp_usage)
del(io_usage)
del(iface_usage)

return (cpu_output, mem_output, swp_output, io_output)
return (cpu_output, mem_output, swp_output, io_output,iface_output)

return (False, False, False)

Expand Down Expand Up @@ -403,12 +428,13 @@ def __split_info(self, info_part, part_type=PART_CPU):
pattern = PATTERN_SWP
elif (part_type == PART_IO):
pattern = PATTERN_IO
elif(part_type == PART_IFACE):
pattern = PATTERN_IFACE

if (pattern == ''):
return False

return_dict = {}

pattern_re = re.compile(pattern)

for part_line in info_part.split("\n"):
Expand Down Expand Up @@ -477,10 +503,17 @@ def __split_info(self, info_part, part_type=PART_CPU):
elif part_type == PART_IO:
fields = self.__io_fields
pairs = FIELD_PAIRS_IO
elif part_type == PART_IFACE:
fields = self.__iface_fields
pairs = FIELD_PAIRS_IFACE

for sectionname in pairs.iterkeys():

value = elems[fields[pairs[sectionname]]]
try :
value = elems[fields[pairs[sectionname]]]
except Exception as e:
if sectionname == 'idle' and len(elems) < 12:
value = elems[-1]

if sectionname == 'membuffer' or \
sectionname == 'memcache' or \
Expand All @@ -504,6 +537,18 @@ def __split_info(self, info_part, part_type=PART_CPU):
else:
return_dict[full_time][sectionname] = value

if part_type == PART_IFACE:
cpuid = elems[(1 if is_24hr is True else 2)]
try:
blah = return_dict[full_time][cpuid]
del(blah)
except KeyError:
return_dict[full_time][cpuid] = {}
return_dict[full_time][cpuid][sectionname] = \
value
else:
return_dict[full_time][sectionname] = value

return (return_dict)

def __get_filedate(self):
Expand Down