diff --git a/instana/__init__.py b/instana/__init__.py index 476e0df0..03a26c19 100644 --- a/instana/__init__.py +++ b/instana/__init__.py @@ -53,6 +53,7 @@ def boot_agent(): import instana.singletons + # Instrumentation if "INSTANA_DISABLE_AUTO_INSTR" not in os.environ: # Import & initialize instrumentation if sys.version_info >= (3, 5, 3): @@ -81,6 +82,8 @@ def boot_agent(): from .instrumentation import urllib3 from .instrumentation.django import middleware + # Hooks + from .hooks import hook_uwsgi if "INSTANA_MAGIC" in os.environ: pkg_resources.working_set.add_entry("/tmp/instana/python") diff --git a/instana/agent.py b/instana/agent.py index dca1da33..9db01f38 100644 --- a/instana/agent.py +++ b/instana/agent.py @@ -154,7 +154,7 @@ def announce(self, discovery): """ try: url = self.__discovery_url() - logger.debug("making announce request to %s", url) + # logger.debug("making announce request to %s", url) response = None response = self.client.put(url, data=to_json(discovery), diff --git a/instana/fsm.py b/instana/fsm.py index 62149887..e1b7c80f 100644 --- a/instana/fsm.py +++ b/instana/fsm.py @@ -90,12 +90,8 @@ def reset(self): :return: void """ - logger.debug("State machine being reset. Will schedule new announce cycle 6 seconds from now.") - - self.timer = t.Timer(6, self.fsm.lookup) - self.timer.daemon = True - self.timer.name = self.THREAD_NAME - self.timer.start() + logger.debug("State machine being reset. Will start a new announce cycle.") + self.fsm.lookup() def lookup_agent_host(self, e): self.agent.should_threads_shutdown.clear() diff --git a/instana/hooks/__init__.py b/instana/hooks/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/instana/hooks/hook_uwsgi.py b/instana/hooks/hook_uwsgi.py new file mode 100644 index 00000000..5af1a27a --- /dev/null +++ b/instana/hooks/hook_uwsgi.py @@ -0,0 +1,38 @@ +""" +The uwsgi and uwsgidecorators packages are added automatically to the Python environment +when running under uWSGI. Here we attempt to detect the presence of these packages and +then use the appropriate hooks. +""" +from __future__ import absolute_import + +from ..log import logger +from ..singletons import agent + +try: + import uwsgi + logger.debug("uWSGI options: %s", uwsgi.opt) + + opt_master = uwsgi.opt.get('master', False) + opt_lazy_apps = uwsgi.opt.get('lazy-apps', False) + + if uwsgi.opt.get('enable-threads', False) is False: + logger.warn("Required: uWSGI threads are not enabled. " + + "Please enable by using the uWSGI --enable-threads option.") + + if opt_master and opt_lazy_apps is False: + # --master is supplied in uWSGI options (otherwise uwsgidecorators package won't be available) + # When --lazy-apps is True, this postfork hook isn't needed + import uwsgidecorators + + @uwsgidecorators.postfork + def uwsgi_handle_fork(): + """ This is our uWSGI hook to detect and act when worker processes are forked off. """ + logger.debug("Handling uWSGI fork...") + agent.handle_fork() + + logger.debug("Applied uWSGI hooks") + else: + logger.debug("uWSGI --master=%s --lazy-apps=%s: postfork hooks not applied", opt_master, opt_lazy_apps) +except ImportError as e: + logger.debug('uwsgi hooks: decorators not available: %s', e) + pass