Ejemplo n.º 1
0
    def report(self,
               reportName=None,
               benchmarkPaths=None,
               classifier=DefaultClassifier(),
               txnFilter=None,
               reportThreshold=3000,
               resultOrder=ResultOrder.WorstToBest):
        """
    Ends active profile session and generates reports.

    This method executes the following steps
    1. Ends samples collection and disconnects tcp connection to target
    2. Gathers sample files for the current profile session and loads elapsed time and pmu counters
    3. Groups related counters to build transactions and timelines
    4. Generates html report and stores results

    :param reportName: Name of the profile report (Default value = None)
    :type reportName: str
    :param benchmarkPaths: List of stored reports from previous runs, for benchmarking (Default value = None)
    :param classifier: Predicate to classify transactions into different categories (Default value = DefaultClassifier()
    :type classifier: xpedite.txn.classifier.ProbeDataClassifier
    :param txnFilter: Lambda to filter transactions prior to report generation
    :type txnFilter: callable accepting a txn instance and returns a bool
    :param reportThreshold: Threshold for number of transactions rendered in html reports (Default value = 3000)
    :type reportThreshold: int
    :param resultOrder: Default sort order of transactions in latency constituent reports
    :type resultOrder: xpedite.pmu.ResultOrder

    """
        from xpedite.profiler.reportgenerator import ReportGenerator
        from xpedite.txn.repo import TxnRepoFactory
        from xpedite.pmu.event import Event
        try:
            if not self.app.dryRun:
                try:
                    self.app.endProfile()
                except Exception as ex:
                    LOGGER.warn('Detected unclean profile termination - %s',
                                ex)
                if self.eventSet:
                    self.app.disablePMU()

            repoFactory = TxnRepoFactory()
            pmc = [
                Event(req.name, req.uarchName)
                for req in self.eventSet.requests()
            ] if self.eventSet else []
            repo = repoFactory.buildTxnRepo(self.app, self.cpuInfo,
                                            self.probes, self.topdownCache,
                                            self.topdownMetrics, pmc,
                                            self.benchmarkProbes,
                                            benchmarkPaths)
            reportName = reportName if reportName else self.app.name
            reportGenerator = ReportGenerator(reportName)
            return reportGenerator.generateReport(self.app, repo, classifier,
                                                  resultOrder, reportThreshold,
                                                  txnFilter, benchmarkPaths)
        except Exception as ex:
            LOGGER.exception('failed to generate report')
            raise ex
Ejemplo n.º 2
0
  def groupElapsedTime(txnSubCollection, cpuInfo, classifier=DefaultClassifier()):
    """
    Aggregates elapsed time by category

    This method computes elapsed wall time for each transaction in the subcollection
    and aggregates computed duration by its soruce transaction's category

    :param txnSubCollection: Transaction subcollection to be aggregated
    :param classifier: Predicate to classify transactions into different categories
    :param cpuInfo: Cpu info to convert cycles to duration (micro seconds)

    """
    elapsedTscGroup = {}
    for txn in txnSubCollection:
      if txn:
        time = cpuInfo.convertCyclesToTime(txn.getElapsedTsc())
        TxnAggregator._addOrUpdateContainer(elapsedTscGroup, lambda v: [v], classifier, txn, time)
    return elapsedTscGroup
Ejemplo n.º 3
0
  def groupTxns(txnSubCollection, classifier=DefaultClassifier(), mustHaveProbes=None):
    """
    Aggregates transactions by their resepective categories

    :param txnSubCollection: Transaction subcollection to be aggregated
    :param classifier: Predicate to classify transactions into different categories
    :param mustHaveProbes: Probes used to exclude transaction from aggregation

    """
    groupMap = {}

    # classifiy the counter breakups into categories
    for txn in txnSubCollection:
      if not mustHaveProbes or txn.hasProbes(mustHaveProbes):
        TxnAggregator._addOrUpdateContainer(
          groupMap, lambda t: txnSubCollectionFactory(txnSubCollection, t),
          classifier, txn, txn
        )
    return groupMap
Ejemplo n.º 4
0
  def groupElapsedTscByScope(txnSubCollection, beginProbe, endProbe, classifier=DefaultClassifier()):
    """
    Aggregates elapsed tsc values by category

    :param txnSubCollection: Transaction subcollection to be aggregated
    :param beginProbe: Begin probe used for elapsed tsc computation
    :param endProbe: End probe used for elapsed tsc computation
    :param classifier: Predicate to classify transactions into different categories

    """
    elapsedTscGroup = {}
    for txn in txnSubCollection:
      if txn.hasProbes([beginProbe, endProbe]):
        beginCounter = txn.getCounterForProbe(beginProbe)
        endCounter = txn.getCounterForProbe(endProbe)
        TxnAggregator._addOrUpdateContainer(
          elapsedTscGroup, lambda v: [v], classifier, txn,
          endCounter.tsc - beginCounter.tsc
        )
    return elapsedTscGroup
Ejemplo n.º 5
0
  def profile(app, profileInfo, reportName, reportPath, dryRun, # pylint: disable=too-many-locals
    heartbeatInterval=120, samplesFileSize=None, interactive=True, duration=None, cprofile=None):
    """
    Orchestrates a Xpedite profile session

    The method starts a profile session by instantiating a xpedite runtime.
    The runtime is kept alive till one of the following conditions are met
    1. The user ends the interactive session by a key press
    2. The total duration for the session elapses
    3. The connection to the profiling target gets closed or disconnected

    Reports and benchmarks are generated at the end of the session

    :param app: An instance of xpedite app, to interact with target application
    :param profileInfo: Parameters and settings for the profile session
    :type profileInfo: xpedite.profileInfo.ProfileInfo
    :param reportName: Name of the profile report
    :type reportName: str
    :param reportPath: Path to persist profile data for benchmarking
    :type reportPath: str
    :param dryRun: Flag to enable simulation of profiling target
    :type dryRun: bool
    :param heartbeatInterval: Heartbeat interval for profiler's tcp connection
    :type heartbeatInterval: int
    :param samplesFileSize: Max size of data files used to store samples
    :type samplesFileSize: int
    :param interactive: Flag to enable, an interactive profiling session (Default value = True)
    :type interactive: bool
    :param duration: Profile duration - The session is automatically terminated after elapse
                     of duration seconds (Default value = None)
    :type duration: int
    :param cprofile: Handle to capture self profile Xpedite report generation code (Default value = None)
    :type cprofile: C{xpedite.selfProfile.CProfile}

    """
    import time
    import select
    from xpedite.profiler.runtime import Runtime
    from xpedite.txn.classifier import DefaultClassifier

    runtime = Runtime(
      app=app, probes=profileInfo.probes, pmc=profileInfo.pmc, cpuSet=profileInfo.cpuSet,
      pollInterval=1, samplesFileSize=samplesFileSize,
    )
    if not dryRun:
      begin = time.time()
      elapsed = 0
      duration = int(duration) if duration is not None else None

      if interactive:
        LOGGER.info('press RETURN key to, end live profile and generate report ...')

      while True:
        timeout = min(heartbeatInterval, duration - elapsed) if duration is not None else heartbeatInterval
        eof = False
        if interactive:
          rlist, _, _ = select.select([sys.stdin], [], [], timeout)
          eof = sys.stdin in rlist
        else:
          time.sleep(timeout)
        elapsed = time.time() - begin
        LOGGER.debug('profile active - elapsed %d / %s seconds | EOF %s', int(elapsed), duration, eof)
        if eof or (duration and elapsed >= duration):
          break
        try:
          app.ping(keepAlive=True)
        except Exception:
          break
    classifier = profileInfo.classifier if profileInfo.classifier else DefaultClassifier()

    if cprofile:
      cprofile.enable()

    report = runtime.report(reportName=reportName, benchmarkPaths=profileInfo.benchmarkPaths
        , classifier=classifier, resultOrder=profileInfo.resultOrder, txnFilter=profileInfo.txnFilter)
    if reportPath:
      report.makeBenchmark(reportPath)
    return report