src/naarad/metrics/procinterrupts_metric.py
def parse(self):
    """
    Processes the files for each IRQ and each CPU in terms of the differences.
    Also produces accumulated interrupt count differences for each set of Ethernet IRQs.
    Generally Ethernet has 8 TxRx IRQs thus all are combined so that one can see the overall interrupts being generated by the NIC.

    Simplified Interrupt File Format: (See examples for example log)

                                        CPU0   CPU1
      2014-10-29 00:27:42.15161    59:    29      2    IR-IO-APIC-edge    timer
      2014-10-29 00:27:42.15161    60:  2123      0    IR-PCI-MSI-edge    eth0

                                        CPU0   CPU1
      2014-10-29 00:27:42.15161    59:    29      2    IR-IO-APIC-edge    timer
      2014-10-29 00:27:42.15161    60:  2123      0    IR-PCI-MSI-edge    eth0

    :returns: True or False whether parsing was successful or not.
    """
    if not os.path.isdir(self.outdir):
      os.makedirs(self.outdir)
    if not os.path.isdir(self.resource_directory):
      os.makedirs(self.resource_directory)

    data = {}
    for input_file in self.infile_list:
      logger.info('Processing : %s', input_file)
      timestamp_format = None
      with open(input_file, 'r') as infile:
        # Get the header for this file
        cpus = self.find_header(infile)
        if len(cpus) == 0:  # Make sure we have header otherwise go to next file
          logger.error("Header not found for file: %s", input_file)
          continue

        # Parse the actual file after header
        prev_data = None    # Stores the previous interval's log data
        curr_data = {}      # Stores the current interval's log data
        eth_data = {}
        for line in infile:
          if self.is_header_line(line):  # New section so save old and aggregate ETH
            prev_data = curr_data
            curr_data = {}
            # New section so store the collected Ethernet data
            # Example Aggregate metric: PROCINTERRUPTS.AGGREGATE.eth0
            for eth in eth_data:
              outcsv = self.get_csv('AGGREGATE', eth)
              if outcsv not in data:
                data[outcsv] = []
              data[outcsv].append(ts + ',' + str(eth_data[eth]))
            eth_data = {}
            continue

          words = line.split()
          if len(words) <= 4:  # Does not have any CPU data so skip
            continue

          # Process timestamp or determine timestamp
          ts = words[0] + " " + words[1]
          if not timestamp_format or timestamp_format == 'unknown':
            timestamp_format = naarad.utils.detect_timestamp_format(ts)
          if timestamp_format == 'unknown':
            continue
          ts = naarad.utils.get_standardized_timestamp(ts, timestamp_format)
          if self.ts_out_of_range(ts):  # See if time is in range
            continue

          # Process data lines
          # Note that some IRQs such as ERR and MIS do not have device nor ascii name
          device = words[2].strip(':')  # Get IRQ Number/Name
          if re.match("\d+", device):
            # Devices with digits need ASCII name if exists
            if (4 + len(cpus)) < len(words):
              device = words[4 + len(cpus)] + "-IRQ" + device
            else:
              device = "IRQ" + device
          else:
            # For devices with IRQ # that aren't digits then has description
            device = "-".join(words[(3 + len(cpus)):]) + "-IRQ" + device

          # Deal with each column worth of data
          for (cpu, datum) in zip(cpus, words[3:]):
            if self.CPUS and cpu not in self.CPUS:  # Skip if config defines which CPUs to look at
              continue
            outcsv = self.get_csv(cpu, device)
            curr_data[outcsv] = int(datum)
            if outcsv in data:
              datum = int(datum) - prev_data[outcsv]  # prev_data exists since outcsv exists in data
            else:
              data[outcsv] = []
              datum = 0  # First data point is set to 0
            # Store data point
            data[outcsv].append(ts + ',' + str(datum))

            # Deal with accumulating aggregate data for Ethernet
            m = re.search("(?P<eth>eth\d)", device)
            if m:
              eth = m.group('eth')
              if eth not in eth_data:
                eth_data[eth] = 0
              eth_data[eth] += datum

    # Post processing, putting data in csv files
    for csv in data.keys():
      self.csv_files.append(csv)
      with open(csv, 'w') as csvf:
        csvf.write('\n'.join(sorted(data[csv])))
    return True
def parse(self):
    """
    Processes the files for each IRQ and each CPU in terms of the differences.
    Also produces accumulated interrupt count differences for each set of Ethernet IRQs.
    Generally Ethernet has 8 TxRx IRQs thus all are combined so that one can see the overall interrupts being generated by the NIC.

    Simplified Interrupt File Format: (See examples for example log)

                                        CPU0   CPU1
      2014-10-29 00:27:42.15161    59:    29      2    IR-IO-APIC-edge    timer
      2014-10-29 00:27:42.15161    60:  2123      0    IR-PCI-MSI-edge    eth0

                                        CPU0   CPU1
      2014-10-29 00:27:42.15161    59:    29      2    IR-IO-APIC-edge    timer
      2014-10-29 00:27:42.15161    60:  2123      0    IR-PCI-MSI-edge    eth0

    :returns: True or False whether parsing was successful or not.
    """
    if not os.path.isdir(self.outdir):
      os.makedirs(self.outdir)
    if not os.path.isdir(self.resource_directory):
      os.makedirs(self.resource_directory)

    data = {}
    for input_file in self.infile_list:
      logger.info('Processing : %s', input_file)
      timestamp_format = None
      with open(input_file, 'r') as infile:
        # Get the header for this file
        cpus = self.find_header(infile)
        if len(cpus) == 0:  # Make sure we have header otherwise go to next file
          logger.error("Header not found for file: %s", input_file)
          continue

        # Parse the actual file after header
        prev_data = None    # Stores the previous interval's log data
        curr_data = {}      # Stores the current interval's log data
        eth_data = {}
        for line in infile:
          if self.is_header_line(line):  # New section so save old and aggregate ETH
            prev_data = curr_data
            curr_data = {}
            # New section so store the collected Ethernet data
            # Example Aggregate metric: PROCINTERRUPTS.AGGREGATE.eth0
            for eth in eth_data:
              outcsv = self.get_csv('AGGREGATE', eth)
              if outcsv not in data:
                data[outcsv] = []
              data[outcsv].append(ts + ',' + str(eth_data[eth]))
            eth_data = {}
            continue

          words = line.split()
          if len(words) <= 4:  # Does not have any CPU data so skip
            continue

          # Process timestamp or determine timestamp
          ts = words[0] + " " + words[1]
          if not timestamp_format or timestamp_format == 'unknown':
            timestamp_format = naarad.utils.detect_timestamp_format(ts)
          if timestamp_format == 'unknown':
            continue
          ts = naarad.utils.get_standardized_timestamp(ts, timestamp_format)
          if self.ts_out_of_range(ts):  # See if time is in range
            continue

          # Process data lines
          # Note that some IRQs such as ERR and MIS do not have device nor ascii name
          device = words[2].strip(':')  # Get IRQ Number/Name
          if re.match("\d+", device):
            # Devices with digits need ASCII name if exists
            if (4 + len(cpus)) < len(words):
              device = words[4 + len(cpus)] + "-IRQ" + device
            else:
              device = "IRQ" + device
          else:
            # For devices with IRQ # that aren't digits then has description
            device = "-".join(words[(3 + len(cpus)):]) + "-IRQ" + device

          # Deal with each column worth of data
          for (cpu, datum) in zip(cpus, words[3:]):
            if self.CPUS and cpu not in self.CPUS:  # Skip if config defines which CPUs to look at
              continue
            outcsv = self.get_csv(cpu, device)
            curr_data[outcsv] = int(datum)
            if outcsv in data:
              datum = int(datum) - prev_data[outcsv]  # prev_data exists since outcsv exists in data
            else:
              data[outcsv] = []
              datum = 0  # First data point is set to 0
            # Store data point
            data[outcsv].append(ts + ',' + str(datum))

            # Deal with accumulating aggregate data for Ethernet
            m = re.search("(?P<eth>eth\d)", device)
            if m:
              eth = m.group('eth')
              if eth not in eth_data:
                eth_data[eth] = 0
              eth_data[eth] += datum

    # Post processing, putting data in csv files
    for csv in data.keys():
      self.csv_files.append(csv)
      with open(csv, 'w') as csvf:
        csvf.write('\n'.join(sorted(data[csv])))
    return True
Processes the files for each IRQ and each CPU in terms of the differences.
    Also produces accumulated interrupt count differences for each set of Ethernet IRQs.
    Generally Ethernet has 8 TxRx IRQs thus all are combined so that one can see the overall interrupts being generated by the NIC.

    Simplified Interrupt File Format: (See examples for example log)

                                        CPU0   CPU1
      2014-10-29 00:27:42.15161    59:    29      2    IR-IO-APIC-edge    timer
      2014-10-29 00:27:42.15161    60:  2123      0    IR-PCI-MSI-edge    eth0

                                        CPU0   CPU1
      2014-10-29 00:27:42.15161    59:    29      2    IR-IO-APIC-edge    timer
      2014-10-29 00:27:42.15161    60:  2123      0    IR-PCI-MSI-edge    eth0

    :returns: True or False whether parsing was successful or not.