def __init__(self,
              api_key=None,
              app_id=None,
              release=None,
              version="",
              base_url="https://api.auklet.io/",
              monitoring=True):
     if release is None:
         raise AukletConfigurationError(
             "Must include release in Monitoring Creation")
     global except_hook_set
     sys.excepthook = self.handle_exc
     if not except_hook_set:
         # ensure not attempting to set threading excepthook more than once
         setup_thread_excepthook()
         except_hook_set = True
     self.auklet_dir = create_dir()
     self.version = version
     self.app_id = app_id
     self.mac_hash = get_mac()
     self.client = Client(api_key, app_id, release, base_url, self.mac_hash,
                          self.version, self.auklet_dir)
     self.emission_rate = update_data_limits(self.client)
     self.tree = MonitoringTree(self.mac_hash)
     self.broker = MQTTClient(self.client)
     self.monitor = monitoring
     signal.signal(self.sig, self.sample)
     signal.siginterrupt(self.sig, False)
     super(Monitoring, self).__init__()
 def setUp(self):
     self.tree = MonitoringTree()
     self.patcher = patch(
         'auklet.stats.MonitoringTree.get_filename', new=self.get_filename)
     self.patcher.start()
     self.event = Event(
         exc_type=str, tb=self.get_traceback(),
         tree=self.tree, abs_path="/")
示例#3
0
 def setUp(self):
     with patch("auklet.monitoring.processing.Client._register_device",
                new=self.__register_device):
         self.broker_username = "******"
         self.broker_password = "******"
         self.client = Client(apikey="",
                              app_id="",
                              base_url="https://api-staging.auklet.io/")
         self.monitoring_tree = MonitoringTree()
 def __init__(self, apikey=None, app_id=None,
              base_url="https://api.auklet.io/", monitoring=True):
     global except_hook_set
     sys.excepthook = self.handle_exc
     if not except_hook_set:
         # ensure not attempting to set threading excepthook more than once
         setup_thread_excepthook()
         except_hook_set = True
     self.app_id = app_id
     self.mac_hash = get_mac()
     self.client = Client(apikey, app_id, base_url, self.mac_hash)
     self.emission_rate = self.client.update_limits()
     self.tree = MonitoringTree(self.mac_hash)
     self.broker = MQTTClient(self.client)
     self.monitor = monitoring
     signal.signal(self.sig, self.sample)
     signal.siginterrupt(self.sig, False)
     super(Monitoring, self).__init__()
class Monitoring(AukletLogging):
    #: The frames sampler.  Usually it is an instance of :class:`profiling.
    #: sampling.samplers.Sampler`
    sampler = None
    tree = None
    client = None
    broker = None
    version = ""
    monitor = True
    samples_taken = 0
    timer = signal.ITIMER_PROF
    sig = signal.SIGPROF
    stopping = False
    stopped = False

    interval = 1e-3  # 1ms

    total_samples = 0

    emission_rate = 60000  # 60 seconds
    hour = 3600000  # 1 hour

    def __init__(self,
                 api_key=None,
                 app_id=None,
                 release=None,
                 version="",
                 base_url="https://api.auklet.io/",
                 monitoring=True):
        if release is None:
            raise AukletConfigurationError(
                "Must include release in Monitoring Creation")
        global except_hook_set
        sys.excepthook = self.handle_exc
        if not except_hook_set:
            # ensure not attempting to set threading excepthook more than once
            setup_thread_excepthook()
            except_hook_set = True
        self.auklet_dir = create_dir()
        self.version = version
        self.app_id = app_id
        self.mac_hash = get_mac()
        self.client = Client(api_key, app_id, release, base_url, self.mac_hash,
                             self.version, self.auklet_dir)
        self.emission_rate = update_data_limits(self.client)
        self.tree = MonitoringTree(self.mac_hash)
        self.broker = MQTTClient(self.client)
        self.monitor = monitoring
        signal.signal(self.sig, self.sample)
        signal.siginterrupt(self.sig, False)
        super(Monitoring, self).__init__()

    def start(self):
        # Set a timer which fires a SIGALRM every interval seconds
        if self.monitor:
            signal.setitimer(self.timer, self.interval, self.interval)

    def stop(self):
        self.stopping = True
        self.wait_for_stop()

    def wait_for_stop(self):
        while not self.stopped:
            pass

    def sample(self, sig, current_frame):
        """Samples the given frame."""
        if self.stopping:
            signal.setitimer(self.timer, 0, 0)
            self.stopped = True
            return
        current_thread = _thread.get_ident()
        for thread_id, frame in iteritems(sys._current_frames()):
            if thread_id == current_thread:
                frame = current_frame
            frames = []
            while frame is not None:
                frames.append(frame)
                frame = frame.f_back
            self.tree.update_hash(frames)
        self.total_samples += 1
        self.samples_taken += 1
        self.process_periodic()

    def process_periodic(self):
        if self.total_samples % self.emission_rate == 0:
            self.broker.produce(self.tree.build_msgpack_tree(self.client))
            self.tree.clear_root()
            self.samples_taken = 0
        if self.total_samples % self.hour == 0:
            self.emission_rate = update_data_limits(self.client)
            self.client.check_date()

    def handle_exc(self, type, value, traceback):
        test = self.client.build_msgpack_event_data(type, traceback, self.tree)
        self.broker.produce(test, "event")
        sys.__excepthook__(type, value, traceback)

    def send(self, msg, data_type="motion"):
        self.broker.produce(
            self.client.build_msgpack_send_data(msg, data_type), "send")

    def log(self, msg, data_type, level="INFO"):
        self.broker.produce(
            self.client.build_msgpack_log_data(msg, data_type, level), "event")
 def setUp(self):
     self.monitoring_tree = MonitoringTree()
     self.function = Function(line_num=0, func_name="UnitTest")
class TestMonitoringTree(unittest.TestCase):
    def setUp(self):
        self.monitoring_tree = MonitoringTree()
        self.function = Function(line_num=0, func_name="UnitTest")

    def test_get_filename(self):
        self.monitoring_tree.cached_filenames.clear()
        self.monitoring_tree.cached_filenames['file_name'] = "file_name"
        self.assertEqual(
            self.monitoring_tree.get_filename(code=self.get_code(),
                                              frame="frame"),
            self.get_code().co_code)

        self.monitoring_tree.cached_filenames.clear()
        self.monitoring_tree.cached_filenames['file_name'] = None
        self.assertIsNone(
            self.monitoring_tree.get_filename(code=self.get_code(),
                                              frame="frame"))

        with patch('inspect.getsourcefile') as _get_source_file:
            _get_source_file.return_value = "file_name"
            self.assertIsNotNone(
                self.monitoring_tree.get_filename(code=self.get_code(),
                                                  frame="frame"))

    def test_create_frame_function(self):
        class Code:
            co_firstlineno = 0
            co_name = ""

        class Frame:
            f_code = Code

        self.assertIsNotNone(
            self.monitoring_tree._create_frame_func("", root=True))
        with patch(
                'auklet.stats.MonitoringTree.get_filename') as _get_filename:
            _get_filename.return_value = None
            self.assertIsNotNone(
                self.monitoring_tree._create_frame_func(Frame))
            self.monitoring_tree.abs_path = "/tests/"
            _get_filename.return_value = "/tests/test_stats.py"
            self.assertIsNotNone(
                self.monitoring_tree._create_frame_func(Frame))

    def test__build_tree(self):
        class Code:
            co_firstlineno = 0
            co_name = ""
            co_code = ""

        class Frame:
            f_code = Code
            file_path = ""
            children = []

        self.assertIsNotNone(self.monitoring_tree._build_tree([Frame, Frame]))

        with patch(
                'auklet.stats.MonitoringTree._create_frame_func') as \
                create_frame_func:
            create_frame_func.return_value = Frame
            self.monitoring_tree._build_tree([Frame])
        self.assertIsNotNone(self.monitoring_tree._build_tree([Frame, Frame]))

    def test_update_sample_count(self):
        self.assertTrue(
            self.monitoring_tree._update_sample_count(
                parent=None, new_parent=self.get_new_parent()))

        if sys.version_info < (3, ):
            self.build_assert_raises(
                "class NewChild has no attribute 'children'", True)
            self.build_assert_raises(
                "Parent instance has no attribute 'children'", False)
        else:
            self.build_assert_raises(
                "type object 'NewChild' has no attribute 'children'", True)
            self.build_assert_raises(
                "'Parent' object has no attribute 'children'", False)

    def test_update_hash(self):
        self.assertNotEqual(self.monitoring_tree.update_hash(new_stack=""),
                            None)

        def _update_sample_count(self, parent, new_parent):
            global test_update_hash_parent  # used to tell if hash was created
            test_update_hash_parent = parent

        self.monitoring_tree.root_func = self.function
        with patch('auklet.stats.MonitoringTree._update_sample_count',
                   new=_update_sample_count):
            self.monitoring_tree.update_hash(new_stack="")

        self.assertNotEqual(test_update_hash_parent, None)  # global used here

    def test_clear_root(self):
        self.monitoring_tree.root_func = self.get_root_function()
        self.assertTrue(self.monitoring_tree.clear_root())
        self.assertEqual(self.monitoring_tree.root_func, None)

    def test_build_tree(self):
        self.monitoring_tree.root_func = None
        self.assertEqual({}, self.monitoring_tree.build_tree(self.Client()))
        self.monitoring_tree.root_func = self.get_root_function()
        self.assertIsNotNone(self.monitoring_tree.build_tree(self.Client()))

    def test_build_msgpack_tree(self):
        self.monitoring_tree.root_func = self.get_root_function()
        self.assertNotEqual(
            self.monitoring_tree.build_msgpack_tree(self.Client()), None)

    def get_code(self):
        class Code:
            co_code = "file_name"
            co_firstlineno = 0
            co_name = ""

        return Code

    def get_frame(self):
        class Frame:
            f_code = self.get_code()

        frame = [Frame, Frame]
        return frame

    def get_root_function(self):
        return {
            'callees': [],
            'filePath': None,
            'functionName': 'root',
            'lineNumber': 1,
            'nCalls': 1,
            'nSamples': 1
        }

    def get_parent(self):
        pass

    def get_new_parent(self):
        class Parent:
            children = []

        return Parent

    def build_assert_raises(self, expected, child_state):
        global child_exists  # For some reason this needs to be done twice
        child_exists = child_state
        with self.assertRaises(AttributeError) as error:
            self.monitoring_tree._update_sample_count(
                parent=self.Parent(), new_parent=self.NewParent())
        self.assertEqual(expected, str(error.exception))

    class Client:
        broker_username = "******"
        abs_path = "/Test/abs/path/"
        app_id = "12345"
        version = None

    class Parent:
        calls = 0
        samples = 0

        def has_child(self, new_child):
            global child_exists  # Must be used to pass variable in class
            if child_exists:

                class Child:
                    calls = 0
                    samples = 0

                child = Child
                child_exists = False
                return child
            else:
                return False

    class NewParent:
        class NewChild:
            calls = 0

        children = [NewChild]