node_info.py
Go to the documentation of this file.
00001 # Copyright (c) 2013, Oregon State University
00002 # All rights reserved.
00003 
00004 # Redistribution and use in source and binary forms, with or without
00005 # modification, are permitted provided that the following conditions are met:
00006 #     * Redistributions of source code must retain the above copyright
00007 #       notice, this list of conditions and the following disclaimer.
00008 #     * Redistributions in binary form must reproduce the above copyright
00009 #       notice, this list of conditions and the following disclaimer in the
00010 #       documentation and/or other materials provided with the distribution.
00011 #     * Neither the name of the Oregon State University nor the
00012 #       names of its contributors may be used to endorse or promote products
00013 #       derived from this software without specific prior written permission.
00014 
00015 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00016 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00018 # DISCLAIMED. IN NO EVENT SHALL OREGON STATE UNIVERSITY BE LIABLE FOR ANY
00019 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00020 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00021 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00022 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026 # Author Dan Lazewatsky/lazewatd@engr.orst.edu
00027 
00028 import rosnode
00029 import rospy
00030 try:
00031     from xmlrpc.client import ServerProxy
00032 except ImportError:
00033     from xmlrpclib import ServerProxy
00034 from socket import error as SocketError
00035 import psutil
00036 
00037 ID = '/NODEINFO'
00038 
00039 
00040 class NodeInfo(object):
00041     nodes = dict()
00042 
00043     def get_node_info(self, node_name, skip_cache=False):
00044         node_api = rosnode.get_api_uri(rospy.get_master(), node_name, skip_cache=skip_cache)
00045         try:
00046             code, msg, pid = ServerProxy(node_api[2]).getPid(ID)
00047             if node_name in self.nodes:
00048                 return self.nodes[node_name]
00049             else:
00050                 try:
00051                     p = psutil.Process(pid)
00052                     self.nodes[node_name] = p
00053                     return p
00054                 except:
00055                     return False
00056         except SocketError:
00057             if not skip_cache:
00058                 return self.get_node_info(node_name, skip_cache=True)
00059             else:
00060                 return False
00061 
00062     def get_all_node_info(self):
00063         infos = []
00064         self.remove_dead_nodes()
00065         for node_name in rosnode.get_node_names():
00066             info = self.get_node_info(node_name)
00067             if info is not False:
00068                 infos.append((node_name, info))
00069         return infos
00070 
00071     def get_all_node_fields(self, fields):
00072         processes = self.get_all_node_info()
00073         infos = []
00074         psutil_v2_api = int(psutil.__version__.split('.')[0]) >= 2
00075         for name, p in processes:
00076             all_fields = fields + ['cmdline', 'get_memory_info']
00077             if psutil_v2_api:
00078                 all_fields = [
00079                     f[4:] if f.startswith('get_') else f
00080                     for f in all_fields]
00081             infos.append(self.as_dict(p, all_fields))
00082             infos[-1]['node_name'] = name
00083         return infos
00084 
00085     def remove_dead_nodes(self):
00086         running_nodes = rosnode.get_node_names()
00087         dead_nodes = [node_name for node_name in self.nodes if node_name not in running_nodes]
00088         for node_name in dead_nodes:
00089             self.nodes.pop(node_name, None)
00090 
00091     def kill_node(self, node_name):
00092         success, fail = rosnode.kill_nodes([node_name])
00093         return node_name in success
00094 
00095     def as_dict(self, p, attrs=[], ad_value=None):
00096         # copied code from psutil.__init__ from a newer version
00097         excluded_names = set(['send_signal', 'suspend', 'resume', 'terminate',
00098                               'kill', 'wait', 'is_running', 'as_dict', 'parent',
00099                               'get_children', 'nice'])
00100         retdict = dict()
00101         for name in set(attrs or dir(p)):
00102             if name.startswith('_'):
00103                 continue
00104             if name.startswith('set_'):
00105                 continue
00106             if name in excluded_names:
00107                 continue
00108             try:
00109                 attr = getattr(p, name)
00110                 if callable(attr):
00111                     if name == 'get_cpu_percent':
00112                         ret = attr(interval=0)
00113                     else:
00114                         ret = attr()
00115                 else:
00116                     ret = attr
00117             except psutil.AccessDenied:
00118                 ret = ad_value
00119             except NotImplementedError:
00120                 # in case of not implemented functionality (may happen
00121                 # on old or exotic systems) we want to crash only if
00122                 # the user explicitly asked for that particular attr
00123                 if attrs:
00124                     raise
00125                 continue
00126             if name.startswith('get'):
00127                 if name[3] == '_':
00128                     name = name[4:]
00129                 elif name == 'getcwd':
00130                     name = 'cwd'
00131             retdict[name] = ret
00132         return retdict


rqt_top
Author(s): Dan Lazewatsky
autogenerated on Thu Jun 6 2019 21:58:04