2010-03-05 19:12:23 +01:00
#! /usr/bin/env python
2008-07-01 20:59:13 +02:00
# Copyright Arvid Norberg 2008. Use, modification and distribution is
# subject to the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2011-03-20 09:58:16 +01:00
import os , sys , time , os
2007-09-29 18:14:03 +02:00
2008-12-27 03:22:20 +01:00
stat = open ( sys . argv [ 1 ] )
line = stat . readline ( )
while not ' second: ' in line :
line = stat . readline ( )
keys = line . strip ( ) . split ( ' : ' ) [ 1 : ]
2011-03-20 09:58:16 +01:00
output_dir = ' session_stats_report '
2011-04-26 08:27:48 +02:00
def gen_report ( name , unit , lines , short_unit , generation , log_file ) :
2011-03-20 09:58:16 +01:00
try :
os . mkdir ( output_dir )
except : pass
2011-03-21 09:16:04 +01:00
filename = os . path . join ( output_dir , ' session_stats_ %s _ %04d .png ' % ( name , generation ) )
thumb = os . path . join ( output_dir , ' session_stats_ %s _ %04d _thumb.png ' % ( name , generation ) )
# don't re-render a graph unless the logfile has changed
try :
dst1 = os . stat ( filename )
dst2 = os . stat ( thumb )
src = os . stat ( log_file )
if dst1 . st_mtime > src . st_mtime and dst2 . st_mtime > src . st_mtime :
sys . stdout . write ( ' . ' )
return
except : pass
2011-03-20 22:05:49 +01:00
out = open ( ' session_stats.gnuplot ' , ' wb ' )
2008-12-27 03:22:20 +01:00
print >> out , " set term png size 1200,700 "
2011-03-21 09:16:04 +01:00
print >> out , ' set output " %s " ' % filename
2008-12-27 03:22:20 +01:00
print >> out , ' set xrange [0:*] '
print >> out , ' set xlabel " time (s) " '
2011-03-20 09:58:16 +01:00
print >> out , ' set ylabel " %s " ' % unit
2011-03-20 19:59:16 +01:00
print >> out , ' set yrange [0:*] '
2010-01-31 22:13:52 +01:00
print >> out , " set tics nomirror "
2008-12-27 03:22:20 +01:00
print >> out , " set style data lines "
print >> out , " set key box "
2011-06-21 09:44:13 +02:00
print >> out , " set format y \" %% .1s %% c %s \" ; " % short_unit
2008-12-27 03:22:20 +01:00
print >> out , ' plot ' ,
column = 2
2011-02-02 04:37:09 +01:00
first = True
2011-03-17 06:31:06 +01:00
for k in lines :
try :
column = keys . index ( k ) + 2
except :
print ' " %s " not found ' % k
continue ;
2011-02-02 04:37:09 +01:00
if not first : print >> out , ' , ' ,
2011-02-04 04:02:23 +01:00
axis = ' x1y1 '
2011-03-20 17:14:56 +01:00
print >> out , ' " %s " using 1: %d title " %s " axes %s with steps ' % ( log_file , column , k , axis ) ,
2011-02-02 04:37:09 +01:00
first = False
2008-12-27 03:22:20 +01:00
column = column + 1
2011-02-02 04:37:09 +01:00
print >> out , ' '
2011-03-20 09:58:16 +01:00
2011-03-20 22:05:49 +01:00
print >> out , " set term png size 150,100 "
2011-03-21 09:16:04 +01:00
print >> out , ' set output " %s " ' % thumb
2011-03-20 09:58:16 +01:00
print >> out , ' set key off '
print >> out , ' unset tics '
print >> out , ' set format x " " '
print >> out , ' set format y " " '
print >> out , ' set xlabel " " '
print >> out , ' set ylabel " " '
print >> out , ' set y2label " " '
2011-03-20 22:05:49 +01:00
print >> out , ' set rmargin 0 '
print >> out , ' set lmargin 0 '
print >> out , ' set tmargin 0 '
print >> out , ' set bmargin 0 '
2011-03-20 09:58:16 +01:00
print >> out , " replot "
2008-12-27 03:22:20 +01:00
out . close ( )
2011-03-20 22:05:49 +01:00
os . system ( ' gnuplot session_stats.gnuplot 2>/dev/null ' ) ;
2011-03-20 09:58:16 +01:00
sys . stdout . write ( ' . ' )
sys . stdout . flush ( )
2011-03-20 17:14:56 +01:00
def gen_html ( reports , generations ) :
2011-03-20 09:58:16 +01:00
file = open ( os . path . join ( output_dir , ' index.html ' ) , ' w+ ' )
2011-03-20 21:22:23 +01:00
css = ''' img { margin: 0}
#head { display: block }
2011-03-20 22:05:49 +01:00
#graphs { white-space:nowrap; }
2011-03-20 21:22:23 +01:00
h1 { line - height : 1 ; display : inline }
h2 { line - height : 1 ; display : inline ; font - size : 1 em ; font - weight : normal } ; '''
print >> file , ' <html><head><style type= " text/css " > %s </style></head><body> ' % css
2011-03-20 09:58:16 +01:00
for i in reports :
2011-04-26 08:27:48 +02:00
print >> file , ' <div id= " head " ><h1> %s </h1><h2> %s </h2><div><div id= " graphs " > ' % ( i [ 0 ] , i [ 3 ] )
2011-03-20 17:14:56 +01:00
for g in generations :
2011-03-20 21:22:23 +01:00
print >> file , ' <a href= " session_stats_ %s _ %04d .png " ><img src= " session_stats_ %s _ %04d _thumb.png " ></a> ' % ( i [ 0 ] , g , i [ 0 ] , g )
2011-03-20 22:05:49 +01:00
print >> file , ' </div> '
2011-03-20 09:58:16 +01:00
2011-03-20 21:22:23 +01:00
print >> file , ' </body></html> '
2011-03-20 09:58:16 +01:00
file . close ( )
reports = [
2011-04-26 08:27:48 +02:00
( ' torrents ' , ' num ' , ' ' , ' number of torrents in different torrent states ' , [ ' downloading torrents ' , ' seeding torrents ' , ' checking torrents ' , ' stopped torrents ' , ' upload-only torrents ' , ' error torrents ' ] ) ,
2011-04-27 19:36:06 +02:00
( ' peers ' , ' num ' , ' ' , ' num connected peers ' , [ ' peers ' , ' connecting peers ' , ' connection attempts ' , ' banned peers ' , ' max connections ' ] ) ,
2011-04-26 08:27:48 +02:00
( ' connect_candidates ' , ' num ' , ' ' , ' number of peers we know of that we can connect to ' , [ ' connect candidates ' ] ) ,
( ' peers_list_size ' , ' num ' , ' ' , ' number of known peers (not necessarily connected) ' , [ ' num list peers ' ] ) ,
2011-06-21 09:44:13 +02:00
( ' overall_rates ' , ' rate ' , ' B/s ' , ' download and upload rates ' , [ ' uploaded bytes ' , ' downloaded bytes ' , ' upload rate ' , ' download rate ' , ' smooth upload rate ' , ' smooth download rate ' ] ) ,
2011-04-26 08:27:48 +02:00
( ' disk_write_queue ' , ' Bytes ' , ' B ' , ' bytes queued up by peers, to be written to disk ' , [ ' disk write queued bytes ' , ' disk queue limit ' , ' disk queue low watermark ' ] ) ,
( ' peers_upload ' , ' num ' , ' ' , ' number of peers by state wrt. uploading ' , [ ' peers up interested ' , ' peers up unchoked ' , ' peers up requests ' , ' peers disk-up ' , ' peers bw-up ' , ' max unchoked ' ] ) ,
2011-06-13 18:20:21 +02:00
( ' peers_download ' , ' num ' , ' ' , ' number of peers by state wrt. downloading ' , [ ' peers down interesting ' , ' peers down unchoked ' , ' peers down requests ' , ' peers disk-down ' , ' peers bw-down ' , ' num end-game peers ' ] ) ,
2011-04-26 08:27:48 +02:00
( ' peer_errors ' , ' num ' , ' ' , ' number of peers by error that disconnected them ' , [ ' error peers ' , ' peer disconnects ' , ' peers eof ' , ' peers connection reset ' , ' connect timeouts ' , ' uninteresting peers disconnect ' , ' banned for hash failure ' ] ) ,
( ' waste ' , ' % o f all downloaded bytes ' , ' %% ' , ' proportion of all downloaded bytes that were wasted ' , [ ' % f ailed payload bytes ' , ' % wasted payload bytes ' , ' % protocol bytes ' ] ) ,
2011-06-24 05:11:39 +02:00
( ' average_disk_time_absolute ' , ' job time ' , ' s ' , ' running averages of timings of disk operations ' , [ ' disk read time ' , ' disk write time ' , ' disk hash time ' , ' disk job time ' , ' disk sort time ' ] ) ,
( ' average_disk_queue_time ' , ' job queued time ' , ' s ' , ' running averages of disk queue time ' , [ ' disk queue time ' , ' disk job time ' ] ) ,
2011-04-26 08:27:48 +02:00
( ' disk_time ' , ' % o f total disk job time ' , ' %% ' , ' proportion of time spent by the disk thread ' , [ ' % r ead time ' , ' % write time ' , ' % ha sh time ' , ' % s ort time ' ] ) ,
( ' disk_cache_hits ' , ' blocks (16kiB) ' , ' ' , ' ' , [ ' disk block read ' , ' read cache hits ' , ' disk block written ' , ' disk read back ' ] ) ,
( ' disk_cache ' , ' blocks (16kiB) ' , ' ' , ' disk cache size and usage ' , [ ' read disk cache size ' , ' disk cache size ' , ' disk buffer allocations ' , ' cache size ' ] ) ,
2011-04-27 19:36:06 +02:00
( ' disk_readback ' , ' % o f written blocks ' , ' %% ' , ' portion of written blocks that had to be read back for hash verification ' , [ ' % r ead back ' ] ) ,
2011-04-26 08:27:48 +02:00
( ' disk_queue ' , ' number of queued disk jobs ' , ' ' , ' queued disk jobs ' , [ ' disk queue size ' , ' disk read queue size ' , ' read job queue size limit ' ] ) ,
2011-07-03 19:21:45 +02:00
( ' disk_iops ' , ' operations/s ' , ' ' , ' number of disk operations per second ' , [ ' read ops/s ' , ' write ops/s ' , ' smooth read ops/s ' , ' smooth write ops/s ' ] ) ,
2011-06-21 09:44:13 +02:00
( ' mixed mode ' , ' rate ' , ' B/s ' , ' rates by transport protocol ' , [ ' TCP up rate ' , ' TCP down rate ' , ' uTP up rate ' , ' uTP down rate ' , ' TCP up limit ' , ' TCP down limit ' ] ) ,
2011-06-29 00:20:34 +02:00
( ' uTP delay ' , ' buffering delay ' , ' s ' , ' network delays measured by uTP ' , [ ' uTP peak send delay ' , ' uTP avg send delay ' ] ) ,
( ' system memory ' , ' ' , ' ' , ' virtual memory page count ' , [ ' active resident pages ' , ' inactive resident pages ' , ' pinned resident pages ' , ' free pages ' ] ) ,
( ' memory paging ' , ' ' , ' ' , ' vm disk activity ' , [ ' pageins ' , ' pageouts ' ] ) ,
( ' page faults ' , ' ' , ' ' , ' ' , [ ' page faults ' ] ) ,
2011-03-20 09:58:16 +01:00
# ('absolute_waste', 'num', '', ['failed bytes', 'redundant bytes', 'download rate']),
2008-12-27 03:22:20 +01:00
2011-03-20 09:58:16 +01:00
#somewhat uninteresting stats
2011-06-21 09:44:13 +02:00
( ' tick_rate ' , ' time between ticks ' , ' s ' , ' ' , [ ' tick interval ' , ' tick residual ' ] ) ,
2011-04-26 08:27:48 +02:00
( ' peer_dl_rates ' , ' num ' , ' ' , ' peers split into download rate buckets ' , [ ' peers down 0 ' , ' peers down 0-2 ' , ' peers down 2-5 ' , ' peers down 5-10 ' , ' peers down 50-100 ' , ' peers down 100- ' ] ) ,
( ' peer_dl_rates2 ' , ' num ' , ' ' , ' peers split into download rate buckets (only downloading peers) ' , [ ' peers down 0-2 ' , ' peers down 2-5 ' , ' peers down 5-10 ' , ' peers down 50-100 ' , ' peers down 100- ' ] ) ,
( ' peer_ul_rates ' , ' num ' , ' ' , ' peers split into upload rate buckets ' , [ ' peers up 0 ' , ' peers up 0-2 ' , ' peers up 2-5 ' , ' peers up 5-10 ' , ' peers up 50-100 ' , ' peers up 100- ' ] ) ,
( ' peer_ul_rates2 ' , ' num ' , ' ' , ' peers split into upload rate buckets (only uploading peers) ' , [ ' peers up 0-2 ' , ' peers up 2-5 ' , ' peers up 5-10 ' , ' peers up 50-100 ' , ' peers up 100- ' ] ) ,
( ' piece_picker_end_game ' , ' blocks ' , ' ' , ' ' , [ ' end game piece picker blocks ' , ' piece picker blocks ' , ' piece picks ' , ' reject piece picks ' , ' unchoke piece picks ' , ' incoming redundant piece picks ' , ' incoming piece picks ' , ' end game piece picks ' , ' snubbed piece picks ' ] ) ,
( ' piece_picker ' , ' blocks ' , ' ' , ' ' , [ ' piece picks ' , ' reject piece picks ' , ' unchoke piece picks ' , ' incoming redundant piece picks ' , ' incoming piece picks ' , ' end game piece picks ' , ' snubbed piece picks ' ] ) ,
2011-03-20 09:58:16 +01:00
]
2007-09-29 18:14:03 +02:00
2011-03-20 17:14:56 +01:00
print ' generating graphs '
log_file_path , log_file = os . path . split ( sys . argv [ 1 ] )
# count the number of log files (generations)
log_file_list = log_file . split ( ' . ' )
g = int ( log_file_list [ 1 ] )
generations = [ ]
2011-03-23 05:44:38 +01:00
while os . path . exists ( os . path . join ( log_file_path , log_file ) ) :
2011-03-20 17:14:56 +01:00
print ' [ %s ] %04d \r [ ' % ( ' ' * len ( reports ) , g ) ,
2011-04-26 08:27:48 +02:00
for i in reports : gen_report ( i [ 0 ] , i [ 1 ] , i [ 4 ] , i [ 2 ] , g , os . path . join ( log_file_path , log_file ) )
2011-03-20 17:14:56 +01:00
print ' '
generations . append ( g )
g + = 1
log_file_list [ 1 ] = ' %04d ' % g
log_file = ' . ' . join ( log_file_list )
2011-03-20 09:58:16 +01:00
print ' generating html '
2011-03-20 17:14:56 +01:00
gen_html ( reports , generations )