예제 #1
0
 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__()
예제 #2
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 setUp(self):
     with patch("auklet.monitoring.processing.Client._register_device",
                new=self.__register_device):
         self.client = Client(apikey="",
                              app_id="",
                              base_url="https://api-staging.auklet.io/")
         with patch('auklet.broker.MQTTClient._get_conf') as _get_conf:
             _get_conf.side_effect = self.get_conf
             self.broker = MQTTClient(self.client)
예제 #4
0
 def setUp(self):
     with patch("auklet.monitoring.processing.Client._register_device",
                new=self.__register_device):
         self.client = Client(
             api_key="",
             app_id="",
             base_url="https://api-staging.auklet.io/",
             auklet_dir=".auklet",
         )
예제 #5
0
 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__()
예제 #6
0
 def setUp(self):
     with patch("auklet.monitoring.processing.Client._register_device",
                new=self.__register_device):
         self.client = Client(api_key="",
                              app_id="",
                              base_url="https://api-staging.auklet.io/",
                              auklet_dir=".auklet")
         with patch('auklet.broker.MQTTClient._get_conf') as _get_conf:
             with patch("os.path.isfile") as is_file_mock:
                 is_file_mock.return_value = False
                 _get_conf.side_effect = self.get_conf
                 self.broker = MQTTClient(self.client)
예제 #7
0
class TestClient(unittest.TestCase):
    data = ast.literal_eval(str(data_factory.MonitoringDataFactory()))

    def setUp(self):
        with patch("auklet.monitoring.processing.Client._register_device",
                   new=self.__register_device):
            self.broker_username = "******"
            self.broker_password = "******"
            self.client = Client(api_key="",
                                 app_id="",
                                 base_url="https://api-staging.auklet.io/",
                                 auklet_dir=".auklet")
            self.monitoring_tree = MonitoringTree()

    def test_get_config(self):
        class MockRequest:
            def __init__(self, *args, **kwargs):
                pass

            def get_type(self):
                pass

        class res:
            def read(self):
                return str(json.dumps({"config": ""})).encode()

        with patch('auklet.utils.urlopen') as _urlopen:
            with patch('auklet.utils.Request') as _Request:
                _Request.side_effect = MockRequest
                _urlopen.return_value = res()
                self.assertIsNotNone(self.client._get_config())

    def test_register_device(self):
        with patch("json.loads", return_value=False):
            with patch("auklet.monitoring.processing.Client."
                       "create_device") as create_mock:
                create_mock.return_value = {
                    "client_password": "******",
                    "client_id": "12345",
                    "id": "12345",
                    "organization": "12345"
                }
                self.assertTrue(self.client._register_device())

        with patch("json.loads") as loads_mock:
            with patch("auklet.monitoring.processing.Client."
                       "check_device") as check_mock:
                loads_mock.return_value = {"id": "12345"}
                check_mock.return_value = ({
                    "client_password": "******",
                    "client_id": "12345",
                    "id": "12345",
                    "organization": "12345"
                }, True)
                self.assertTrue(self.client._register_device())

    def test_check_device(self):
        with patch("auklet.monitoring.processing.open_auklet_url",
                   return_value=self.MockResult()):
            res = self.client.check_device("123")
            self.assertFalse(res[1])
        with patch("auklet.monitoring.processing.open_auklet_url",
                   side_effect=HTTPError("url", 404, "failed post",
                                         {"test": "header"}, None)):
            res = self.client.check_device("123")
            self.assertTrue(res[1])

    def test_create_device(self):
        with patch("auklet.monitoring.processing.post_auklet_url",
                   return_value=self.MockResult()):
            res = self.client.create_device()
            self.assertEqual(res.read(), b(json.dumps({"test": "object"})))

    def test_load_limits(self):
        default_data = data_factory.LimitsGenerator()
        self.write_load_limits_test(default_data)
        self.build_load_limits_test(1, self.client.data_day)

        self.assertEqual(None, self.client.data_limit)
        self.assertEqual(None, self.client.offline_limit)

        data = data_factory.LimitsGenerator(cellular_data_limit=10)
        self.write_load_limits_test(data)
        self.client._load_limits()
        self.build_load_limits_test(10000000.0, self.client.data_limit)

        data = data_factory.LimitsGenerator(cellular_data_limit="null",
                                            storage_limit=10)
        self.write_load_limits_test(data)
        self.client._load_limits()
        self.build_load_limits_test(10000000.0, self.client.offline_limit)

        with open(self.client.limits_filename, "w") as limits:
            limits.write(str(default_data))

        self.base_patch_side_effect_with_none(
            'auklet.monitoring.processing.open', IOError,
            self.client._load_limits)

    def test_build_usage_json(self):
        data = self.client._build_usage_json()
        for value in data.values():
            self.assertNotEqual(value, None)

    def test_update_usage_file(self):
        os.system("rm -R .auklet")
        self.assertFalse(self.client._update_usage_file())
        os.system("mkdir .auklet")
        os.system("touch %s" % self.client.offline_filename)
        os.system("touch .auklet/version")

    def test_check_data_limit(self):
        self.client.offline_limit = None
        self.assertTrue(
            self.client.check_data_limit(data=self.data,
                                         current_use=0,
                                         offline=True))

        self.client.data_limit = None
        self.assertTrue(
            self.client.check_data_limit(data=self.data, current_use=0))

        self.client.offline_limit = self.client.data_limit = 1
        self.assertFalse(
            self.client.check_data_limit(data=self.data, current_use=0))

        self.client.data_limit = 1000
        self.client.check_data_limit(data=self.data,
                                     current_use=0,
                                     offline=True)
        self.assertNotEqual(self.client.offline_current, 0)

        self.client.check_data_limit(data=self.data, current_use=0)
        self.assertNotEqual(self.client.data_current, 0)

        self.assertTrue(
            self.client.check_data_limit(data=self.data, current_use=0))

    def test_check_date(self):
        self.client.data_day = datetime.today().day
        self.client.data_current = 1000
        self.client.reset_data = True
        self.client.check_date()
        self.assertEqual(self.client.data_current, 0)
        self.assertEqual(self.client.reset_data, False)
        self.client.data_day = datetime.today().day + 1
        self.client.check_date()
        self.assertTrue(self.client.reset_data)

    def test_update_limits(self):
        with patch('auklet.monitoring.processing.Client._get_config',
                   new=self._get_config):
            self.assertEqual(self.client.update_limits(), 60000)
            self.none = False

            self.cellular_data_limit = 1000
            self.client.update_limits()
            self.assertEqual(self.client.data_limit, 1000000000.0)
            self.cellular_data_limit = None

            self.storage_limit = 1000
            self.client.update_limits()
            self.assertEqual(self.client.offline_limit, 1000000000.0)
            self.storage_limit = None

            self.cell_plan_date = 10
            self.client.update_limits()
            self.assertEqual(self.client.data_day, 10)
            self.cell_plan_date = 1

            self.assertEqual(self.client.update_limits(), 60000)

    def test_build_event_data(self):
        with patch("auklet.monitoring.processing.traceback.format_exc",
                   new=self.mock_format_exc):
            self.assertBuildEventData(self.client.build_event_data)

    def test_build_log_data(self):
        self.assertBuildLogData(
            self.client.build_log_data(msg='msg',
                                       data_type='data_type',
                                       level='level'))

    def test_build_msgpack_event_data(self):
        with patch("auklet.monitoring.processing.traceback.format_exc",
                   new=self.mock_format_exc):
            self.assertBuildEventData(self.client.build_msgpack_event_data)

    def test_build_msgpack_log_data(self):
        self.assertBuildLogData(
            self.client.build_msgpack_log_data(msg='msg',
                                               data_type='data_type',
                                               level='level'))

    def mock_format_exc(self):
        return ""

    @staticmethod
    def get_mock_event(exc_type=None, tb=None, tree=None, abs_path=None):
        return {
            "stackTrace": [{
                "functionName": "",
                "filePath": "",
                "lineNumber": 0,
                "locals": {
                    "key": "value"
                }
            }]
        }

    def base_patch_side_effect_with_none(self, location, side_effect, actual):
        with patch(location) as _base:
            _base.side_effect = side_effect
            self.assertIsNone(actual())

    def build_load_limits_test(self, expected, actual):
        self.assertEqual(expected, actual)

    def write_load_limits_test(self, data):
        filename = self.client.limits_filename
        with open(filename, "w") as limits:
            limits.write(str(data))

    def assertBuildEventData(self, function):
        def traceback():
            class Code:
                co_code = "file_name"
                co_name = ""

            class Frame:
                f_code = Code()
                f_lineno = 0
                f_locals = ""

            class Traceback:
                tb_lineno = 0
                tb_frame = Frame()
                tb_next = None

            return Traceback

        with patch('auklet.monitoring.processing.Event',
                   new=self.get_mock_event):
            self.monitoring_tree.cached_filenames["file_name"] = "file_name"
            self.assertNotEqual(
                function(type=Exception,
                         tb=traceback(),
                         tree=self.monitoring_tree), None)

    def assertBuildLogData(self, function):
        self.assertNotEqual(function, None)

    none = True
    cellular_data_limit = None
    storage_limit = None
    cell_plan_date = 1

    def _get_config(self):
        if self.none:
            return None
        else:
            return {
                "storage": {
                    "storage_limit": self.storage_limit
                },
                "emission_period": 60,
                "features": {
                    "performance_metrics": True,
                    "user_metrics": False
                },
                "data": {
                    "cellular_data_limit": self.cellular_data_limit,
                    "normalized_cell_plan_date": self.cell_plan_date
                }
            }

    @staticmethod
    def __register_device(self):
        return True

    class MockResult(object):
        def read(self):
            return b(json.dumps({"test": "object"}))
예제 #8
0
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")