Home | History | Annotate | Download | only in metrics
      1 #!/usr/bin/env python
      2 #
      3 #   Copyright 2017 - The Android Open Source Project
      4 #
      5 #   Licensed under the Apache License, Version 2.0 (the "License");
      6 #   you may not use this file except in compliance with the License.
      7 #   You may obtain a copy of the License at
      8 #
      9 #       http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 #   Unless required by applicable law or agreed to in writing, software
     12 #   distributed under the License is distributed on an "AS IS" BASIS,
     13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 #   See the License for the specific language governing permissions and
     15 #   limitations under the License.
     16 
     17 import itertools
     18 from metrics.metric import Metric
     19 
     20 
     21 class ProcessTimeMetric(Metric):
     22     TIME_COMMAND = 'ps -p %s -o etimes,command | sed 1d'
     23     # Number of seconds in 24 hours
     24     MIN_TIME = 86400
     25     # Fields for response dictionary
     26     ADB_PROCESSES = 'adb_processes'
     27     NUM_ADB_PROCESSES = 'num_adb_processes'
     28     FASTBOOT_PROCESSES = 'fastboot_processes'
     29     NUM_FASTBOOT_PROCESSES = 'num_fastboot_processes'
     30 
     31     def gather_metric(self):
     32         """Returns ADB and Fastboot processes and their time elapsed
     33 
     34         Returns:
     35             A dictionary with adb/fastboot_processes as a list of serial nums or
     36             NONE if number wasn't in command. num_adb/fastboot_processes as
     37             the number of serials in list.
     38         """
     39         # Get the process ids
     40         pids = self.get_adb_fastboot_pids()
     41 
     42         # Get elapsed time for selected pids
     43         adb_processes, fastboot_processes = [], []
     44         for pid in pids:
     45             # Sample output:
     46             # 232893 fastboot -s FA6BM0305019 -w
     47 
     48             output = self._shell.run(self.TIME_COMMAND % pid).stdout
     49             spl_ln = output.split()
     50 
     51             # There is a potential race condition between getting pids, and the
     52             # pid then dying, so we must check that there is output.
     53             if spl_ln:
     54                 # pull out time in seconds
     55                 time = int(spl_ln[0])
     56             else:
     57                 continue
     58 
     59             # We only care about processes older than the min time
     60             if time > self.MIN_TIME:
     61                 # ignore fork-server command, because it's not a problematic process
     62                 if 'fork-server' not in output:
     63                     # get serial number, which defaults to none
     64                     serial_number = None
     65                     if '-s' in spl_ln:
     66                         sn_index = spl_ln.index('-s')
     67                         # avoid indexing out of range
     68                         if sn_index + 1 < len(spl_ln):
     69                             serial_number = spl_ln[sn_index + 1]
     70                     # append to proper list
     71                     if 'fastboot' in output:
     72                         fastboot_processes.append(serial_number)
     73                     elif 'adb' in output:
     74                         adb_processes.append(serial_number)
     75 
     76         # Create response dictionary
     77         response = {
     78             self.ADB_PROCESSES: adb_processes,
     79             self.NUM_ADB_PROCESSES: len(adb_processes),
     80             self.FASTBOOT_PROCESSES: fastboot_processes,
     81             self.NUM_FASTBOOT_PROCESSES: len(fastboot_processes)
     82         }
     83         return response
     84 
     85     def get_adb_fastboot_pids(self):
     86         """Finds a list of ADB and Fastboot process ids.
     87 
     88         Returns:
     89           A list of PID strings
     90         """
     91         # Get ids of processes with 'adb' or 'fastboot' in name
     92         adb_result = self._shell.get_command_pids('adb')
     93         fastboot_result = self._shell.get_command_pids('fastboot')
     94         # concatenate two generator objects, return as list
     95         return list(itertools.chain(adb_result, fastboot_result))
     96