summary.py 6.02 KB
Newer Older
1
2
3
4
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import time
Mario Hock's avatar
Mario Hock committed
5
import os
6
from itertools import zip_longest
Mario Hock's avatar
Mario Hock committed
7
8

from cnl_library import CNLParser
9
from split_text import split_proprtionally
10
11
12
13
14
15
16
17
18
19

## some "constants"/preferences
divisor = 1000000.0
rounding_digits = 2
unit = "MBits"


def format_timestamp(t):
    return time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime(t))

20
21
22
23
24
25
26

def sprint_bold(text):
    return "\033[1m" + text + "\033[0m"

def sprint_inverted(text):
    return "\033[7m" + text + "\033[0m"

27
def print_inverted(text, **kwargs):
28
29
30
31
32
33
34
    #print( "\033[7m" + text + "\033[0m", **kwargs )
    print( sprint_inverted(text), **kwargs )


def print_in_two_columns(format_str, left_col, right_col):
    for l, r in zip_longest(left_col, right_col, fillvalue=""):
        print( format_str.format(l, r) )
35
36


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

class LogAnalyzer:

    def __init__(self, cnl_file):
        self.cnl_file = cnl_file

        ## Get all fields to watch for activity (NIC, send and receive)
        self.nics = cnl_file.get_nics()
        self.watch_fields = list()
        nic_fields = [".send", ".receive"]
        for nic_name in self.nics:
            for nic_field in nic_fields:
                self.watch_fields.append( nic_name + nic_field )

        # important csv indices
        self.watch_indices = cnl_file.get_csv_indices_of(self.watch_fields)
        self.begin_index = cnl_file.get_csv_index_of("begin")
        self.end_index = cnl_file.get_csv_index_of("end")
Mario Hock's avatar
Mario Hock committed
55
        self.duration_index = cnl_file.get_csv_index_of("duration")
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75


        ## Result variables
        self.experiment_start_time = None
        self.experiment_end_time = None
        self.recording_start_time = None
        self.recording_end_time = None

        self.sums = [0.0] * len(self.watch_fields)


    def _is_activity(self, line):
        for field_name in self.watch_indices:
            if ( float( line[field_name] ) > 0 ):
                return True

        return False

    def _sum_line(self, line):
        for i in range( len(self.sums) ):
Mario Hock's avatar
Mario Hock committed
76
            self.sums[i] += line[ self.watch_indices[i] ] * line[self.duration_index]
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106



    def _get_begin(self, line):
        return line[self.begin_index]

    def _get_end(self, line):
        return line[self.end_index]


    def summarize(self):

        for line in self.cnl_file.get_csv_iterator():
            ## on active samples
            if ( self._is_activity(line) ):

                # Find begin of the experiment.
                if ( not self.experiment_start_time ):
                    self.experiment_start_time = self._get_begin(line)

                # Find end of the experiment.
                self.experiment_end_time = self._get_end(line)

            ## Sum watched columns.
            self._sum_line(line)


        self.experiment_duration = self.experiment_end_time - self.experiment_start_time


Mario Hock's avatar
Mario Hock committed
107

108
    def show(self):
Mario Hock's avatar
Mario Hock committed
109
110
111
112
113
114
115
        print("=== Summary ===")
        #print( "Filename: " + os.path.relpath(self.cnl_file.filename) )
        form_str = "{:<10} {}"
        print( form_str.format("Filename:", os.path.basename(self.cnl_file.filename)) )
        print( form_str.format("Comment:", self.cnl_file.get_comment()) )
        print( form_str.format("Hostname:", self.cnl_file.get_sysinfo()["hostname"]) )
        print( form_str.format("Kernel:", self.cnl_file.get_sysinfo()["kernel"]) )
116
117
        print()

Mario Hock's avatar
Mario Hock committed
118
119
120
        print( form_str.format( "Start:", format_timestamp(self.experiment_start_time) ) )
        print( form_str.format( "End:", format_timestamp(self.experiment_end_time) ) )
        print( form_str.format( "Duration:", round(self.experiment_duration) ) )
121
122
        print()

Mario Hock's avatar
Mario Hock committed
123
124
        print( "CPUs: " + ", ".join(self.cnl_file.get_cpus()) )
        print( "NICs: " + ", ".join(self.cnl_file.get_nics()) )
125
126
127
        print()

        # Show average transmission rates.
Mario Hock's avatar
Mario Hock committed
128
        print("== Average transmission rates ==")
129
130
        for i in range( len(self.sums) ):
            speed = round(self.sums[i] / divisor / self.experiment_duration, rounding_digits)
Mario Hock's avatar
Mario Hock committed
131
            print( "{:<13} {:>10} {}/s".format(self.watch_fields[i]+":", speed, unit) )
132
133


Mario Hock's avatar
Mario Hock committed
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    def show_brief(self):
        speeds = list()
        for i in range( len(self.sums) ):
            speed = "{:.2f}".format( round(self.sums[i] / divisor / self.experiment_duration, rounding_digits) )
            speeds.append( "{:>8} {}/s".format(speed, unit) )

        speeds_str = " ".join(speeds)
        filename = os.path.basename(self.cnl_file.filename)
        comments = self.cnl_file.get_comment().split(";")

        print( "{:<32} {}".format( filename + ":", speeds_str) )
        for comment in comments:
            print( "{:<32} {}".format( "", comment.strip()) )



150
151
152
153
    def visualize_brief(self):
        filename = os.path.basename(self.cnl_file.filename)
        comments = self.cnl_file.get_comment().split(";")

154
155
156
157
158
        left_col = list()
        right_col = list()

        #left_col.append( sprint_bold(filename + ":") )
        left_col.append( filename + ":" )
159
        for comment in comments:
160
            left_col.append(comment.strip()[:48])
161
162
163
164
165
166


        speeds = list()
        for i in range( len(self.sums) ):
            speed = self.sums[i] / self.experiment_duration

167
168
169
170
171
172
173
174
175
176
177
178
179
            number_str = "{:.2f}".format( round(speed / divisor, rounding_digits) )
            #text = "{:>10} {}/s".format(s1, unit)
            bar_str = "{:<20}".format(number_str + " " + unit + "/s")

            label = "{:<6}".format( self.nics[int(i/2)] + ":" if i%2==0 else "" )

            parts = split_proprtionally(bar_str, [speed, 1000000*10000-speed])
            text = label + "|" + sprint_inverted(parts[0]) + parts[1] + "|"

            right_col.append( text )


        print_in_two_columns("{:<50} {}", left_col, right_col )
180
181


182
183
184
185
186

## MAIN ##
if __name__ == "__main__":
    import sys

Mario Hock's avatar
Mario Hock committed
187
    filenames = sorted( sys.argv[1:] )
188

Mario Hock's avatar
Mario Hock committed
189
190
191
    for filename in filenames:
        ## * Parse input file. *
        cnl_file = CNLParser(filename)
192

Mario Hock's avatar
Mario Hock committed
193
194
        log = LogAnalyzer(cnl_file)
        log.summarize()
195

Mario Hock's avatar
Mario Hock committed
196
        if ( len(filenames) > 1 ):
197
198
            #log.show_brief()
            log.visualize_brief()
Mario Hock's avatar
Mario Hock committed
199
200
201
            print()
        else:
            log.show()