📄 np_sperf.py
字号:
#! /usr/bin/env python################################################################################ ## Copyright 2005 University of Cambridge Computer Laboratory. ## ## This file is part of Nprobe. ## ## Nprobe is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## Nprobe is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Nprobe; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ################################################################################################################################################################ #### ## #### ############################################################################ import stringimport globimport osimport sysimport nprobefrom sys import argvimport getoptfrom signal import *import Numeric## import np_file_util## import np_http_util## from np_obnode import *## from np_longutil import *## from np_tfilter import *## #from np_plot import *## #from np_plot import DataSet, DATA_TS, EmptyDataSetError## import np_plotimport np_file_utilimport np_http_utilimport np_ns_utilsfrom np_obnode import *#from np_draw_obtree import *from np_TCP_Window import *from np_longutil import *from np_lookups import *from np_tfilter import *from np_TCP import *from TCP_Imp import *from np_atypes import Atypefrom Tkinter import *from np_widgets import *from np_notesel import *########################################################################################################################################################EV_CONN_SOUGHT = 0EV_CONN_RESP = 1EV_OB_REQ = 2EV_OB_START = 3EV_OB_SERVED = 4EV_CONN_CLOSE = 5EV_DUP_SYN = 6EV_RTMTS = 7P_DS = 8P_RTMT = 9########################################################################################################################################################def usage(scriptname): print "usage: " + scriptname + '<-p/P(eriod s)>' + " <rep-file-list>" print '\t-p -- aggregate as occurences per specified aggregation period' print '\t-P -- aggregate as occurences per second over aggregation period' sys.exit(1)############################################################################### Aggregate cl list of connections wanteddef get_conns_wanted(s): connids = [] for f in string.splitfields(s, ','): #print f #print '%d' % (string.atoi(f)) connids.append(string.atoi(f)) return connids#############################################################################def handle_sigint(n, f): global logf print 'SIGINT' try: cache_lookups() if logf != None: logf.flush() except: sys.exit(0)############################################################################# def main(): scriptname = 'np_sperf.py' nrecs = 0 startconn = 0 oneconn = None connstr = '' fspec = 0 per = 1.0 per_sec = 0 try: optlist, args = getopt.getopt(sys.argv[1:], 'hvr:s:c:F:T:p:P:') except getopt.error, s: print scriptname + ": " + s usage(scriptname) sys.exit(1)## print args## if len(args) != 1:## print 'foo'## usage(scriptname) tfilt = TFilter() optstr = '' for opt in optlist: if opt[0] == "-h": usage(scriptname) if opt[0] == "-p": per = string.atof(opt[1]) optstr = optstr + '-p' + opt[1] if opt[0] == "-P": per = string.atof(opt[1]) optstr = optstr + '-P' + opt[1] per_sec = 1 if opt[0] == "-v": nprobe.set_print_full_hostname(1) if opt[0] == "-r": nrecs = string.atoi(opt[1]) optstr = optstr + '-r' + opt[1] if opt[0] == "-s": startconn = string.atoi(opt[1]) optstr = optstr + '-s' + opt[1] if opt[0] == "-c": oneconn = get_conns_wanted(opt[1]) optstr = optstr + '-c' + opt[1] print 'analysing only connection(s) ', print oneconn if opt[0] == "-F": print 'foo' if opt[1] == 'h' or opt[1] == 'H': nprobe.filter_help() sys.exit(0) fspec = string.atoi(opt[1]) optstr = optstr + '-F' + opt[1] if opt[0] == "-T": if opt[1] == 'h' or opt[1] == 'H': tfilt.help() sys.exit(0) tfilt.build_filters(opt[1]) optstr = optstr + '-T' + opt[1] if per == 1.0: print 'No aggregation period specified - defaulting to %.3fs' % (per) signal(SIGINT, handle_sigint) openfilelist, counters, basepath = np_file_util.get_files(args) #counters.printself("") filepath = basepath + 'counters' counters.printself_tofile(filepath, '') basepath = basepath + optstr## ### # Dictionary of tcp connections keyed by conn_id ## # - initially used to collect headers, then to reference connections## ### conn_ids = {} # # event lists # evlist = [] nconns = 0 nconns_accepted = 0 # rejected by id filter id_rej = 0 # rejected by connection filter cf_rej = 0 # only one way seen one_ways = 0 nread = 0 ntrans = 0 servtrans_bad = 0 clitrans_bad = 0 for file in openfilelist: if len(openfilelist) > 1: print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" print "File %s - %d records" % (file.fnm, file.counters.nrecords) print sys.stdout.flush() while 1: if nrecs and nread > nrecs: break nread += 1 rectype = file.next_type_rec(REC_TCP_HTTP) if rectype == -1: #EOF break elif rectype & OPEN_BIT: # notification of TCP open file.advance() continue elif rectype & HDRS_BIT: # a block of hdrs file.advance() continue elif rectype == REC_TCP_HTTP: #TCP/HTTP #read the lot indx, connrec, translist = np_http_util.get_http_rec(file) else: # any other TCP close record # get tconn record and its data connrec = nprobe.tcp_conn() connrec.get_conn(file) print 'X?X?X?' file.advance() continue # Have now got an HTTP close record - is it one we want? # get the conn_id conn_id = connrec.get_conn_id() flow = connrec.flow_inner nconns += 1 if oneconn != None: if not oneconn.count(conn_id): id_rej += 1 continue elif id < startconn: continue elif not nprobe.accept_conn(flow, fspec): cf_rej += 1 continue elif not tfilt.pss(connrec, translist): #evlist.append((ull2l(connrec.open()) + ul2l(connrec.clisyn()), EV_RTMTS)) continue # only want where both directions seen if not (connrec.server_seen() and connrec.client_seen()): one_ways += 1 continue if not connrec.no_rtmts_or_gaps(): evlist.append((ull2l(connrec.open()), EV_RTMTS)) #continue # # Now do what we're here for # nconns_accepted += 1 open_us = ull2l(connrec.open()) clisyn_us = ul2l(connrec.clisyn()) + open_us clisynack_us = ul2l(connrec.cliacksyn()) + open_us close_us = ull2l(connrec.close()) evlist.append((clisyn_us, EV_CONN_SOUGHT)) evlist.append((clisynack_us, EV_CONN_RESP)) evlist.append((close_us, EV_CONN_CLOSE)) for t in translist: ntrans += 1 if t.http_serv_nogood(): servtrans_bad += 1 break if t.http_cli_nogood(): clitrans_bad += 1 break reqstart_us = ul2l(t.http_reqstart_us()) + open_us repstart_us = ul2l(t.http_repstart_us()) + open_us repend_us = ul2l(t.http_repend_us()) + open_us evlist.append((reqstart_us, EV_OB_REQ)) evlist.append((repstart_us, EV_OB_START)) evlist.append((repend_us, EV_OB_SERVED)) if connrec.get_cflags() & TSP_DUP_SYN: #print 'dup SYN' evlist.append((clisyn_us, EV_DUP_SYN)) print 'Records read %d' % (nread) print 'Total HTTP connections %d' % (nconns) print 'Total HTTP connections accepted %d' % (nconns_accepted) print '\t%d rejected by flow id filter' % (id_rej) print '\t%d rejected by flow filter' % (cf_rej) print '\tRejected by tfilter:' tfilt.report() print print '%d Transactions' % (ntrans) print '\t%d client invalid %d server invalid' % (clitrans_bad, servtrans_bad) buckets = [0, 0, 0, 0, 0, 0, 0, 0] aggs = [[], [], [], [], [], [], [], [], [], []] # calculation granularity in us #TIME_GRAN = 100000 # = 100ms TIME_GRAN = per*1000000 # time stamp precision TIME_PREC = 1000000.0 # = 1us # rate factor if per_sec: RATE_FACT = TIME_PREC/TIME_GRAN else: RATE_FACT = 1 evlist.sort() tbase = evlist[0][0] tm = TIME_GRAN last_tm = 0 dlen = 1 for e in evlist: us = long(e[0] - tbase) ev = e[1] #print 'tm %.6f ev %d' % (us/1000000.0, e[1]) #print tm, #print us if us > tm: # end of aggregation period while last_tm < tm: # zero any missing intervals for agg in range(len(buckets)): aggs[agg].append([last_tm/TIME_PREC, 0, agg, []]) aggs[P_DS].append([tm/TIME_PREC, 0.0, P_DS, []]) aggs[P_RTMT].append([tm/TIME_PREC, 0.0, P_RTMT, []]) last_tm = last_tm + TIME_GRAN last_tm = last_tm + TIME_GRAN # save values for this period if buckets[EV_CONN_SOUGHT]: p_ds = float(buckets[EV_DUP_SYN])/buckets[EV_CONN_SOUGHT] p_rtmt = float(buckets[EV_RTMTS])/buckets[EV_CONN_SOUGHT] else: p_ds = 0.0 p_rtmt = 0.0 aggs[P_DS].append([tm/TIME_PREC, p_ds, P_DS, []]) aggs[P_RTMT].append([tm/TIME_PREC, p_rtmt, P_RTMT, []]) for agg in range(len(buckets)): aggs[agg].append([tm/TIME_PREC, buckets[agg]*RATE_FACT, agg, []]) buckets[agg] = 0 tm = ((us/TIME_GRAN)+1)*TIME_GRAN # record this event buckets[ev] += 1 while last_tm < tm: aggs[P_DS].append([tm/TIME_PREC, 0.0, P_DS, []]) aggs[P_RTMT].append([tm/TIME_PREC, 0.0, P_RTMT, []]) for agg in range(len(buckets)): aggs[agg].append([last_tm/TIME_PREC, 0, agg, []]) last_tm = last_tm + TIME_GRAN aggs[P_DS].append([tm/TIME_PREC, 0.0, P_DS, []]) aggs[P_RTMT].append([tm/TIME_PREC, 0.0, P_RTMT, []]) for agg in range(len(buckets)): aggs[agg].append([tm/TIME_PREC, buckets[agg]*RATE_FACT, agg, []]) ## # calculate proportion of conns per period with dup SYNs or rtmts## p_ds = []## p_rtmt = []## for i in range(len(aggs[EV_CONN_SOUGHT])): sets = [] sets.append(DataSet(aggs[EV_CONN_SOUGHT], DATA_TS, 'Connection attempts', 0, None)) ## sets.append(DataSet(aggs[EV_CONN_RESP], DATA_TS,## 'Connections made', 1, None))## sets.append(DataSet(aggs[EV_OB_REQ], DATA_TS,## 'Requests', 2, None))## sets.append(DataSet(aggs[EV_OB_START], DATA_TS,## 'Responses', 3, None))## sets.append(DataSet(aggs[EV_OB_SERVED], DATA_TS,## 'Responses completed', 4, None))## sets.append(DataSet(aggs[EV_CONN_CLOSE], DATA_TS, 'Connections closed', 5, None)) sets.append(DataSet(aggs[EV_DUP_SYN], DATA_TS, 'Duplicate SYNs', 6, None)) sets.append(DataSet(aggs[EV_RTMTS], DATA_TS, 'Data RTMTs', 7, None)) sets.append(DataSet(aggs[P_DS], DATA_TS, 'P Duplicate SYNs', 8, None)) sets.append(DataSet(aggs[P_RTMT], DATA_TS, 'P Data RTMTs', 9, None)) if per_sec: rf_str = 's' elif TIME_GRAN < 1000: rf_str = '%dus' % (TIME_GRAN) elif 1000 <= TIME_GRAN <= 1000000: rf_str = '%dms' % (TIME_GRAN/1000) else: rf_str = '%ds' % (TIME_GRAN/1000000) ylabstr = 'No/%s' % (rf_str) try: np_Plot(sets, standalone='yes', path=basepath, title='Server load', xlab='time s', ylab=ylabstr) except EmptyDataSetError: print '%s - empty data set' % (ds.path) sys.exit(1) ############################################################################### Call main when run as scriptif __name__ == '__main__': main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -