19aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr#!/usr/bin/python
29aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr"""
39aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrPostprocessing module for IOzone. It is capable to pick results from an
49aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrIOzone run, calculate the geometric mean for all throughput results for
59aacf2b1d80524c7a168afc7b0ee75417ac05d22lmra given file size or record size, and then generate a series of 2D and 3D
69aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrgraphs. The graph generation functionality depends on gnuplot, and if it
79aacf2b1d80524c7a168afc7b0ee75417ac05d22lmris not present, functionality degrates gracefully.
89aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
99aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr@copyright: Red Hat 2010
109aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr"""
119aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrimport os, sys, optparse, logging, math, time
129aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrimport common
139aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrfrom autotest_lib.client.common_lib import logging_config, logging_manager
149aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrfrom autotest_lib.client.common_lib import error
159aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrfrom autotest_lib.client.bin import utils, os_dep
169aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
179aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
189aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr_LABELS = ['file_size', 'record_size', 'write', 'rewrite', 'read', 'reread',
199aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr           'randread', 'randwrite', 'bkwdread', 'recordrewrite', 'strideread',
209aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr           'fwrite', 'frewrite', 'fread', 'freread']
219aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
229aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
239aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrdef unique(list):
249aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
259aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    Return a list of the elements in list, but without duplicates.
269aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
279aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @param list: List with values.
289aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @return: List with non duplicate elements.
299aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
309aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    n = len(list)
319aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    if n == 0:
329aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return []
339aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    u = {}
349aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    try:
359aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for x in list:
369aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            u[x] = 1
379aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    except TypeError:
389aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return None
399aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    else:
409aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return u.keys()
419aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
429aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
439aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrdef geometric_mean(values):
449aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
459aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    Evaluates the geometric mean for a list of numeric values.
469aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
479aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @param values: List with values.
489aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @return: Single value representing the geometric mean for the list values.
499aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @see: http://en.wikipedia.org/wiki/Geometric_mean
509aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
519aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    try:
529aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        values = [int(value) for value in values]
539aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    except ValueError:
549aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return None
559aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    product = 1
569aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    n = len(values)
579aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    if n == 0:
589aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return None
599aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    return math.exp(sum([math.log(x) for x in values])/n)
609aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
619aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
629aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrdef compare_matrices(matrix1, matrix2, treshold=0.05):
639aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
649aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    Compare 2 matrices nxm and return a matrix nxm with comparison data
659aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
669aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @param matrix1: Reference Matrix with numeric data
679aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @param matrix2: Matrix that will be compared
689aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    @param treshold: Any difference bigger than this percent treshold will be
699aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            reported.
709aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
719aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    improvements = 0
729aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    regressions = 0
739aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    same = 0
749aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    comparison_matrix = []
759aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
769aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    new_matrix = []
779aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    for line1, line2 in zip(matrix1, matrix2):
789aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        new_line = []
799aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for element1, element2 in zip(line1, line2):
809aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            ratio = float(element2) / float(element1)
819aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            if ratio < (1 - treshold):
829aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                regressions += 1
839aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                new_line.append((100 * ratio - 1) - 100)
849aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            elif ratio > (1 + treshold):
859aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                improvements += 1
869aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                new_line.append("+" + str((100 * ratio - 1) - 100))
879aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            else:
889aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                same + 1
899aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                if line1.index(element1) == 0:
909aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                    new_line.append(element1)
919aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                else:
929aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                    new_line.append(".")
939aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        new_matrix.append(new_line)
949aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
959aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    total = improvements + regressions + same
969aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
979aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    return (new_matrix, improvements, regressions, total)
989aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
999aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1009aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrclass IOzoneAnalyzer(object):
1019aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
1029aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    Analyze an unprocessed IOzone file, and generate the following types of
1039aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    report:
1049aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1059aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    * Summary of throughput for all file and record sizes combined
1069aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    * Summary of throughput for all file sizes
1079aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    * Summary of throughput for all record sizes
1089aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1099aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    If more than one file is provided to the analyzer object, a comparison
1109aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    between the two runs is made, searching for regressions in performance.
1119aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
1129aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def __init__(self, list_files, output_dir):
1139aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        self.list_files = list_files
1149aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if not os.path.isdir(output_dir):
1159aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            os.makedirs(output_dir)
1169aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        self.output_dir = output_dir
1179aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("Results will be stored in %s", output_dir)
1189aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1199aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1209aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def average_performance(self, results, size=None):
1219aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1229aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Flattens a list containing performance results.
1239aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1249aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param results: List of n lists containing data from performance runs.
1259aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param size: Numerical value of a size (say, file_size) that was used
1269aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                to filter the original results list.
1279aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @return: List with 1 list containing average data from the performance
1289aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                run.
1299aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1309aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        average_line = []
1319aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if size is not None:
1329aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            average_line.append(size)
1339aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for i in range(2, 15):
1349aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            average = geometric_mean([line[i] for line in results]) / 1024.0
1359aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            average = int(average)
1369aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            average_line.append(average)
1379aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return average_line
1389aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1399aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1409aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def process_results(self, results, label=None):
1419aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1429aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Process a list of IOzone results according to label.
1439aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1449aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @label: IOzone column label that we'll use to filter and compute
1459aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                geometric mean results, in practical term either 'file_size'
1469aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                or 'record_size'.
1479aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @result: A list of n x m columns with original iozone results.
1489aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @return: A list of n-? x (m-1) columns with geometric averages for
1499aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                values of each label (ex, average for all file_sizes).
1509aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1519aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        performance = []
1529aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if label is not None:
1539aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            index = _LABELS.index(label)
1549aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            sizes = unique([line[index] for line in results])
1559aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            sizes.sort()
1569aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            for size in sizes:
1579aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                r_results = [line for line in results if line[index] == size]
1589aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                performance.append(self.average_performance(r_results, size))
1599aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        else:
1609aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            performance.append(self.average_performance(results))
1619aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1629aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return performance
1639aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1649aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1659aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def parse_file(self, file):
1669aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1679aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Parse an IOzone results file.
1689aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1699aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param file: File object that will be parsed.
1709aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @return: Matrix containing IOzone results extracted from the file.
1719aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1729aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        lines = []
1739aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for line in file.readlines():
1749aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            fields = line.split()
1759aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            if len(fields) != 15:
1769aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                continue
1779aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            try:
1789aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                lines.append([int(i) for i in fields])
1799aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            except ValueError:
1809aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                continue
1819aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        return lines
1829aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1839aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1849aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def report(self, overall_results, record_size_results, file_size_results):
1859aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1869aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Generates analysis data for IOZone run.
1879aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1889aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Generates a report to both logs (where it goes with nice headers) and
1899aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        output files for further processing (graph generation).
1909aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
1919aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param overall_results: 1x15 Matrix containing IOzone results for all
1929aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                file sizes
1939aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param record_size_results: nx15 Matrix containing IOzone results for
1949aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                each record size tested.
1959aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param file_size_results: nx15 Matrix containing file size results
1969aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                for each file size tested.
1979aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
1989aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        # Here we'll use the logging system to put the output of our analysis
1999aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        # to files
2009aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logger = logging.getLogger()
2019aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        formatter = logging.Formatter("")
2029aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2039aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2049aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("TABLE:  SUMMARY of ALL FILE and RECORD SIZES                        Results in MB/sec")
2059aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2069aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("FILE & RECORD  INIT    RE              RE    RANDOM  RANDOM  BACKWD   RECRE  STRIDE    F       FRE     F       FRE")
2079aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("SIZES (KB)     WRITE   WRITE   READ    READ    READ   WRITE    READ   WRITE    READ    WRITE   WRITE   READ    READ")
2089aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("-------------------------------------------------------------------------------------------------------------------")
2099aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for result_line in overall_results:
2109aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.info("ALL            %-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s" % tuple(result_line))
2119aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2129aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2139aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("DRILLED DATA:")
2149aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2159aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2169aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("TABLE:  RECORD Size against all FILE Sizes                          Results in MB/sec")
2179aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2189aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("RECORD    INIT    RE              RE    RANDOM  RANDOM  BACKWD   RECRE  STRIDE    F       FRE     F       FRE ")
2199aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("SIZE (KB) WRITE   WRITE   READ    READ    READ   WRITE    READ   WRITE    READ    WRITE   WRITE   READ    READ")
2209aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("--------------------------------------------------------------------------------------------------------------")
2219aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2229aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        foutput_path = os.path.join(self.output_dir, '2d-datasource-file')
2239aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if os.path.isfile(foutput_path):
2249aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            os.unlink(foutput_path)
2259aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        foutput = logging.FileHandler(foutput_path)
2269aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        foutput.setFormatter(formatter)
2279aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logger.addHandler(foutput)
2289aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for result_line in record_size_results:
2299aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.info("%-10s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s" % tuple(result_line))
2309aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logger.removeHandler(foutput)
2319aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2329aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2339aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2349aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2359aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("TABLE:  FILE Size against all RECORD Sizes                          Results in MB/sec")
2369aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2379aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("RECORD    INIT    RE              RE    RANDOM  RANDOM  BACKWD   RECRE  STRIDE    F       FRE     F       FRE ")
2389aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("SIZE (KB) WRITE   WRITE   READ    READ    READ   WRITE    READ   WRITE    READ    WRITE   WRITE   READ    READ")
2399aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("--------------------------------------------------------------------------------------------------------------")
2409aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2419aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        routput_path = os.path.join(self.output_dir, '2d-datasource-record')
2429aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if os.path.isfile(routput_path):
2439aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            os.unlink(routput_path)
2449aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        routput = logging.FileHandler(routput_path)
2459aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        routput.setFormatter(formatter)
2469aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logger.addHandler(routput)
2479aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for result_line in file_size_results:
2489aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.info("%-10s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s" % tuple(result_line))
2499aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logger.removeHandler(routput)
2509aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2519aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2529aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2539aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2549aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def report_comparison(self, record, file):
2559aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
2569aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Generates comparison data for 2 IOZone runs.
2579aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2589aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        It compares 2 sets of nxm results and outputs a table with differences.
2599aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        If a difference higher or smaller than 5% is found, a warning is
2609aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        triggered.
2619aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2629aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param record: Tuple with 4 elements containing results for record size.
2639aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        @param file: Tuple with 4 elements containing results for file size.
2649aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
2659aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        (record_size, record_improvements, record_regressions,
2669aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr         record_total) = record
2679aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        (file_size, file_improvements, file_regressions,
2689aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr         file_total) = file
2699aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("ANALYSIS of DRILLED DATA:")
2709aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2719aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2729aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("TABLE:  RECsize Difference between runs                            Results are % DIFF")
2739aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2749aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("RECORD    INIT    RE              RE    RANDOM  RANDOM  BACKWD   RECRE  STRIDE    F       FRE     F       FRE ")
2759aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("SIZE (KB) WRITE   WRITE   READ    READ    READ   WRITE    READ   WRITE    READ    WRITE   WRITE   READ    READ")
2769aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("--------------------------------------------------------------------------------------------------------------")
2779aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for result_line in record_size:
2789aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.info("%-10s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s" % tuple(result_line))
2799aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("REGRESSIONS: %d (%.2f%%)    Improvements: %d (%.2f%%)",
2809aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     record_regressions,
2819aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     (100 * record_regressions/float(record_total)),
2829aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     record_improvements,
2839aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     (100 * record_improvements/float(record_total)))
2849aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2859aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
2869aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2879aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("TABLE:  FILEsize Difference between runs                           Results are % DIFF")
2889aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
2899aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("RECORD    INIT    RE              RE    RANDOM  RANDOM  BACKWD   RECRE  STRIDE    F       FRE     F       FRE ")
2909aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("SIZE (KB) WRITE   WRITE   READ    READ    READ   WRITE    READ   WRITE    READ    WRITE   WRITE   READ    READ")
2919aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("--------------------------------------------------------------------------------------------------------------")
2929aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for result_line in file_size:
2939aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.info("%-10s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s%-8.6s" % tuple(result_line))
2949aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("REGRESSIONS: %d (%.2f%%)    Improvements: %d (%.2f%%)",
2959aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     file_regressions,
2969aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     (100 * file_regressions/float(file_total)),
2979aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     file_improvements,
2989aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     (100 * file_improvements/float(file_total)))
2999aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        logging.info("")
3009aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3019aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3029aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def analyze(self):
3039aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
3049aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Analyzes and eventually compares sets of IOzone data.
3059aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
3069aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        overall = []
3079aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        record_size = []
3089aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        file_size = []
3099aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for path in self.list_files:
3109aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            file = open(path, 'r')
3119aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.info('FILE: %s', path)
3129aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3139aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            results = self.parse_file(file)
3149aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3159aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            overall_results = self.process_results(results)
3169aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            record_size_results = self.process_results(results, 'record_size')
3179aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            file_size_results = self.process_results(results, 'file_size')
3189aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.report(overall_results, record_size_results, file_size_results)
3199aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3209aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            if len(self.list_files) == 2:
3219aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                overall.append(overall_results)
3229aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                record_size.append(record_size_results)
3239aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                file_size.append(file_size_results)
3249aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3259aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if len(self.list_files) == 2:
3269aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            record_comparison = compare_matrices(*record_size)
3279aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            file_comparison = compare_matrices(*file_size)
3289aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.report_comparison(record_comparison, file_comparison)
3299aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3309aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3319aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrclass IOzonePlotter(object):
3329aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
3339aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    Plots graphs based on the results of an IOzone run.
3349aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3359aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    Plots graphs based on the results of an IOzone run. Uses gnuplot to
3369aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    generate the graphs.
3379aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    """
3389aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def __init__(self, results_file, output_dir):
3399aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        self.active = True
3409aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        try:
3419aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.gnuplot = os_dep.command("gnuplot")
3429aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        except:
3439aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.error("Command gnuplot not found, disabling graph "
3449aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                          "generation")
3459aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.active = False
3469aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3479aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if not os.path.isdir(output_dir):
3489aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            os.makedirs(output_dir)
3499aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        self.output_dir = output_dir
3509aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3519aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if not os.path.isfile(results_file):
3529aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            logging.error("Invalid file %s provided, disabling graph "
3539aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                          "generation", results_file)
3549aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.active = False
3559aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.results_file = None
3569aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        else:
3579aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.results_file = results_file
3589aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.generate_data_source()
3599aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3609aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3619aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def generate_data_source(self):
3629aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
3639aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Creates data file without headers for gnuplot consumption.
3649aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
3659aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        results_file = open(self.results_file, 'r')
3669aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        self.datasource = os.path.join(self.output_dir, '3d-datasource')
3679aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        datasource = open(self.datasource, 'w')
3689aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for line in results_file.readlines():
3699aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            fields = line.split()
3709aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            if len(fields) != 15:
3719aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                continue
3729aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            try:
3739aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                values = [int(i) for i in fields]
3749aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                datasource.write(line)
3759aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            except ValueError:
3769aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                continue
3779aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        datasource.close()
3789aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3799aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
3809aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def plot_2d_graphs(self):
3819aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
3829aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        For each one of the throughput parameters, generate a set of gnuplot
3839aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        commands that will create a parametric surface with file size vs.
3849aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        record size vs. throughput.
3859aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
3869aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        datasource_2d = os.path.join(self.output_dir, '2d-datasource-file')
3873ce7ac1035d8f5331441cf4d9edd78be09c8bf9blmr        for index, label in zip(range(2, 15), _LABELS[2:]):
3889aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_path = os.path.join(self.output_dir, '2d-%s.do' % label)
3899aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands = ""
3909aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set title 'Iozone performance: %s'\n" % label
3919aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set logscale x\n"
3929aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set xlabel 'File size (KB)'\n"
3939aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set ylabel 'Througput (MB/s)'\n"
3949aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set terminal png small size 450 350\n"
3959aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set output '%s'\n" % os.path.join(self.output_dir,
3969aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                                                           '2d-%s.png' % label)
3979aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += ("plot '%s' using 1:%s title '%s' with lines \n" %
3989aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                         (datasource_2d, index, label))
3999aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_file = open(commands_path, 'w')
4009aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_file.write(commands)
4019aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_file.close()
4029aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            try:
403456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis                utils.system("%s %s" % (self.gnuplot, commands_path))
404456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis            except error.CmdError:
405456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis                logging.error("Problem plotting from commands file %s",
406456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis                              commands_path)
4079aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4089aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4099aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def plot_3d_graphs(self):
4109aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
4119aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        For each one of the throughput parameters, generate a set of gnuplot
4129aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        commands that will create a parametric surface with file size vs.
4139aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        record size vs. throughput.
4149aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
4159aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        for index, label in zip(range(1, 14), _LABELS[2:]):
4169aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_path = os.path.join(self.output_dir, '%s.do' % label)
4179aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands = ""
4189aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set title 'Iozone performance: %s'\n" % label
4199aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set grid lt 2 lw 1\n"
4209aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set surface\n"
4219aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set parametric\n"
4229aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set xtics\n"
4239aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set ytics\n"
4249aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set logscale x 2\n"
4259aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set logscale y 2\n"
4269aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set logscale z\n"
4279aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set xrange [2.**5:2.**24]\n"
4289aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set xlabel 'File size (KB)'\n"
4299aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set ylabel 'Record size (KB)'\n"
4309aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set zlabel 'Througput (KB/s)'\n"
4319aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set data style lines\n"
4329aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set dgrid3d 80,80, 3\n"
4339aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set terminal png small size 900 700\n"
4349aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += "set output '%s'\n" % os.path.join(self.output_dir,
4359aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                                                           '%s.png' % label)
4369aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands += ("splot '%s' using 1:2:%s title '%s'\n" %
4379aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                         (self.datasource, index, label))
4389aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_file = open(commands_path, 'w')
4399aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_file.write(commands)
4409aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            commands_file.close()
4419aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            try:
442456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis                utils.system("%s %s" % (self.gnuplot, commands_path))
443456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis            except error.CmdError:
444456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis                logging.error("Problem plotting from commands file %s",
445456d3c115952bf1ae984770e226c5a50676b31c0Dale Curtis                              commands_path)
4469aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4479aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4489aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def plot_all(self):
4499aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
4509aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        Plot all graphs that are to be plotted, provided that we have gnuplot.
4519aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        """
4529aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        if self.active:
4539aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.plot_2d_graphs()
4549aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr            self.plot_3d_graphs()
4559aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4569aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4579aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrclass AnalyzerLoggingConfig(logging_config.LoggingConfig):
4589aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    def configure_logging(self, results_dir=None, verbose=False):
4599aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        super(AnalyzerLoggingConfig, self).configure_logging(use_console=True,
4609aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                                                        verbose=verbose)
4619aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4629aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4639aacf2b1d80524c7a168afc7b0ee75417ac05d22lmrif __name__ == "__main__":
4649aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    parser = optparse.OptionParser("usage: %prog [options] [filenames]")
4659aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    options, args = parser.parse_args()
4669aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4679aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    logging_manager.configure_logging(AnalyzerLoggingConfig())
4689aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4699aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    if args:
4709aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        filenames = args
4719aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    else:
4729aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        parser.print_help()
4739aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        sys.exit(1)
4749aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4759aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    if len(args) > 2:
4769aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        parser.print_help()
4779aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        sys.exit(1)
4789aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4799aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    o = os.path.join(os.getcwd(),
4809aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr                     "iozone-graphs-%s" % time.strftime('%Y-%m-%d-%H.%M.%S'))
4819aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    if not os.path.isdir(o):
4829aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr        os.makedirs(o)
4839aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr
4849aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    a = IOzoneAnalyzer(list_files=filenames, output_dir=o)
4859aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    a.analyze()
4869aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    p = IOzonePlotter(results_file=filenames[0], output_dir=o)
4879aacf2b1d80524c7a168afc7b0ee75417ac05d22lmr    p.plot_all()
488