class_docstr: CPU and Memory logger.
  
  Class for starting a monitor job of CPU and memory utilization in the
  background in a Python script. The ``monitor`` class records the
  ``cpu_percent``, ``rss`` and ``vms`` as collected by the
  psutil_ library for the parent process' pid.
  
  CPU usage and memory utilization are stored as attributes in numpy arrays.
  
  .. _psutil: https://pypi.python.org/pypi/psutil
  
  Examples
  --------
  >>> from time import sleep
  >>> from mlens.utils.utils import CMLog
  >>> cm = CMLog(verbose=True)
  >>> cm.monitor(2, 0.5)
  >>> _ = [i for i in range(10000000)]
  >>>
  >>> # Collecting before completion triggers a message but no error
  >>> cm._collect()
  >>>
  >>> sleep(2)
  >>> cm._collect()
  >>> print('CPU usage:')
  >>> cm.cpu
  [CMLog] Monitoring for 2 seconds with checks every 0.5 seconds.
  [CMLog] Job not finished. Cannot _collect yet.
  [CMLog] Collecting... done. Read 4 lines in 0.000 seconds.
  CPU usage:
  array([ 50. ,  22.4,   6. ,  11.9])
  
  Raises
  ------
  ImportError :
      Depends on psutil. If not installed, raises ImportError on
      instantiation.
  
  Parameters
  ----------
  verbose : bool
      whether to notify of job start.
docstr: Start monitoring CPU and memory usage.
  
  Parameters
  ----------
  stop : float or None (default = None)
      seconds to monitor for. If None, monitors until ``_collect`` is
      called.
  
  ival : float (default=0.1)
      interval of monitoring.
  
  kill : bool (default = True)
      whether to kill the monitoring job if ``_collect`` is called before
      timeout (``stop``). If set to False, calling ``_collect`` will
      cause the instance to wait until the job completes.
docstr_tok: ["Start","monitoring","CPU","and","memory","usage",".","Parameters","--","--","--","--","--","stop",":","float","or","None","(","default","=","None",")","seconds","to","monitor","for",".","If","None",",","monitors","until","``","_collect","``","is","called",".","ival",":","float","(","default=0.1",")","interval","of","monitoring",".","kill",":","bool","(","default","=","True",")","whether","to","kill","the","monitoring","job","if","``","_collect","``","is","called","before","timeout","(","``","stop","``",")",".","If","set","to","False",",","calling","``","_collect","``","will","cause","the","instance","to","wait","until","the","job","completes","."]
code: def monitor(self, stop=None, ival=0.1, kill=True):
      """Start monitoring CPU and memory usage.
  
      Parameters
      ----------
      stop : float or None (default = None)
          seconds to monitor for. If None, monitors until ``_collect`` is
          called.
  
      ival : float (default=0.1)
          interval of monitoring.
  
      kill : bool (default = True)
          whether to kill the monitoring job if ``_collect`` is called before
          timeout (``stop``). If set to False, calling ``_collect`` will
          cause the instance to wait until the job completes.
      """
      if stop is None and not kill:
          raise ValueError(
              "If no time limit is set 'kill' must be enabled."
          )
  
      self._t0 = time()
      self._stop = stop
      self._kill = kill
  
      # Delete previous job data to avoid confusion
      try:
          del self.cpu
          del self.rss
          del self.vms
      except AttributeError:
          pass
  
      if self.verbose:
          if self._stop is not None:
              safe_print(
                  "[CMLog] Monitoring for {} seconds with checks "
                  "every {} seconds.".format(stop, ival)
              )
          else:
              safe_print(
                  "[CMLog] Monitoring until collection with checks "
                  "every {} seconds.".format(ival)
              )
  
      # Initialize subprocess
      self._out = subprocess.Popen(
          [
              sys.executable,
              "-c",
              "from mlens.utils.utils import _recorder; "
              "_recorder({}, {}, {})".format(
                  self.pid, stop, float(ival)
              ),
          ],
          stdout=subprocess.PIPE,
      )
      return
  
imports: from __future__ import division, print_function, with_statement
  import os
  import sys
  import warnings
  import subprocess
  from numpy import array
  from ..config import get_ivals
  from .exceptions import ParallelProcessingError, ParallelProcessingWarning
  from time import sleep
label_desc: Use image node_id 2 for calling the CMLog obj's underlying member method code with example usage: obj.monitor(stop, ival, kill) without return types