glusterfs

Форк
0
/
glusterfs-profiler 
817 строк · 24.1 Кб
1
#!/usr/bin/python3
2

3
#  Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com>
4
#  This file is part of GlusterFS.
5
#
6
#  This file is licensed to you under your choice of the GNU Lesser
7
#  General Public License, version 3 or any later version (LGPLv3 or
8
#  later), or the GNU General Public License, version 2 (GPLv2), in all
9
#  cases as published by the Free Software Foundation.
10

11

12
# texttable - module for creating simple ASCII tables
13
# Incorporated from texttable.py downloaded from
14
# http://jefke.free.fr/stuff/python/texttable/texttable-0.7.0.tar.gz
15

16
import sys
17
import string
18

19
try:
20
    if sys.version >= '2.3':
21
        import textwrap
22
    elif sys.version >= '2.2':
23
        from optparse import textwrap
24
    else:
25
        from optik import textwrap
26
except ImportError:
27
    sys.stderr.write("Can't import textwrap module!\n")
28
    raise
29

30
try:
31
    True, False
32
except NameError:
33
    (True, False) = (1, 0)
34

35
def len(iterable):
36
    """Redefining len here so it will be able to work with non-ASCII characters
37
    """
38
    if not isinstance(iterable, str):
39
        return iterable.__len__()
40
    
41
    try:
42
        return len(unicode(iterable, 'utf'))
43
    except:
44
        return iterable.__len__()
45

46
class ArraySizeError(Exception):
47
    """Exception raised when specified rows don't fit the required size
48
    """
49

50
    def __init__(self, msg):
51
        self.msg = msg
52
        Exception.__init__(self, msg, '')
53

54
    def __str__(self):
55
        return self.msg
56

57
class Texttable:
58

59
    BORDER = 1
60
    HEADER = 1 << 1
61
    HLINES = 1 << 2
62
    VLINES = 1 << 3
63

64
    def __init__(self, max_width=80):
65
        """Constructor
66

67
        - max_width is an integer, specifying the maximum width of the table
68
        - if set to 0, size is unlimited, therefore cells won't be wrapped
69
        """
70

71
        if max_width <= 0:
72
            max_width = False
73
        self._max_width = max_width
74
        self._deco = Texttable.VLINES | Texttable.HLINES | Texttable.BORDER | \
75
            Texttable.HEADER
76
        self.set_chars(['-', '|', '+', '='])
77
        self.reset()
78

79
    def reset(self):
80
        """Reset the instance
81

82
        - reset rows and header
83
        """
84

85
        self._hline_string = None
86
        self._row_size = None
87
        self._header = []
88
        self._rows = []
89

90
    def header(self, array):
91
        """Specify the header of the table
92
        """
93

94
        self._check_row_size(array)
95
        self._header = map(str, array)
96

97
    def add_row(self, array):
98
        """Add a row in the rows stack
99

100
        - cells can contain newlines and tabs
101
        """
102

103
        self._check_row_size(array)
104
        self._rows.append(map(str, array))
105

106
    def add_rows(self, rows, header=True):
107
        """Add several rows in the rows stack
108

109
        - The 'rows' argument can be either an iterator returning arrays,
110
          or a by-dimensional array
111
        - 'header' specifies if the first row should be used as the header
112
          of the table
113
        """
114

115
        # nb: don't use 'iter' on by-dimensional arrays, to get a 
116
        #     usable code for python 2.1
117
        if header:
118
            if hasattr(rows, '__iter__') and hasattr(rows, 'next'):
119
                self.header(rows.next())
120
            else:
121
                self.header(rows[0])
122
                rows = rows[1:]
123
        for row in rows:
124
            self.add_row(row)
125

126
    def set_chars(self, array):
127
        """Set the characters used to draw lines between rows and columns
128

129
        - the array should contain 4 fields:
130

131
            [horizontal, vertical, corner, header]
132

133
        - default is set to:
134

135
            ['-', '|', '+', '=']
136
        """
137

138
        if len(array) != 4:
139
            raise ArraySizeError, "array should contain 4 characters"
140
        array = [ x[:1] for x in [ str(s) for s in array ] ]
141
        (self._char_horiz, self._char_vert,
142
            self._char_corner, self._char_header) = array
143

144
    def set_deco(self, deco):
145
        """Set the table decoration
146

147
        - 'deco' can be a combinaison of:
148

149
            Texttable.BORDER: Border around the table
150
            Texttable.HEADER: Horizontal line below the header
151
            Texttable.HLINES: Horizontal lines between rows
152
            Texttable.VLINES: Vertical lines between columns
153

154
           All of them are enabled by default
155

156
        - example:
157

158
            Texttable.BORDER | Texttable.HEADER
159
        """
160

161
        self._deco = deco
162

163
    def set_cols_align(self, array):
164
        """Set the desired columns alignment
165

166
        - the elements of the array should be either "l", "c" or "r":
167

168
            * "l": column flushed left
169
            * "c": column centered
170
            * "r": column flushed right
171
        """
172

173
        self._check_row_size(array)
174
        self._align = array
175

176
    def set_cols_valign(self, array):
177
        """Set the desired columns vertical alignment
178

179
        - the elements of the array should be either "t", "m" or "b":
180

181
            * "t": column aligned on the top of the cell
182
            * "m": column aligned on the middle of the cell
183
            * "b": column aligned on the bottom of the cell
184
        """
185

186
        self._check_row_size(array)
187
        self._valign = array
188

189
    def set_cols_width(self, array):
190
        """Set the desired columns width
191

192
        - the elements of the array should be integers, specifying the
193
          width of each column. For example:
194

195
                [10, 20, 5]
196
        """
197

198
        self._check_row_size(array)
199
        try:
200
            array = map(int, array)
201
            if reduce(min, array) <= 0:
202
                raise ValueError
203
        except ValueError:
204
            sys.stderr.write("Wrong argument in column width specification\n")
205
            raise
206
        self._width = array
207

208
    def draw(self):
209
        """Draw the table
210

211
        - the table is returned as a whole string
212
        """
213

214
        if not self._header and not self._rows:
215
            return
216
        self._compute_cols_width()
217
        self._check_align()
218
        out = ""
219
        if self._has_border():
220
            out += self._hline()
221
        if self._header:
222
            out += self._draw_line(self._header, isheader=True)
223
            if self._has_header():
224
                out += self._hline_header()
225
        length = 0
226
        for row in self._rows:
227
            length += 1
228
            out += self._draw_line(row)
229
            if self._has_hlines() and length < len(self._rows):
230
                out += self._hline()
231
        if self._has_border():
232
            out += self._hline()
233
        return out[:-1]
234

235
    def _check_row_size(self, array):
236
        """Check that the specified array fits the previous rows size
237
        """
238

239
        if not self._row_size:
240
            self._row_size = len(array)
241
        elif self._row_size != len(array):
242
            raise ArraySizeError, "array should contain %d elements" \
243
                % self._row_size
244

245
    def _has_vlines(self):
246
        """Return a boolean, if vlines are required or not
247
        """
248

249
        return self._deco & Texttable.VLINES > 0
250

251
    def _has_hlines(self):
252
        """Return a boolean, if hlines are required or not
253
        """
254

255
        return self._deco & Texttable.HLINES > 0
256

257
    def _has_border(self):
258
        """Return a boolean, if border is required or not
259
        """
260

261
        return self._deco & Texttable.BORDER > 0
262

263
    def _has_header(self):
264
        """Return a boolean, if header line is required or not
265
        """
266

267
        return self._deco & Texttable.HEADER > 0
268

269
    def _hline_header(self):
270
        """Print header's horizontal line
271
        """
272

273
        return self._build_hline(True)
274

275
    def _hline(self):
276
        """Print an horizontal line
277
        """
278

279
        if not self._hline_string:
280
            self._hline_string = self._build_hline()
281
        return self._hline_string
282

283
    def _build_hline(self, is_header=False):
284
        """Return a string used to separated rows or separate header from
285
        rows
286
        """
287
        horiz = self._char_horiz
288
        if (is_header):
289
            horiz = self._char_header
290
        # compute cell separator
291
        s = "%s%s%s" % (horiz, [horiz, self._char_corner][self._has_vlines()],
292
            horiz)
293
        # build the line
294
        l = s.join([horiz*n for n in self._width])
295
        # add border if needed
296
        if self._has_border():
297
            l = "%s%s%s%s%s\n" % (self._char_corner, horiz, l, horiz,
298
                self._char_corner)
299
        else:
300
            l += "\n"
301
        return l
302

303
    def _len_cell(self, cell):
304
        """Return the width of the cell
305

306
        Special characters are taken into account to return the width of the
307
        cell, such like newlines and tabs
308
        """
309

310
        cell_lines = cell.split('\n')
311
        maxi = 0
312
        for line in cell_lines:
313
            length = 0
314
            parts = line.split('\t')
315
            for part, i in zip(parts, range(1, len(parts) + 1)):
316
                length = length + len(part)
317
                if i < len(parts):
318
                    length = (length/8 + 1)*8
319
            maxi = max(maxi, length)
320
        return maxi
321

322
    def _compute_cols_width(self):
323
        """Return an array with the width of each column
324

325
        If a specific width has been specified, exit. If the total of the
326
        columns width exceed the table desired width, another width will be
327
        computed to fit, and cells will be wrapped.
328
        """
329

330
        if hasattr(self, "_width"):
331
            return
332
        maxi = []
333
        if self._header:
334
            maxi = [ self._len_cell(x) for x in self._header ]
335
        for row in self._rows:
336
            for cell,i in zip(row, range(len(row))):
337
                try:
338
                    maxi[i] = max(maxi[i], self._len_cell(cell))
339
                except (TypeError, IndexError):
340
                    maxi.append(self._len_cell(cell))
341
        items = len(maxi)
342
        length = reduce(lambda x,y: x+y, maxi)
343
        if self._max_width and length + items*3 + 1 > self._max_width:
344
            maxi = [(self._max_width - items*3 -1) / items \
345
                for n in range(items)]
346
        self._width = maxi
347

348
    def _check_align(self):
349
        """Check if alignment has been specified, set default one if not
350
        """
351

352
        if not hasattr(self, "_align"):
353
            self._align = ["l"]*self._row_size
354
        if not hasattr(self, "_valign"):
355
            self._valign = ["t"]*self._row_size
356

357
    def _draw_line(self, line, isheader=False):
358
        """Draw a line
359

360
        Loop over a single cell length, over all the cells
361
        """
362

363
        line = self._splitit(line, isheader)
364
        space = " "
365
        out  = ""
366
        for i in range(len(line[0])):
367
            if self._has_border():
368
                out += "%s " % self._char_vert
369
            length = 0
370
            for cell, width, align in zip(line, self._width, self._align):
371
                length += 1
372
                cell_line = cell[i]
373
                fill = width - len(cell_line)
374
                if isheader:
375
                    align = "c"
376
                if align == "r":
377
                    out += "%s " % (fill * space + cell_line)
378
                elif align == "c":
379
                    out += "%s " % (fill/2 * space + cell_line \
380
                            + (fill/2 + fill%2) * space)
381
                else:
382
                    out += "%s " % (cell_line + fill * space)
383
                if length < len(line):
384
                    out += "%s " % [space, self._char_vert][self._has_vlines()]
385
            out += "%s\n" % ['', self._char_vert][self._has_border()]
386
        return out
387

388
    def _splitit(self, line, isheader):
389
        """Split each element of line to fit the column width
390

391
        Each element is turned into a list, result of the wrapping of the
392
        string to the desired width
393
        """
394

395
        line_wrapped = []
396
        for cell, width in zip(line, self._width):
397
            array = []
398
            for c in cell.split('\n'):
399
                array.extend(textwrap.wrap(unicode(c, 'utf'), width))
400
            line_wrapped.append(array)
401
        max_cell_lines = reduce(max, map(len, line_wrapped))
402
        for cell, valign in zip(line_wrapped, self._valign):
403
            if isheader:
404
                valign = "t"
405
            if valign == "m":
406
                missing = max_cell_lines - len(cell)
407
                cell[:0] = [""] * (missing / 2)
408
                cell.extend([""] * (missing / 2 + missing % 2))
409
            elif valign == "b":
410
                cell[:0] = [""] * (max_cell_lines - len(cell))
411
            else:
412
                cell.extend([""] * (max_cell_lines - len(cell)))
413
        return line_wrapped
414

415

416
#    Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com>
417
#    This file is part of GlusterFS.
418

419
#    GlusterFS is free software; you can redistribute it and/or modify
420
#    it under the terms of the GNU General Public License as published
421
#    by the Free Software Foundation; either version 3 of the License,
422
#    or (at your option) any later version.
423

424
#    GlusterFS is distributed in the hope that it will be useful, but
425
#    WITHOUT ANY WARRANTY; without even the implied warranty of
426
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
427
#    General Public License for more details.
428

429
#    You should have received a copy of the GNU General Public License
430
#    along with this program.  If not, see
431
#    <http://www.gnu.org/licenses/>.
432

433
graph_available = True
434

435
try:
436
    import numpy as np
437
    import matplotlib.pyplot as plt
438
except ImportError:
439
    graph_available = False
440

441
import re
442
import sys
443

444
from optparse import OptionParser
445

446
# Global dict-of-dict holding the latency data
447
# latency[xlator-name][op-name]
448

449
latencies = {}
450
counts = {}
451
totals = {}
452

453
def collect_data (f):
454
    """Collect latency data from the file object f and store it in
455
    the global variable @latencies"""
456

457
    # example dump file line:
458
    # fuse.latency.TRUNCATE=3147.000,4
459

460
    for line in f:
461
        m = re.search ("(\w+)\.\w+.(\w+)=(\w+\.\w+),(\w+),(\w+.\w+)", line)
462
        if m and float(m.group(3)) != 0:
463
            xlator = m.group(1)
464
            op     = m.group(2)
465
            time   = m.group(3)
466
            count  = m.group(4)
467
            total  = m.group(5)
468

469
            if not xlator in latencies.keys():
470
                latencies[xlator] = dict()
471

472
            if not xlator in counts.keys():
473
                counts[xlator] = dict()
474

475
            if not xlator in totals.keys():
476
                totals[xlator] = dict()
477

478
            latencies[xlator][op] = time
479
            counts[xlator][op]    = count
480
            totals[xlator][op]    = total
481

482

483
def calc_latency_heights (xlator_order):
484
    heights = map (lambda x: [], xlator_order)
485

486
    N = len (xlator_order)
487
    for i in range (N):
488
        xl = xlator_order[i]
489

490
        k = latencies[xl].keys()
491
        k.sort()
492

493
        if i == len (xlator_order) - 1:
494
            # bottom-most xlator
495
            heights[i] = [float (latencies[xl][key]) for key in k]
496

497
        else:
498
            next_xl = xlator_order[i+1]
499
            this_xl_time = [latencies[xl][key] for key in k]
500
            next_xl_time = [latencies[next_xl][key] for key in k]
501

502
            heights[i] = map (lambda x, y: float (x) - float (y),
503
                              this_xl_time, next_xl_time)
504
    return heights
505

506
# have sufficient number of colors
507
colors = ["violet", "blue", "green", "yellow", "orange", "red"]
508

509
def latency_profile (title, xlator_order, mode):
510
    heights = calc_latency_heights (xlator_order)
511

512
    N     = len (latencies[xlator_order[0]].keys())
513
    Nxl   = len (xlator_order)
514
    ind   = np.arange (N)
515
    width = 0.35
516

517
    pieces  = map (lambda x: [], xlator_order)
518
    bottoms = map (lambda x: [], xlator_order)
519

520
    bottoms[Nxl-1] = map (lambda x: 0, latencies[xlator_order[0]].keys())
521

522
    k = latencies[xlator_order[0]].keys()
523
    k.sort()
524

525
    for i in range (Nxl-1):
526
        xl = xlator_order[i+1]
527
        bottoms[i] = [float(latencies[xl][key]) for key in k]
528

529
    if mode == 'text':
530
        print "\n%sLatency profile for %s\n" % (' '*20, title)
531
        print "Average latency (microseconds):\n"
532

533
        table = Texttable()
534

535
        table.set_cols_align(["l", "r"] + ["r"] * len(xlator_order))
536
        rows = []
537

538
        header = ['OP', 'OP Average (us)'] + xlator_order
539
        rows = []
540

541
        for op in k:
542
            sum = reduce (lambda x, y: x + y, [heights[xlator_order.index(xl)][k.index(op)] for xl in xlator_order],
543
                          0)
544

545
            row = [op]
546
            row += ["%5.2f" % sum]
547

548
            for xl in xlator_order:
549
                op_index = k.index(op)
550
                row += ["%5.2f" % (heights[xlator_order.index(xl)][op_index])]
551

552
            rows.append(row)
553

554
        def row_sort(r1, r2):
555
            v1 = float(r1[1])
556
            v2 = float(r2[1])
557

558
            if v1 < v2:
559
                return -1
560
            elif v1 == v2:
561
                return 0
562
            else:
563
                return 1
564

565
        rows.sort(row_sort, reverse=True)
566
        table.add_rows([header] + rows)
567
        print table.draw()
568

569
    elif mode == 'graph':
570
        for i in range(Nxl):
571
            pieces[i] = plt.bar (ind, heights[i], width, color=colors[i],
572
                                 bottom=bottoms[i])
573

574
            plt.ylabel ("Average Latency (microseconds)")
575
            plt.title ("Latency Profile for '%s'" % title)
576
            k = latencies[xlator_order[0]].keys()
577
            k.sort ()
578
            plt.xticks (ind+width/2., k)
579

580
            m = round (max(map (float, latencies[xlator_order[0]].values())), -2)
581
            plt.yticks (np.arange(0, m + m*0.1, m/10))
582
            plt.legend (map (lambda p: p[0], pieces), xlator_order)
583

584
            plt.show ()
585
    else:
586
        print "Unknown mode specified!"
587
        sys.exit(1)
588

589

590
def fop_distribution (title, xlator_order, mode):
591
    plt.ylabel ("Percentage of calls")
592
    plt.title ("FOP distribution for '%s'" % title)
593
    k = counts[xlator_order[0]].keys()
594
    k.sort ()
595

596
    N     = len (latencies[xlator_order[0]].keys())
597
    ind   = np.arange(N)
598
    width = 0.35
599

600
    total = 0
601
    top_xl = xlator_order[0]
602
    for op in k:
603
        total += int(counts[top_xl][op])
604

605
    heights = []
606

607
    for op in k:
608
        heights.append (float(counts[top_xl][op])/total * 100)
609

610
    if mode == 'text':
611
        print "\n%sFOP distribution for %s\n" % (' '*20, title)
612
        print "Total number of calls: %d\n" % total
613

614
        table = Texttable()
615

616
        table.set_cols_align(["l", "r", "r"])
617

618
        rows = []
619
        header = ["OP", "% of Calls", "Count"]
620

621
        for op in k:
622
            row = [op, "%5.2f" % (float(counts[top_xl][op])/total * 100), counts[top_xl][op]]
623
            rows.append(row)
624

625
        def row_sort(r1, r2):
626
            v1 = float(r1[1])
627
            v2 = float(r2[1])
628

629
            if v1 < v2:
630
                return -1
631
            elif v1 == v2:
632
                return 0
633
            else:
634
                return 1
635

636
        rows.sort(row_sort, reverse=True)
637
        table.add_rows([header] + rows)
638
        print table.draw()
639

640
    elif mode == 'graph':
641
        bars = plt.bar (ind, heights, width, color="red")
642

643
        for bar in bars:
644
            height = bar.get_height()
645
            plt.text (bar.get_x()+bar.get_width()/2., 1.05*height,
646
                      "%d%%" % int(height))
647

648
            plt.xticks(ind+width/2., k)
649
            plt.yticks(np.arange (0, 110, 10))
650

651
            plt.show()
652
    else:
653
        print "mode not specified!"
654
        sys.exit(1)
655

656

657
def calc_workload_heights (xlator_order, scaling):
658
    workload_heights = map (lambda x: [], xlator_order)
659

660
    top_xl = xlator_order[0]
661

662
    N = len (xlator_order)
663
    for i in range (N):
664
        xl = xlator_order[i]
665

666
        k = totals[xl].keys()
667
        k.sort()
668

669
        if i == len (xlator_order) - 1:
670
            # bottom-most xlator
671
            workload_heights[i] = [float (totals[xl][key]) / float(totals[top_xl][key]) * scaling[k.index(key)] for key in k]
672

673
        else:
674
            next_xl = xlator_order[i+1]
675
            this_xl_time = [float(totals[xl][key]) / float(totals[top_xl][key]) * scaling[k.index(key)] for key in k]
676
            next_xl_time = [float(totals[next_xl][key]) / float(totals[top_xl][key]) * scaling[k.index(key)] for key in k]
677

678
            workload_heights[i] = map (lambda x, y: (float (x) - float (y)),
679
                                       this_xl_time, next_xl_time)
680

681
    return workload_heights
682

683
def workload_profile(title, xlator_order, mode):
684
    plt.ylabel ("Percentage of Total Time")
685
    plt.title ("Workload Profile for '%s'" % title)
686
    k = totals[xlator_order[0]].keys()
687
    k.sort ()
688

689
    N     = len(totals[xlator_order[0]].keys())
690
    Nxl   = len(xlator_order)
691
    ind   = np.arange(N)
692
    width = 0.35
693

694
    total = 0
695
    top_xl = xlator_order[0]
696
    for op in k:
697
        total += float(totals[top_xl][op])
698

699
    p_heights = []
700

701
    for op in k:
702
        p_heights.append (float(totals[top_xl][op])/total * 100)
703

704
    heights = calc_workload_heights (xlator_order, p_heights)
705

706
    pieces  = map (lambda x: [], xlator_order)
707
    bottoms = map (lambda x: [], xlator_order)
708

709
    bottoms[Nxl-1] = map (lambda x: 0, totals[xlator_order[0]].keys())
710

711
    for i in range (Nxl-1):
712
        xl = xlator_order[i+1]
713
        k = totals[xl].keys()
714
        k.sort()
715

716
        bottoms[i] = [float(totals[xl][key]) / float(totals[top_xl][key]) * p_heights[k.index(key)] for key in k]
717

718
    if mode == 'text':
719
        print "\n%sWorkload profile for %s\n" % (' '*20, title)
720
        print "Total Time: %d microseconds = %.1f seconds = %.1f minutes\n" % (total, total / 1000000.0, total / 6000000.0)
721

722
        table = Texttable()
723
        table.set_cols_align(["l", "r"] + ["r"] * len(xlator_order))
724
        rows = []
725

726
        header = ['OP', 'OP Total (%)'] + xlator_order
727
        rows = []
728

729
        for op in k:
730
            sum = reduce (lambda x, y: x + y, [heights[xlator_order.index(xl)][k.index(op)] for xl in xlator_order],
731
                          0)
732
            row = [op]
733
            row += ["%5.2f" % sum]
734

735
            for xl in xlator_order:
736
                op_index = k.index(op)
737
                row += ["%5.2f" % heights[xlator_order.index(xl)][op_index]]
738

739
            rows.append(row)
740

741
        def row_sort(r1, r2):
742
            v1 = float(r1[1])
743
            v2 = float(r2[1])
744

745
            if v1 < v2:
746
                return -1
747
            elif v1 == v2:
748
                return 0
749
            else:
750
                return 1
751

752
        rows.sort(row_sort, reverse=True)
753
        table.add_rows([header] + rows)
754
        print table.draw()
755

756
    elif mode == 'graph':
757
        for i in range(Nxl):
758
            pieces[i] = plt.bar (ind, heights[i], width, color=colors[i],
759
                                 bottom=bottoms[i])
760

761
        for key in k:
762
            bar = pieces[Nxl-1][k.index(key)]
763
            plt.text (bar.get_x() + bar.get_width()/2., 1.05*p_heights[k.index(key)],
764
                      "%d%%" % int(p_heights[k.index(key)]))
765

766
        plt.xticks(ind+width/2., k)
767
        plt.yticks(np.arange (0, 110, 10))
768
        plt.legend (map (lambda p: p[0], pieces), xlator_order)
769

770
        plt.show()
771
    else:
772
        print "Unknown mode specified!"
773
        sys.exit(1)
774

775

776
def main ():
777
    parser = OptionParser(usage="usage: %prog [-l | -d | -w] -x <xlator order> <state dump file>")
778
    parser.add_option("-l", "--latency", dest="latency", action="store_true",
779
                      help="Produce latency profile")
780
    parser.add_option("-d", "--distribution", dest="distribution", action="store_true",
781
                      help="Produce distribution of FOPs")
782
    parser.add_option("-w", "--workload", dest="workload", action="store_true",
783
                      help="Produce workload profile")
784
    parser.add_option("-t", "--title", dest="title", help="Set the title of the graph")
785
    parser.add_option("-x", "--xlator-order", dest="xlator_order", help="Specify the order of xlators")
786
    parser.add_option("-m", "--mode", dest="mode", help="Output format, can be text[default] or graph")
787

788
    (options, args) = parser.parse_args()
789

790
    if len(args) != 1:
791
        parser.error("Incorrect number of arguments")
792

793
    if (options.xlator_order):
794
        xlator_order = options.xlator_order.split()
795
    else:
796
        print "xlator order must be specified"
797
        sys.exit(1)
798

799
    collect_data(file (args[0], 'r'))
800

801
    mode = 'text'
802
    if (options.mode):
803
        mode = options.mode
804
        if options.mode == 'graph' and graph_available == False:
805
            print "matplotlib not available, falling back to text mode"
806
            mode = 'text'
807

808
    if (options.latency):
809
        latency_profile (options.title, xlator_order, mode)
810

811
    if (options.distribution):
812
        fop_distribution(options.title, xlator_order, mode)
813

814
    if (options.workload):
815
        workload_profile(options.title, xlator_order, mode)
816

817
main ()
818

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.