Skip to content

Commit 2cb7a11

Browse files
authored
Improved uWSGI & GUnicorn App Names (#171)
* Check if uwsgi API available and use to detect environment * Better names for gunicorn too
1 parent 7fbc4dd commit 2cb7a11

File tree

1 file changed

+66
-13
lines changed

1 file changed

+66
-13
lines changed

instana/meter.py

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ def reset(self):
153153
self.last_collect = None
154154
self.last_metrics = None
155155
self.snapshot_countdown = 0
156+
self.cached_snapshot = None
156157
self.thread = None
157158

158159
self.thread = threading.Thread(target=self.collect_and_report)
@@ -240,25 +241,77 @@ def handle_agent_tasks(self, task):
240241

241242
self.agent.task_response(task["messageId"], payload)
242243

244+
def get_proc_cmdline(self):
245+
name = None
246+
if os.path.isfile("/proc/self/cmdline"):
247+
with open("/proc/self/cmdline") as cmd:
248+
name = cmd.read()
249+
return name
250+
251+
def get_application_name(self):
252+
# One environment variable to rule them all
253+
if "INSTANA_SERVICE_NAME" in os.environ:
254+
return os.environ["INSTANA_SERVICE_NAME"]
255+
256+
# Now best effort in naming this process. No nice package.json like in Node.js
257+
# so we do best effort detection here.
258+
259+
basename = os.path.basename(sys.argv[0])
260+
if basename == "gunicorn":
261+
# gunicorn renames their processes to pretty things - we use those by default
262+
# gunicorn: master [djface.wsgi]
263+
# gunicorn: worker [djface.wsgi]
264+
app_name = self.get_proc_cmdline()
265+
266+
if app_name is None:
267+
app_name = basename
268+
elif "FLASK_APP" in os.environ:
269+
app_name = os.environ["FLASK_APP"]
270+
elif "DJANGO_SETTINGS_MODULE" in os.environ:
271+
app_name = os.environ["DJANGO_SETTINGS_MODULE"].split('.')[0]
272+
elif basename == '':
273+
if sys.stdout.isatty():
274+
app_name = "Interactive Console"
275+
else:
276+
# No arguments. Take executable as app_name
277+
app_name = os.path.basename(sys.executable)
278+
else:
279+
# Last chance. app_name for "python main.py" would be "main.py" here.
280+
app_name = basename
281+
282+
# We should have a good app_name by this point.
283+
# Last conditional, if uwsgi, then wrap the name
284+
# with the uwsgi process type
285+
if basename == "uwsgi":
286+
# We have an app name by this point. Now if running under
287+
# uwsgi, augment the appname
288+
try:
289+
import uwsgi
290+
291+
if app_name == "uwsgi":
292+
app_name = ""
293+
else:
294+
app_name = " [%s]" % app_name
295+
296+
if os.getpid() == uwsgi.masterpid():
297+
uwsgi_type = "uWSGI master%s"
298+
else:
299+
uwsgi_type = "uWSGI worker%s"
300+
301+
app_name = uwsgi_type % app_name
302+
except ImportError:
303+
pass
304+
305+
logger.warn("App name is: %s", app_name)
306+
return app_name
307+
243308
def collect_snapshot(self):
244309
""" Collects snapshot related information to this process and environment """
245310
try:
246311
if self.cached_snapshot is not None:
247312
return self.cached_snapshot
248313

249-
if "INSTANA_SERVICE_NAME" in os.environ:
250-
appname = os.environ["INSTANA_SERVICE_NAME"]
251-
elif "FLASK_APP" in os.environ:
252-
appname = os.environ["FLASK_APP"]
253-
elif "DJANGO_SETTINGS_MODULE" in os.environ:
254-
appname = os.environ["DJANGO_SETTINGS_MODULE"].split('.')[0]
255-
elif os.path.basename(sys.argv[0]) == '' and sys.stdout.isatty():
256-
appname = "Interactive Console"
257-
else:
258-
if os.path.basename(sys.argv[0]) == '':
259-
appname = os.path.basename(sys.executable)
260-
else:
261-
appname = os.path.basename(sys.argv[0])
314+
appname = self.get_application_name()
262315

263316
s = Snapshot(name=appname, version=platform.version(),
264317
f=platform.python_implementation(),

0 commit comments

Comments
 (0)