diff --git a/instana/meter.py b/instana/meter.py index 570b557a..0aea2bdc 100644 --- a/instana/meter.py +++ b/instana/meter.py @@ -153,6 +153,7 @@ def reset(self): self.last_collect = None self.last_metrics = None self.snapshot_countdown = 0 + self.cached_snapshot = None self.thread = None self.thread = threading.Thread(target=self.collect_and_report) @@ -240,25 +241,77 @@ def handle_agent_tasks(self, task): self.agent.task_response(task["messageId"], payload) + def get_proc_cmdline(self): + name = None + if os.path.isfile("/proc/self/cmdline"): + with open("/proc/self/cmdline") as cmd: + name = cmd.read() + return name + + def get_application_name(self): + # One environment variable to rule them all + if "INSTANA_SERVICE_NAME" in os.environ: + return os.environ["INSTANA_SERVICE_NAME"] + + # Now best effort in naming this process. No nice package.json like in Node.js + # so we do best effort detection here. + + basename = os.path.basename(sys.argv[0]) + if basename == "gunicorn": + # gunicorn renames their processes to pretty things - we use those by default + # gunicorn: master [djface.wsgi] + # gunicorn: worker [djface.wsgi] + app_name = self.get_proc_cmdline() + + if app_name is None: + app_name = basename + elif "FLASK_APP" in os.environ: + app_name = os.environ["FLASK_APP"] + elif "DJANGO_SETTINGS_MODULE" in os.environ: + app_name = os.environ["DJANGO_SETTINGS_MODULE"].split('.')[0] + elif basename == '': + if sys.stdout.isatty(): + app_name = "Interactive Console" + else: + # No arguments. Take executable as app_name + app_name = os.path.basename(sys.executable) + else: + # Last chance. app_name for "python main.py" would be "main.py" here. + app_name = basename + + # We should have a good app_name by this point. + # Last conditional, if uwsgi, then wrap the name + # with the uwsgi process type + if basename == "uwsgi": + # We have an app name by this point. Now if running under + # uwsgi, augment the appname + try: + import uwsgi + + if app_name == "uwsgi": + app_name = "" + else: + app_name = " [%s]" % app_name + + if os.getpid() == uwsgi.masterpid(): + uwsgi_type = "uWSGI master%s" + else: + uwsgi_type = "uWSGI worker%s" + + app_name = uwsgi_type % app_name + except ImportError: + pass + + logger.warn("App name is: %s", app_name) + return app_name + def collect_snapshot(self): """ Collects snapshot related information to this process and environment """ try: if self.cached_snapshot is not None: return self.cached_snapshot - if "INSTANA_SERVICE_NAME" in os.environ: - appname = os.environ["INSTANA_SERVICE_NAME"] - elif "FLASK_APP" in os.environ: - appname = os.environ["FLASK_APP"] - elif "DJANGO_SETTINGS_MODULE" in os.environ: - appname = os.environ["DJANGO_SETTINGS_MODULE"].split('.')[0] - elif os.path.basename(sys.argv[0]) == '' and sys.stdout.isatty(): - appname = "Interactive Console" - else: - if os.path.basename(sys.argv[0]) == '': - appname = os.path.basename(sys.executable) - else: - appname = os.path.basename(sys.argv[0]) + appname = self.get_application_name() s = Snapshot(name=appname, version=platform.version(), f=platform.python_implementation(),