#!/usr/bin/env python # #Copyright (c) 2009, Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #******************************************************************************* # #Author: Stephen Moon # #Summary: A stand alone version of the track_parse_module.py import re, sys, os, stat class CMD_Dict(dict): def __init__(self, *arg, **kw): super(CMD_Dict, self).__init__(*arg, **kw) self.CMD = {} self.db_name = {} self.param = {} self.stat_array = [] def readFile(self, file_name, cmd): db = re.compile(r'^---\s(db\.\w+)\s+$') lapse = re.compile(r'^---\s(lapse)\s(\S+)$') usage = re.compile(r'^---\s(usage)\s(.+)$') rpc = re.compile(r'^---\s(rpc)\s(.+)$') param = re.compile(r'^---\s+(\w+)\s(.+)$') db_name = '' f = open(file_name, 'r') for each_line in f.readlines(): m_db = db.match(each_line) m_lapse = lapse.match(each_line) m_usage = usage.match(each_line) m_rpc = rpc.match(each_line) if m_lapse is not None: pass elif m_usage is not None: pass elif m_rpc is not None: pass elif m_db is not None: db_name = m_db.group(1) elif each_line != '': m_param = param.match(each_line) if m_param is not None: param_stat = db_name + "#" + m_param.group(1) stat_array = m_param.group(2).split(' ') if param_stat.split('#')[1] == 'pages': #print stat_array[0] self.param[param_stat + '_' + stat_array[0]] = self.stat_pages('pages', stat_array) #params and its stats elif param_stat.split('#')[1] == 'locks': self.param[param_stat] = self.stat_locks('locks', stat_array) #params and its stats elif param_stat.split('#')[1] == 'total': self.param[param_stat] = self.stat_max_total_locks('total', stat_array) #params and its stats elif param_stat.split('#')[1] == 'max': self.param[param_stat] = self.stat_max_total_locks('max', stat_array) #params and its stats self.db_name[db_name] = self.param #different params for each table self.CMD[cmd] = self.db_name #top dict contains the db names f.close() def stat_pages(self, param_name, stats): pages = {} if stats[0] == 'in+out+cached': #pages in+out+caches 277+711+96, stats[0] == in+out+caches pages = { param_name + '_' + page_io:num_page_io for page_io, num_page_io in zip(stats[0].split('+'), stats[1].split('+')) } elif stats[0] == 'split': #pages split internal+leaf 2+0, stats[0] == split pages = { param_name + '_' + stats[0] + '_' + page_split:num_page_split for page_split, num_page_split in zip(stats[1].split('+'), stats[2].split('+')) } elif stats[0] == 'reordered': #pages reordered internal+leaf 2+0, stats[0] == split pages = { param_name + '_' + stats[0] + '_' + page_reordered:num_page_reordered for page_reordered, num_page_reordered in zip(stats[1].split('+'), stats[2].split('+')) } return pages def stat_locks(self, param_name, stats): #locks read/write 1/64 rows get+pos+scan put+del 0+1+1 6400+0, stats[0] == read/write locks_acq = { read_write + '_' + param_name : num_locks for read_write, num_locks in zip(stats[0].split('/'), stats[1].split('/')) } locked_rows = { param_name + '_' + stats[2] + '_' + rows_scan: num_rows for rows_scan, num_rows in zip(stats[3].split('+'), stats[5].split('+')) } locked_rows_io = { param_name + '_' + stats[2] + '_' + rows_io: num_rows for rows_io, num_rows in zip(stats[4].split('+'), stats[6].split('+')) } return dict(locks_acq.items() + locked_rows.items() + locked_rows_io.items()) def stat_max_total_locks(self, param_name, stats): #total lock wait+held read/write 0mx+0ms/0ms+34ms, stats[0] == lock # max lock wait+held read/write 0mx+0ms/0ms+34ms, stats[0] == lock if param_name == 'total': total_read_lock = { param_name + '_' + stats[2].split('/')[0] + '_' + stats[0] + '_' + wait_held : time_wait_held for wait_held, time_wait_held in zip(stats[1].split('+'), stats[3].split('/')[0].split('+'))} total_write_lock = { param_name + '_' + stats[2].split('/')[1] + '_' + stats[0] + '_' + wait_held : time_wait_held for wait_held, time_wait_held in zip(stats[1].split('+'), stats[3].split('/')[1].split('+'))} return dict(total_read_lock.items() + total_write_lock.items()) elif param_name == 'max': max_read_lock = { param_name + '_' + stats[2].split('/')[0] + '_' + stats[0] + '_' + wait_held : time_wait_held for wait_held, time_wait_held in zip(stats[1].split('+'), stats[3].split('/')[0].split('+'))} max_write_lock = { param_name + '_' + stats[2].split('/')[1] + '_' + stats[0] + '_' + wait_held : time_wait_held for wait_held, time_wait_held in zip(stats[1].split('+'), stats[3].split('/')[1].split('+'))} return dict(max_read_lock.items() + max_write_lock.items()) def main(): if len(sys.argv) != 2: print("Usage: {0} ".format(sys.argv[0])) sys.exit(1) file_name = sys.argv[1] c = CMD_Dict() for each_cmd in ['sync',]: c.readFile(file_name, each_cmd) for cmd in c.CMD: for db_name in c.CMD[cmd]: for param, details in c.CMD[cmd][db_name].iteritems(): if db_name == param.split('#')[0]: for k, v in c.CMD[cmd][db_name][param].iteritems(): print("{0}:{1}:{2}:{3}:{4}".format(cmd, db_name, param.split('#')[1], k, v)) if __name__ == '__main__': main()