def test_filter(self): record = mock.MagicMock() log_filter = PySOALogContextFilter() self.assertTrue(log_filter.filter(record)) self.assertEqual('--', record.correlation_id) self.assertEqual('--', record.request_id) self.assertEqual('unknown', record.service_name) PySOALogContextFilter.set_service_name('foo_qux') PySOALogContextFilter.set_logging_request_context(filter='mine', **{'logger': 'yours'}) self.assertEqual({'filter': 'mine', 'logger': 'yours'}, PySOALogContextFilter.get_logging_request_context()) record.reset_mock() self.assertTrue(log_filter.filter(record)) self.assertEqual('--', record.correlation_id) self.assertEqual('--', record.request_id) self.assertEqual('foo_qux', record.service_name) PySOALogContextFilter.set_logging_request_context(request_id=4321, **{'correlation_id': 'abc1234'}) self.assertEqual( {'request_id': 4321, 'correlation_id': 'abc1234'}, PySOALogContextFilter.get_logging_request_context() ) record.reset_mock() self.assertTrue(log_filter.filter(record)) self.assertEqual('abc1234', record.correlation_id) self.assertEqual(4321, record.request_id) self.assertEqual('foo_qux', record.service_name) PySOALogContextFilter.clear_logging_request_context() self.assertEqual({'filter': 'mine', 'logger': 'yours'}, PySOALogContextFilter.get_logging_request_context()) record.reset_mock() self.assertTrue(log_filter.filter(record)) self.assertEqual('--', record.correlation_id) self.assertEqual('--', record.request_id) self.assertEqual('foo_qux', record.service_name) PySOALogContextFilter.clear_logging_request_context() self.assertIsNone(PySOALogContextFilter.get_logging_request_context()) record.reset_mock() self.assertTrue(log_filter.filter(record)) self.assertEqual('--', record.correlation_id) self.assertEqual('--', record.request_id) self.assertEqual('foo_qux', record.service_name)
def main(cls): """ Command-line entry point for running a PySOA server. The chain of method calls is as follows:: cls.main | -> cls.initialize => new_cls -> new_cls.__init__ => self -> self.run | -> self.setup -> loop: self.handle_next_request while not self.shutting_down | -> transport.receive_request_message -> self.perform_idle_actions (if no request) -> self.perform_pre_request_actions -> self.process_job | -> middleware(self.execute_job) -> transport.send_response_message -> self.perform_post_request_actions """ parser = argparse.ArgumentParser( description='Server for the {} SOA service'.format(cls.service_name), ) parser.add_argument( '-d', '--daemon', action='store_true', help='run the server process as a daemon', ) if not cls.use_django: # If Django mode is turned on, we use the Django settings framework to get our settings, so the caller # needs to set DJANGO_SETTINGS_MODULE. Otherwise, the caller must pass in the -s/--settings argument. parser.add_argument( '-s', '--settings', help='The settings module to use', required=True, ) cmd_options, _ = parser.parse_known_args(sys.argv[1:]) # Load settings from the given file (or use Django and grab from its settings) if cls.use_django: # noinspection PyUnresolvedReferences if not django_settings: raise ImportError( 'Could not import Django. You must install Django if you enable Django support in your service.' ) try: settings = cls.settings_class(django_settings.SOA_SERVER_SETTINGS) except AttributeError: raise ValueError('Cannot find `SOA_SERVER_SETTINGS` in the Django settings.') else: try: settings_module = importlib.import_module(cmd_options.settings) except ImportError as e: raise ValueError('Cannot import settings module `%s`: %s' % (cmd_options.settings, e)) try: settings_dict = getattr(settings_module, 'SOA_SERVER_SETTINGS') except AttributeError: try: settings_dict = getattr(settings_module, 'settings') except AttributeError: raise ValueError( "Cannot find `SOA_SERVER_SETTINGS` or `settings` variable in settings module `{}`.".format( cmd_options.settings, ) ) settings = cls.settings_class(settings_dict) PySOALogContextFilter.set_service_name(cls.service_name) # Set up logging logging.config.dictConfig(settings['logging']) # Optionally daemonize if cmd_options.daemon: pid = os.fork() if pid > 0: print('PID={}'.format(pid)) sys.exit() # Set up server and signal handling server = cls.initialize(settings)(settings) # Start server event loop server.run()
def main(cls, forked_process_id=None): """ Command-line entry point for running a PySOA server. The chain of method calls is as follows:: cls.main | -> cls.initialize => new_cls -> new_cls.__init__ => self -> self.run | -> self.setup -> [async event loop started if Python 3.5+] -> [heartbeat file created if configured] -> loop: self.handle_next_request while not self.shutting_down | -> transport.receive_request_message -> self.perform_idle_actions (if no request) -> self.perform_pre_request_actions -> self.process_job | -> middleware(self.execute_job) -> transport.send_response_message -> self.perform_post_request_actions -> self.teardown -> [async event loop joined in Python 3.5+; this make take a few seconds to finish running tasks] -> [Django resources cleaned up] -> [heartbeat file deleted if configured] :param forked_process_id: If multiple processes are forked by the same parent process, this will be set to a unique, deterministic (incremental) ID which can be used in logging, the heartbeat file, etc. For example, if the `--fork` argument is used with the value 5 (creating five child processes), this argument will have the values 1, 2, 3, 4, and 5 across the five respective child processes. :type forked_process_id: int """ parser = argparse.ArgumentParser( description='Server for the {} SOA service'.format(cls.service_name), ) parser.add_argument( '-d', '--daemon', action='store_true', help='run the server process as a daemon', ) if not cls.use_django: # If Django mode is turned on, we use the Django settings framework to get our settings, so the caller # needs to set DJANGO_SETTINGS_MODULE. Otherwise, the caller must pass in the -s/--settings argument. parser.add_argument( '-s', '--settings', help='The settings module to use', required=True, ) cmd_options, _ = parser.parse_known_args(sys.argv[1:]) # Load settings from the given file (or use Django and grab from its settings) if cls.use_django: # noinspection PyUnresolvedReferences if not django_settings: raise ImportError( 'Could not import Django. You must install Django if you enable Django support in your service.' ) try: settings = cls.settings_class(django_settings.SOA_SERVER_SETTINGS) except AttributeError: raise ValueError('Cannot find `SOA_SERVER_SETTINGS` in the Django settings.') else: try: settings_module = importlib.import_module(cmd_options.settings) except ImportError as e: raise ValueError('Cannot import settings module `%s`: %s' % (cmd_options.settings, e)) try: settings_dict = getattr(settings_module, 'SOA_SERVER_SETTINGS') except AttributeError: try: settings_dict = getattr(settings_module, 'settings') except AttributeError: raise ValueError( "Cannot find `SOA_SERVER_SETTINGS` or `settings` variable in settings module `{}`.".format( cmd_options.settings, ) ) settings = cls.settings_class(settings_dict) PySOALogContextFilter.set_service_name(cls.service_name) # Set up logging logging.config.dictConfig(settings['logging']) # Optionally daemonize if cmd_options.daemon: pid = os.fork() if pid > 0: print('PID={}'.format(pid)) sys.exit() # Set up server and signal handling server = cls.initialize(settings)(settings, forked_process_id) # Start server event loop server.run()