Exemple #1
0
class Test_profile_log(unittest.TestCase):

    def setUp(self):
        if xprofile is None:
            raise SkipTest

        self.dir1 = tempfile.mkdtemp()
        self.log_filename_prefix1 = self.dir1 + '/unittest.profile'
        self.profile_log1 = ProfileLog(self.log_filename_prefix1, False)
        self.pids1 = ['123', '456', str(os.getpid())]
        profiler1 = xprofile.get_profiler('eventlet.green.profile')
        for pid in self.pids1:
            profiler1.runctx('import os;os.getcwd();', globals(), locals())
            self.profile_log1.dump_profile(profiler1, pid)

        self.dir2 = tempfile.mkdtemp()
        self.log_filename_prefix2 = self.dir2 + '/unittest.profile'
        self.profile_log2 = ProfileLog(self.log_filename_prefix2, True)
        self.pids2 = ['321', '654', str(os.getpid())]
        profiler2 = xprofile.get_profiler('eventlet.green.profile')
        for pid in self.pids2:
            profiler2.runctx('import os;os.getcwd();', globals(), locals())
            self.profile_log2.dump_profile(profiler2, pid)

    def tearDown(self):
        self.profile_log1.clear('all')
        self.profile_log2.clear('all')
        shutil.rmtree(self.dir1, ignore_errors=True)
        shutil.rmtree(self.dir2, ignore_errors=True)

    def test_get_all_pids(self):
        self.assertEquals(self.profile_log1.get_all_pids(),
                          sorted(self.pids1, reverse=True))
        for pid in self.profile_log2.get_all_pids():
            self.assertTrue(pid.split('-')[0] in self.pids2)

    def test_clear(self):
        self.profile_log1.clear('123')
        self.assertFalse(os.path.exists(self.log_filename_prefix1 + '123'))
        self.profile_log1.clear('current')
        self.assertFalse(os.path.exists(self.log_filename_prefix1 +
                                        str(os.getpid())))
        self.profile_log1.clear('all')
        for pid in self.pids1:
            self.assertFalse(os.path.exists(self.log_filename_prefix1 + pid))

        self.profile_log2.clear('321')
        self.assertFalse(os.path.exists(self.log_filename_prefix2 + '321'))
        self.profile_log2.clear('current')
        self.assertFalse(os.path.exists(self.log_filename_prefix2 +
                                        str(os.getpid())))
        self.profile_log2.clear('all')
        for pid in self.pids2:
            self.assertFalse(os.path.exists(self.log_filename_prefix2 + pid))

    def test_get_logfiles(self):
        log_files = self.profile_log1.get_logfiles('all')
        self.assertEqual(len(log_files), 3)
        self.assertEquals(len(log_files), len(self.pids1))
        log_files = self.profile_log1.get_logfiles('current')
        self.assertEqual(len(log_files), 1)
        self.assertEquals(log_files, [self.log_filename_prefix1
                          + str(os.getpid())])
        log_files = self.profile_log1.get_logfiles(self.pids1[0])
        self.assertEqual(len(log_files), 1)
        self.assertEquals(log_files, [self.log_filename_prefix1
                          + self.pids1[0]])
        log_files = self.profile_log2.get_logfiles('all')
        self.assertEqual(len(log_files), 3)
        self.assertEquals(len(log_files), len(self.pids2))
        log_files = self.profile_log2.get_logfiles('current')
        self.assertEqual(len(log_files), 1)
        self.assertTrue(log_files[0].find(self.log_filename_prefix2 +
                                          str(os.getpid())) > -1)
        log_files = self.profile_log2.get_logfiles(self.pids2[0])
        self.assertEqual(len(log_files), 1)
        self.assertTrue(log_files[0].find(self.log_filename_prefix2 +
                                          self.pids2[0]) > -1)

    def test_dump_profile(self):
        prof = xprofile.get_profiler('eventlet.green.profile')
        prof.runctx('import os;os.getcwd();', globals(), locals())
        prof.create_stats()
        pfn = self.profile_log1.dump_profile(prof, os.getpid())
        self.assertTrue(os.path.exists(pfn))
        os.remove(pfn)
        pfn = self.profile_log2.dump_profile(prof, os.getpid())
        self.assertTrue(os.path.exists(pfn))
        os.remove(pfn)
Exemple #2
0
class ProfileMiddleware(object):

    def __init__(self, app, conf):
        self.app = app
        self.logger = get_logger(conf, log_route='profile')
        self.log_filename_prefix = conf.get('log_filename_prefix',
                                            DEFAULT_PROFILE_PREFIX)
        dirname = os.path.dirname(self.log_filename_prefix)
        # Notes: this effort may fail due to permission denied.
        # it is better to be created and authorized to current
        # user in advance.
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        self.dump_interval = float(conf.get('dump_interval', 5.0))
        self.dump_timestamp = config_true_value(conf.get(
            'dump_timestamp', 'no'))
        self.flush_at_shutdown = config_true_value(conf.get(
            'flush_at_shutdown', 'no'))
        self.path = conf.get('path', '__profile__').replace('/', '')
        self.unwind = config_true_value(conf.get('unwind', 'no'))
        self.profile_module = conf.get('profile_module',
                                       'eventlet.green.profile')
        self.profiler = get_profiler(self.profile_module)
        self.profile_log = ProfileLog(self.log_filename_prefix,
                                      self.dump_timestamp)
        self.viewer = HTMLViewer(self.path, self.profile_module,
                                 self.profile_log)
        self.dump_pool = GreenPool(1000)
        self.last_dump_at = None

    def __del__(self):
        if self.flush_at_shutdown:
            self.profile_log.clear(str(os.getpid()))

    def _combine_body_qs(self, request):
        wsgi_input = request.environ['wsgi.input']
        query_dict = request.params
        qs_in_body = wsgi_input.read().decode('utf-8')
        query_dict.update(urllib.parse.parse_qs(qs_in_body,
                                                keep_blank_values=True,
                                                strict_parsing=False))
        return query_dict

    def dump_checkpoint(self):
        current_time = time.time()
        if self.last_dump_at is None or self.last_dump_at +\
                self.dump_interval < current_time:
            self.dump_pool.spawn_n(self.profile_log.dump_profile,
                                   self.profiler, os.getpid())
            self.last_dump_at = current_time

    def __call__(self, environ, start_response):
        request = Request(environ)
        path_entry = request.path_info.split('/')
        # hijack favicon request sent by browser so that it doesn't
        # invoke profiling hook and contaminate the data.
        if path_entry[1] == 'favicon.ico':
            start_response('200 OK', [])
            return ''
        elif path_entry[1] == self.path:
            try:
                self.dump_checkpoint()
                query_dict = self._combine_body_qs(request)
                content, headers = self.viewer.render(request.url,
                                                      request.method,
                                                      path_entry,
                                                      query_dict,
                                                      self.renew_profile)
                start_response('200 OK', headers)
                if isinstance(content, six.text_type):
                    content = content.encode('utf-8')
                return [content]
            except MethodNotAllowed as mx:
                start_response('405 Method Not Allowed', [])
                return '%s' % mx
            except NotFoundException as nx:
                start_response('404 Not Found', [])
                return '%s' % nx
            except ProfileException as pf:
                start_response('500 Internal Server Error', [])
                return '%s' % pf
            except Exception as ex:
                start_response('500 Internal Server Error', [])
                return _('Error on render profiling results: %s') % ex
        else:
            _locals = locals()
            code = self.unwind and PROFILE_EXEC_EAGER or\
                PROFILE_EXEC_LAZY
            self.profiler.runctx(code, globals(), _locals)
            app_iter = _locals['app_iter_']
            self.dump_checkpoint()
            return app_iter

    def renew_profile(self):
        self.profiler = get_profiler(self.profile_module)
Exemple #3
0
class Test_profile_log(unittest.TestCase):

    def setUp(self):
        if xprofile is None:
            raise SkipTest

        self.dir1 = tempfile.mkdtemp()
        self.log_filename_prefix1 = self.dir1 + '/unittest.profile'
        self.profile_log1 = ProfileLog(self.log_filename_prefix1, False)
        self.pids1 = ['123', '456', str(os.getpid())]
        profiler1 = xprofile.get_profiler('eventlet.green.profile')
        for pid in self.pids1:
            profiler1.runctx('import os;os.getcwd();', globals(), locals())
            self.profile_log1.dump_profile(profiler1, pid)

        self.dir2 = tempfile.mkdtemp()
        self.log_filename_prefix2 = self.dir2 + '/unittest.profile'
        self.profile_log2 = ProfileLog(self.log_filename_prefix2, True)
        self.pids2 = ['321', '654', str(os.getpid())]
        profiler2 = xprofile.get_profiler('eventlet.green.profile')
        for pid in self.pids2:
            profiler2.runctx('import os;os.getcwd();', globals(), locals())
            self.profile_log2.dump_profile(profiler2, pid)

    def tearDown(self):
        self.profile_log1.clear('all')
        self.profile_log2.clear('all')
        shutil.rmtree(self.dir1, ignore_errors=True)
        shutil.rmtree(self.dir2, ignore_errors=True)

    def test_get_all_pids(self):
        self.assertEqual(self.profile_log1.get_all_pids(),
                         sorted(self.pids1, reverse=True))
        for pid in self.profile_log2.get_all_pids():
            self.assertTrue(pid.split('-')[0] in self.pids2)

    def test_clear(self):
        self.profile_log1.clear('123')
        self.assertFalse(os.path.exists(self.log_filename_prefix1 + '123'))
        self.profile_log1.clear('current')
        self.assertFalse(os.path.exists(self.log_filename_prefix1 +
                                        str(os.getpid())))
        self.profile_log1.clear('all')
        for pid in self.pids1:
            self.assertFalse(os.path.exists(self.log_filename_prefix1 + pid))

        self.profile_log2.clear('321')
        self.assertFalse(os.path.exists(self.log_filename_prefix2 + '321'))
        self.profile_log2.clear('current')
        self.assertFalse(os.path.exists(self.log_filename_prefix2 +
                                        str(os.getpid())))
        self.profile_log2.clear('all')
        for pid in self.pids2:
            self.assertFalse(os.path.exists(self.log_filename_prefix2 + pid))

    def test_get_logfiles(self):
        log_files = self.profile_log1.get_logfiles('all')
        self.assertEqual(len(log_files), 3)
        self.assertEqual(len(log_files), len(self.pids1))
        log_files = self.profile_log1.get_logfiles('current')
        self.assertEqual(len(log_files), 1)
        self.assertEqual(log_files, [self.log_filename_prefix1
                         + str(os.getpid())])
        log_files = self.profile_log1.get_logfiles(self.pids1[0])
        self.assertEqual(len(log_files), 1)
        self.assertEqual(log_files, [self.log_filename_prefix1
                         + self.pids1[0]])
        log_files = self.profile_log2.get_logfiles('all')
        self.assertEqual(len(log_files), 3)
        self.assertEqual(len(log_files), len(self.pids2))
        log_files = self.profile_log2.get_logfiles('current')
        self.assertEqual(len(log_files), 1)
        self.assertTrue(log_files[0].find(self.log_filename_prefix2 +
                                          str(os.getpid())) > -1)
        log_files = self.profile_log2.get_logfiles(self.pids2[0])
        self.assertEqual(len(log_files), 1)
        self.assertTrue(log_files[0].find(self.log_filename_prefix2 +
                                          self.pids2[0]) > -1)

    def test_dump_profile(self):
        prof = xprofile.get_profiler('eventlet.green.profile')
        prof.runctx('import os;os.getcwd();', globals(), locals())
        prof.create_stats()
        pfn = self.profile_log1.dump_profile(prof, os.getpid())
        self.assertTrue(os.path.exists(pfn))
        os.remove(pfn)
        pfn = self.profile_log2.dump_profile(prof, os.getpid())
        self.assertTrue(os.path.exists(pfn))
        os.remove(pfn)
Exemple #4
0
class ProfileMiddleware(object):
    def __init__(self, app, conf):
        self.app = app
        self.logger = get_logger(conf, log_route='profile')
        self.log_filename_prefix = conf.get('log_filename_prefix',
                                            DEFAULT_PROFILE_PREFIX)
        dirname = os.path.dirname(self.log_filename_prefix)
        # Notes: this effort may fail due to permission denied.
        # it is better to be created and authorized to current
        # user in advance.
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        self.dump_interval = float(conf.get('dump_interval', 5.0))
        self.dump_timestamp = config_true_value(
            conf.get('dump_timestamp', 'no'))
        self.flush_at_shutdown = config_true_value(
            conf.get('flush_at_shutdown', 'no'))
        self.path = conf.get('path', '__profile__').replace('/', '')
        self.unwind = config_true_value(conf.get('unwind', 'no'))
        self.profile_module = conf.get('profile_module',
                                       'eventlet.green.profile')
        self.profiler = get_profiler(self.profile_module)
        self.profile_log = ProfileLog(self.log_filename_prefix,
                                      self.dump_timestamp)
        self.viewer = HTMLViewer(self.path, self.profile_module,
                                 self.profile_log)
        self.dump_pool = GreenPool(1000)
        self.last_dump_at = None

    def __del__(self):
        if self.flush_at_shutdown:
            self.profile_log.clear(str(os.getpid()))

    def _combine_body_qs(self, request):
        wsgi_input = request.environ['wsgi.input']
        query_dict = request.params
        qs_in_body = wsgi_input.read().decode('utf-8')
        query_dict.update(
            urllib.parse.parse_qs(qs_in_body,
                                  keep_blank_values=True,
                                  strict_parsing=False))
        return query_dict

    def dump_checkpoint(self):
        current_time = time.time()
        if self.last_dump_at is None or self.last_dump_at +\
                self.dump_interval < current_time:
            self.dump_pool.spawn_n(self.profile_log.dump_profile,
                                   self.profiler, os.getpid())
            self.last_dump_at = current_time

    def __call__(self, environ, start_response):
        request = Request(environ)
        path_entry = request.path_info.split('/')
        # hijack favicon request sent by browser so that it doesn't
        # invoke profiling hook and contaminate the data.
        if path_entry[1] == 'favicon.ico':
            start_response('200 OK', [])
            return ''
        elif path_entry[1] == self.path:
            try:
                self.dump_checkpoint()
                query_dict = self._combine_body_qs(request)
                content, headers = self.viewer.render(request.url,
                                                      request.method,
                                                      path_entry, query_dict,
                                                      self.renew_profile)
                start_response('200 OK', headers)
                if isinstance(content, six.text_type):
                    content = content.encode('utf-8')
                return [content]
            except MethodNotAllowed as mx:
                start_response('405 Method Not Allowed', [])
                return '%s' % mx
            except NotFoundException as nx:
                start_response('404 Not Found', [])
                return '%s' % nx
            except ProfileException as pf:
                start_response('500 Internal Server Error', [])
                return '%s' % pf
            except Exception as ex:
                start_response('500 Internal Server Error', [])
                return _('Error on render profiling results: %s') % ex
        else:
            _locals = locals()
            code = self.unwind and PROFILE_EXEC_EAGER or\
                PROFILE_EXEC_LAZY
            self.profiler.runctx(code, globals(), _locals)
            app_iter = _locals['app_iter_']
            self.dump_checkpoint()
            return app_iter

    def renew_profile(self):
        self.profiler = get_profiler(self.profile_module)