Exemplo n.º 1
0
def graph(rowPoint, logsDir, warmupSec, names, fileName, maxQPS=None):

  graphData = []

  if rowPoint == 'min':
    sla = None
  elif rowPoint == 'max':
    sla = SLA[-1][1]
  else:
    sla = None
    for pct, maxResponseTime in SLA:
      if pct == logPoints[rowPoint][0]:
        sla = maxResponseTime
        break

  passesSLA = set()
  maxActualQPS = {}
  
  for name in names:

    reQPS = re.compile(r'^%s\.qps([\.0-9]+)(\.|$)' % re.escape(name))

    for f in os.listdir(logsDir):
      m = reQPS.match(f)
      resultsFile = '%s/%s/results.pk' % (logsDir, f)
      if not os.path.exists(resultsFile):
        resultsFile = '%s/%s/results.bin' % (logsDir, f)
        
      if m is not None and os.path.exists(resultsFile):
        qps = float(m.group(1))

        if False and qps > 575:
          continue
        
        if maxQPS is not None and qps > maxQPS:
          print 'SKIPPING %s qps' % qps
          continue

        # qps is the "target", ie the rate at which we sent the
        # queries to the server; actualQPS is what the server actually
        # achieved overall:
        pctPoints, actualQPS, endTimeSec = responseTimeGraph.getPctPoints(resultsFile, name, warmupSec)

        print '%s: qps %s, actualQPS %s' % (name, qps, actualQPS)

        if rowPoint == 'min':
          t = pctPoints[0]
        elif rowPoint == 'max':
          t = pctPoints[-1]
        else:
          if rowPoint+1 >= len(pctPoints):
            break
          t = pctPoints[1+rowPoint]

        if sla is not None and t <= sla:
          passesSLA.add((qps, name))
          print '  PASS'

        if True or t < 30000:
          graphData.append((qps, actualQPS, name, t))
        else:
          print '%s: drop data point qps=%s t=%s: t is >= 30000' % (name, qps, t)

        if name not in maxActualQPS:
          maxActualQPS[name] = actualQPS
        elif actualQPS > maxActualQPS[name]:
          maxActualQPS[name] = actualQPS

  graphData.sort()

  l = []
  w = l.append
    
  w("['QPS', %s],\n" % (', '.join(["'%s'" % responseTimeGraph.cleanName(x) for x in names])),)
  for qps, actualQPS, name, responseTime in graphData:
    row = ['%.1f' % actualQPS]
    for name2 in names:
      if name2 == name:
        row.append('%.1f' % responseTime)
      else:
        row.append('null')
    w('[%s],\n' % ','.join(row))
    
  if rowPoint == 'max':
    p = 'Max'
  elif rowPoint == 'min':
    p = 'Min'
  else:
    p = '%g%%' % logPoints[rowPoint][0]
    
  html = graphHeader + ''.join(l) + graphFooter % p
  open(fileName, 'wb').write(html)
  print '  saved %s' % fileName
  if sla is None:
    return None, maxActualQPS
  else:
    return passesSLA, maxActualQPS
Exemplo n.º 2
0
def main(maxQPS=None):
    logsDir = sys.argv[1]
    warmupSec = int(sys.argv[2])
    reportsDir = sys.argv[3]

    if maxQPS is None:
        if os.path.exists(reportsDir):
            print 'ERROR: please move existing reportsDir (%s) out of the way' % reportsDir
            sys.exit(1)

            print 'getInterpValue: list=%s interpDate=%s' % (valueList,
                                                             interpDate)

        os.makedirs(reportsDir)

    qps = set()
    names = set()
    byName = {}
    byPCT = {}

    for f in os.listdir(logsDir):
        m = reQPS.search(f)
        if m is not None:

            qpsString = m.group(1)
            qpsValue = float(qpsString)

            if False and qpsValue > 200:
                continue

            qps.add((qpsValue, qpsString))
            name = f[:f.find('.qps')]

            # nocommit
            if name.find('G1') != -1:
                continue

            if name.lower().find('warmup') == -1:
                names.add(name)
                if not name in byName:
                    byName[name] = []
                byName[name].append((qpsValue, qpsString, f))

                m = rePCT.search(f)
                if m is not None:
                    pct = int(m.group(1))
                    if pct not in byPCT:
                        byPCT[pct] = []
                    byPCT[pct].append((name, qpsValue, qpsString, f))

    if len(names) == 0:
        raise RuntimeError('no logs found @ %s' % logsDir)

    if False:
        for name, l in byName.items():
            l.sort()
            for idx, (qpsS, qps, dirName) in enumerate(l):
                if dirName.find('.pct') == -1:
                    os.rename('%s/%s' % (logsDir, dirName),
                              '%s/%s.pct%s' % (logsDir, dirName, pcts[idx]))
            print '%s -> %s' % (name, l)

    if maxQPS is None:
        indexOut = open('%s/index.html' % reportsDir, 'wb')
    else:
        indexOut = open('%s/index.html' % reportsDir, 'ab')
        indexOut.write('\n<br>')

    w = indexOut.write

    names = list(names)
    names.sort()

    try:
        if maxQPS is None:

            w('<h2>By QPS:</h2>')

            if len(byPCT) != 0:
                l = list(byPCT.keys())
                l.sort()

                # Collate by PCT:
                for idx, pct in enumerate(l):

                    # Sort by name so we get consistent colors:
                    l2 = byPCT[pct]
                    l2.sort()

                    d = []
                    for name, qpsValue, qpsString, resultsFile in l2:
                        d.append(
                            ('%s.qps%s' % (name, qpsString),
                             '%s/%s/results.bin' % (logsDir, resultsFile)))

                    if len(d) == 0:
                        raise RuntimeError('nothing matches pct=%d' % pct)

                    print
                    print 'Create response-time graph @ pct=%d: d=%s' % (pct,
                                                                         d)

                    if len(d) != 0:
                        try:
                            html = responseTimeGraph.createGraph(
                                d,
                                warmupSec,
                                title='Query time at %d%% load' % pct)
                        except IndexError:
                            raise
                        fileName = '%s/responseTime%sPCT.html' % (reportsDir,
                                                                  pct)
                        open(fileName, 'wb').write(html)
                        w('<a href="%s">at %d%% load</a>' % (fileName, pct))
                        w('<br>\n')

            else:
                # Collate by QPS:
                l = list(qps)
                l.sort()

                for idx, (qps, qpsString) in enumerate(l):

                    d = []
                    validNames = []
                    for name in names:
                        resultsFile = '%s/%s.qps%s/results.bin' % (
                            logsDir, name, qpsString)
                        if os.path.exists(resultsFile):
                            d.append(
                                ('%s.qps%s' % (name, qpsString), resultsFile))
                            validNames.append(name)

                    if len(d) == 0:
                        #raise RuntimeError('nothing matches qps=%s' % qpsString)
                        continue

                    print
                    print 'Create response-time graph @ qps=%s: d=%s' % (qps,
                                                                         d)

                    if len(d) != 0:
                        try:
                            html = responseTimeGraph.createGraph(d, warmupSec)
                        except IndexError:
                            raise
                        open('%s/%sqps.html' % (reportsDir, qpsString),
                             'wb').write(html)
                        w('<a href="%sqps.html">%d queries/sec [%s]</a>' %
                          (qpsString, qps, ', '.join(
                              responseTimeGraph.cleanName(x)
                              for x in validNames)))
                        w('<br>\n')

        if maxQPS is None:
            w('<h2>By percentile:</h2>')
        else:
            w('<h2>By percentile (max QPS %d):</h2>' % maxQPS)

        allPassesSLA = None

        for idx in xrange(len(loadGraphActualQPS.logPoints)):

            print
            print 'Create pct graph @ %s%%' % loadGraphActualQPS.logPoints[
                idx][0]

            if maxQPS is not None:
                fileName = 'load%spct_max%s.html' % (
                    loadGraphActualQPS.logPoints[idx][0], maxQPS)
            else:
                fileName = 'load%spct.html' % (
                    loadGraphActualQPS.logPoints[idx][0])

            stop = False
            try:
                passesSLA, maxActualQPS = loadGraphActualQPS.graph(
                    idx,
                    logsDir,
                    warmupSec,
                    names,
                    '%s/%s' % (reportsDir, fileName),
                    maxQPS=maxQPS)
            except RuntimeError:
                stop = True

            if passesSLA is not None:
                if allPassesSLA is None:
                    allPassesSLA = passesSLA
                else:
                    for x in list(allPassesSLA):
                        if x not in passesSLA:
                            allPassesSLA.remove(x)

            if stop:
                break

            w('<a href="%s">%s %%</a>' %
              (fileName, loadGraphActualQPS.logPoints[idx][0]))
            w('<br>\n')

        fileName = '%s/loadmax.html' % reportsDir
        passesSLA, maxActualQPS = loadGraphActualQPS.graph('max',
                                                           logsDir,
                                                           warmupSec,
                                                           names,
                                                           fileName,
                                                           maxQPS=maxQPS)
        if passesSLA is not None:
            for x in list(allPassesSLA):
                if x not in passesSLA:
                    allPassesSLA.remove(x)

        highest = {}
        for qps, name in allPassesSLA:
            if name not in highest or qps > highest[name]:
                highest[name] = qps

        l = [(y, x) for x, y in highest.items()]
        l.sort()

        print
        print 'Max actual QPS:'
        for name, qps in maxActualQPS.items():
            print '  %s: %.1f QPS' % (name, qps)

        print
        print 'Highest QPS w/ SLA met:'
        for qps, name in l:
            print '  %s: %s QPS' % (responseTimeGraph.cleanName(name), qps)

        w('<a href="loadmax.html">100%%</a>')
        w('<br>')

    finally:
        indexOut.close()
Exemplo n.º 3
0
def main(maxQPS = None):
  logsDir = sys.argv[1]
  warmupSec = int(sys.argv[2])
  reportsDir = sys.argv[3]

  if maxQPS is None:
    if os.path.exists(reportsDir):
      print 'ERROR: please move existing reportsDir (%s) out of the way' % reportsDir
      sys.exit(1)

      print 'getInterpValue: list=%s interpDate=%s' % (valueList, interpDate)

    os.makedirs(reportsDir)

  qps = set()
  names = set()
  byName = {}
  byPCT = {}
  
  for f in os.listdir(logsDir):
    m = reQPS.search(f)
    if m is not None:

      qpsString = m.group(1)
      qpsValue = float(qpsString)

      if False and qpsValue > 200:
        continue
        
      qps.add((qpsValue, qpsString))
      name = f[:f.find('.qps')]

      # nocommit
      if name.find('G1') != -1:
        continue
      
      if name.lower().find('warmup') == -1:
        names.add(name)
        if not name in byName:
          byName[name] = []
        byName[name].append((qpsValue, qpsString, f))

        m = rePCT.search(f)
        if m is not None:
          pct = int(m.group(1))
          if pct not in byPCT:
            byPCT[pct] = []
          byPCT[pct].append((name, qpsValue, qpsString, f))

  if len(names) == 0:
    raise RuntimeError('no logs found @ %s' % logsDir)

  if False:
    for name, l in byName.items():
      l.sort()
      for idx, (qpsS, qps, dirName) in enumerate(l):
        if dirName.find('.pct') == -1:
          os.rename('%s/%s' % (logsDir, dirName),
                    '%s/%s.pct%s' % (logsDir, dirName, pcts[idx]))
      print '%s -> %s' % (name, l)

  if maxQPS is None:
    indexOut = open('%s/index.html' % reportsDir, 'wb')
  else:
    indexOut = open('%s/index.html' % reportsDir, 'ab')
    indexOut.write('\n<br>')
    
  w = indexOut.write

  names = list(names)
  names.sort()
  
  try:
    if maxQPS is None:

      w('<h2>By QPS:</h2>')

      if len(byPCT) != 0:
        l = list(byPCT.keys())
        l.sort()
        
        # Collate by PCT:
        for idx, pct in enumerate(l):

          # Sort by name so we get consistent colors:
          l2 = byPCT[pct]
          l2.sort()
          
          d = []
          for name, qpsValue, qpsString, resultsFile in l2:
            d.append(('%s.qps%s' % (name, qpsString), '%s/%s/results.bin' % (logsDir, resultsFile)))

          if len(d) == 0:
            raise RuntimeError('nothing matches pct=%d' % pct)

          print
          print 'Create response-time graph @ pct=%d: d=%s' % (pct, d)

          if len(d) != 0:
            try:
              html = responseTimeGraph.createGraph(d, warmupSec, title='Query time at %d%% load' % pct)
            except IndexError:
              raise
            fileName = '%s/responseTime%sPCT.html' % (reportsDir, pct)
            open(fileName, 'wb').write(html)
            w('<a href="%s">at %d%% load</a>' % (fileName, pct))
            w('<br>\n')
        
      else:
        # Collate by QPS:
        l = list(qps)
        l.sort()

        for idx, (qps, qpsString) in enumerate(l):

          d = []
          validNames = []
          for name in names:
            resultsFile = '%s/%s.qps%s/results.bin' % (logsDir, name, qpsString)
            if os.path.exists(resultsFile):
              d.append(('%s.qps%s' % (name, qpsString), resultsFile))
              validNames.append(name)

          if len(d) == 0:
            #raise RuntimeError('nothing matches qps=%s' % qpsString)
            continue

          print
          print 'Create response-time graph @ qps=%s: d=%s' % (qps, d)

          if len(d) != 0:
            try:
              html = responseTimeGraph.createGraph(d, warmupSec)
            except IndexError:
              raise
            open('%s/%sqps.html' % (reportsDir, qpsString), 'wb').write(html)
            w('<a href="%sqps.html">%d queries/sec [%s]</a>' % (qpsString, qps, ', '.join(responseTimeGraph.cleanName(x) for x in validNames)))
            w('<br>\n')

    if maxQPS is None:
      w('<h2>By percentile:</h2>')
    else:
      w('<h2>By percentile (max QPS %d):</h2>' % maxQPS)

    allPassesSLA = None

    for idx in xrange(len(loadGraphActualQPS.logPoints)):

      print
      print 'Create pct graph @ %s%%' % loadGraphActualQPS.logPoints[idx][0]

      if maxQPS is not None:
        fileName = 'load%spct_max%s.html' % (loadGraphActualQPS.logPoints[idx][0], maxQPS)
      else:
        fileName = 'load%spct.html' % (loadGraphActualQPS.logPoints[idx][0])

      stop = False
      try:
        passesSLA, maxActualQPS = loadGraphActualQPS.graph(idx, logsDir, warmupSec, names, '%s/%s' % (reportsDir, fileName), maxQPS=maxQPS)
      except RuntimeError:
        stop = True

      if passesSLA is not None:
        if allPassesSLA is None:
          allPassesSLA = passesSLA
        else:
          for x in list(allPassesSLA):
            if x not in passesSLA:
              allPassesSLA.remove(x)

      if stop:
        break
      
      w('<a href="%s">%s %%</a>' % (fileName, loadGraphActualQPS.logPoints[idx][0]))
      w('<br>\n')

    fileName = '%s/loadmax.html' % reportsDir      
    passesSLA, maxActualQPS = loadGraphActualQPS.graph('max', logsDir, warmupSec, names, fileName, maxQPS=maxQPS)
    if passesSLA is not None:
      for x in list(allPassesSLA):
        if x not in passesSLA:
          allPassesSLA.remove(x)

    highest = {}
    for qps, name in allPassesSLA:
      if name not in highest or qps > highest[name]:
        highest[name] = qps

    l = [(y, x) for x, y in highest.items()]
    l.sort()

    print
    print 'Max actual QPS:'
    for name, qps in maxActualQPS.items():
      print '  %s: %.1f QPS' % (name, qps)

    print
    print 'Highest QPS w/ SLA met:'
    for qps, name in l:
      print '  %s: %s QPS' % (responseTimeGraph.cleanName(name), qps)

    w('<a href="loadmax.html">100%%</a>')
    w('<br>')

  finally:
    indexOut.close()