@@ -241,78 +241,108 @@ def handle_agent_tasks(self, task):
241241
242242 self .agent .task_response (task ["messageId" ], payload )
243243
244- def get_proc_cmdline (self ):
245- name = None
244+ def get_proc_cmdline (self , as_string = False ):
245+ """
246+ Parse the proc file system for the command line of this process. If not available, then return a default.
247+ Return is dependent on the value of `as_string`. If True, return the full command line as a string,
248+ otherwise a list.
249+ """
250+ name = "python"
246251 if os .path .isfile ("/proc/self/cmdline" ):
247252 with open ("/proc/self/cmdline" ) as cmd :
248253 name = cmd .read ()
249- return name
254+ else :
255+ # Most likely not on a *nix based OS. Return a default
256+ if as_string is True :
257+ return name
258+ else :
259+ return [name ]
260+
261+ # /proc/self/command line will have strings with null bytes such as "/usr/bin/python\0-s\0-d\0". This
262+ # bit will prep the return value and drop the trailing null byte
263+ parts = name .split ('\0 ' )
264+ parts .pop ()
265+
266+ if as_string is True :
267+ parts = " " .join (parts )
268+
269+ return parts
250270
251271 def get_application_name (self ):
272+ """ This function makes a best effort to name this application process. """
273+
252274 # One environment variable to rule them all
253275 if "INSTANA_SERVICE_NAME" in os .environ :
254276 return os .environ ["INSTANA_SERVICE_NAME" ]
255277
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"
278+ try :
279+ # Now best effort in naming this process. No nice package.json like in Node.js
280+ # so we do best effort detection here.
281+ app_name = "python" # the default name
282+
283+ if not hasattr (sys , 'argv' ):
284+ proc_cmdline = self .get_proc_cmdline (as_string = False )
285+ return os .path .basename (proc_cmdline [0 ])
286+
287+ basename = os .path .basename (sys .argv [0 ])
288+ if basename == "gunicorn" :
289+ # gunicorn renames their processes to pretty things - we use those by default
290+ # gunicorn: master [djface.wsgi]
291+ # gunicorn: worker [djface.wsgi]
292+ app_name = self .get_proc_cmdline (as_string = True )
293+
294+ if app_name is None :
295+ app_name = basename
296+ elif "FLASK_APP" in os .environ :
297+ app_name = os .environ ["FLASK_APP" ]
298+ elif "DJANGO_SETTINGS_MODULE" in os .environ :
299+ app_name = os .environ ["DJANGO_SETTINGS_MODULE" ].split ('.' )[0 ]
300+ elif basename == '' :
301+ if sys .stdout .isatty ():
302+ app_name = "Interactive Console"
298303 else :
299- uwsgi_type = "uWSGI worker%s"
300-
301- app_name = uwsgi_type % app_name
302- except ImportError :
303- pass
304+ # No arguments. Take executable as app_name
305+ app_name = os . path . basename ( sys . executable )
306+ else :
307+ # Last chance. app_name for "python main.py" would be "main.py" here.
308+ app_name = basename
304309
305- return app_name
310+ # We should have a good app_name by this point.
311+ # Last conditional, if uwsgi, then wrap the name
312+ # with the uwsgi process type
313+ if basename == "uwsgi" :
314+ # We have an app name by this point. Now if running under
315+ # uwsgi, augment the app name
316+ try :
317+ import uwsgi
318+
319+ if app_name == "uwsgi" :
320+ app_name = ""
321+ else :
322+ app_name = " [%s]" % app_name
323+
324+ if os .getpid () == uwsgi .masterpid ():
325+ uwsgi_type = "uWSGI master%s"
326+ else :
327+ uwsgi_type = "uWSGI worker%s"
328+
329+ app_name = uwsgi_type % app_name
330+ except ImportError :
331+ pass
332+ return app_name
333+ except Exception as e :
334+ logger .debug ("get_application_name: " , exc_info = True )
335+ return app_name
306336
307337 def collect_snapshot (self ):
308338 """ Collects snapshot related information to this process and environment """
309339 try :
310340 if self .cached_snapshot is not None :
311341 return self .cached_snapshot
312342
313- appname = self .get_application_name ()
343+ app_name = self .get_application_name ()
314344
315- s = Snapshot (name = appname , version = platform .version (),
345+ s = Snapshot (name = app_name , version = platform .version (),
316346 f = platform .python_implementation (),
317347 a = platform .architecture ()[0 ],
318348 djmw = self .djmw )
0 commit comments