class_docstr: Object for monitoring
  
  Must be child of engine
  
  Handles signal messages and watches Engine process for exiting
class_docstr_tok: ["Object","for","monitoring","Must","be","child","of","engine","Handles","signal","messages","and","watches","Engine","process","for","exiting"]
code: def __init__(
      self,
      *,
      pid: int,
      engine_id: int,
      control_url: str,
      registration_url: str,
      identity: bytes,
      curve_serverkey: bytes,
      curve_publickey: bytes,
      curve_secretkey: bytes,
      config: Config,
      pipe,
      log_level: int = logging.INFO,
  ):
      self.pid = pid
      self.engine_id = engine_id
      self.parent_process = psutil.Process(self.pid)
      self.control_url = control_url
      self.registration_url = registration_url
      self.identity = identity
      self.curve_serverkey = curve_serverkey
      self.curve_publickey = curve_publickey
      self.curve_secretkey = curve_secretkey
      self.config = config
      self.pipe = pipe
      self.session = Session(config=self.config)
  
      self.log = local_logger(
          f"{self.__class__.__name__}.{engine_id}", log_level
      )
      self.log.propagate = False
  
      self.control_handlers = {
          "signal_request": self.signal_request,
      }
      self._finish_called = False
  
imports: import asyncio
  import logging
  import os
  import pickle
  import signal
  import sys
  from subprocess import PIPE, Popen
  from threading import Thread
  import psutil
  import zmq
  from jupyter_client.session import Session
  from tornado.ioloop import IOLoop
  from traitlets.config import Config
  from zmq.eventloop.zmqstream import ZMQStream
  from ipyparallel import error, util
  from ipyparallel.util import local_logger
label_desc: Use image node_id 1 to create a new KernelNanny object  with example: obj = KernelNanny()