ATLAS Offline Software
PyMonUtils.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 # @file: PyMonUtils.py
4 # @author: Sebastien Binet <binet@cern.ch>
5 
6 __author__ = "Sebastien Binet <binet@cern.ch>"
7 __version__ = "$Revision: 1.3 $"
8 __doc__ = """python module holding some general and/or miscellaneous tools, functions and classes to ease gathering monitoring data
9 """
10 
11 class Units:
12  kB = 1024.
13  MB = 1024. * 1024.
14  pass
15 
16 def mon_push_back (sgname='StoreGateSvc'):
17  """
18  Helper method to crawl through collections in a StoreGateSvc instance and
19  assess how much memory they are wasting b/c they 'forgot' to reserve
20  enough space before doing 'push_back'.
21 
22  This task is performed by just comparing what Klass::size() and
23  Klass::capacity() are returning as a value.
24 
25  @param `sgname` the fully qualified Gaudi name of the StoreGateSvc instance
26  @return a dictionary of { <sgkey> : (size, capacity, clid) }
27  """
28  wasted = {}
29  try:
30  from AthenaPython import PyAthena
31  except ImportError:
32  # arf... release 13...
33  return wasted
34 
35  sg = PyAthena.py_svc (sgname)
36  cl = PyAthena.py_svc ('ClassIDSvc')
37 
38  # retrieve all containers from StoreGate
39  proxies = sg.proxies()
40 
41  for dp in proxies:
42  k = dp.name()
43  # no double counting from symlinks
44  # FIXME: it is actually valid to have 2 different collections
45  # (=/= CLIDs) with the same key...
46  if k in wasted:
47  continue
48  clid = dp.clID()
49  klass = "%s" % cl.typename(clid)
50  # 'handle' classes for which we were not able to fetch
51  # a C++ typename from the SG::DataProxy classID (e.g. HistoryObjects)
52  if klass == "None":
53  continue
54 
55  try:
56  data = sg.retrieve(klass, k)
57  except Exception:
58  # don't bother user: probably no Reflex dictionary...
59  continue
60 
61  if not data:
62  continue
63 
64  # reject objects we can't inspect or not interested in
65  if not hasattr(data, 'size') or \
66  not hasattr(data, 'capacity'):
67  continue
68 
69  sz = data.size()
70  cp = data.capacity()
71  rt = 0.
72  if cp != 0.:
73  rt = sz/float(cp)*100.
74  # simple minded filter
75  if rt==0. or rt>=90.:
76  continue
77  wasted[k] = (sz, cp, clid)
78  pass
79  return wasted
80 
81 def dump_smaps (fname=None):
82  import os,sys
83  if not (fname is None):
84  o = open (fname, 'w')
85  else:
86  o = sys.stdout
87  for z in open('/proc/%d/smaps'%os.getpid()):
88  print(z, file=o)
89  if not (fname is None):
90  o.close()
91  return
92 
93 def loaded_libs (fname=None, pid=None, show=False):
94  import os,sys,re
95  if not (fname is None):
96  o = open (fname, 'w')
97  else:
98  o = sys.stdout
99  pat = re.compile(r'(?P<addr_beg>\w*?)\-(?P<addr_end>\w*?)\s'\
100  r'(?P<perm>.{4})\s(?P<offset>\w*?)\s'\
101  r'(?P<devmajor>\d{2}):(?P<devminor>\d{2})\s'\
102  r'(?P<inode>\d*?)\s(?P<libname>.*)')
103  libs = set()
104  _realpath = os.path.realpath
105  if pid is None:
106  pid = os.getpid()
107  for line in open('/proc/%s/smaps'%pid):
108  z = line.strip()
109  res = re.match(pat,z)
110  if res:
111  g = res.group
112  libname = g('libname').strip()
113  libs.add(_realpath(libname))
114  libs = sorted([z for z in libs], reverse=True)
115  if show:
116  for libname in libs:
117  print(libname, file=o)
118  return libs
119 
120 import sys
121 if sys.platform == 'darwin':
122  def pymon():
123  from resource import getrusage, RUSAGE_SELF
124  cpu = getrusage(RUSAGE_SELF)
125  cpu = (cpu.ru_utime+cpu.ru_stime) * 1e3 # in milliseconds
126  # The following is placeholder code for the Mac to get vmem and rss in bytes. This is available
127  # via the C task_info() function, for which there isn't a Python wrapper yet. The following is
128  # a hack using the 'ps' command which is certainly not optimal! The vsz and rss are claimed to
129  # be returned from the 'ps' command in units of Kb, but it looks like vsz is in pages rather than
130  # Kb, so I'll scale it by that, whereas rsz does appear to be in units of Kb.
131  from resource import getpagesize
132  from os import popen, getpid
133  pageSize = getpagesize()
134  vsz = int(popen('ps -p %d -o %s | tail -1' % (getpid(), "vsz")).read())
135  rss = int(popen('ps -p %d -o %s | tail -1' % (getpid(), "rss")).read())
136  vmem = vsz*pageSize / 1024.0 / 1024.0
137  rss = rss / 1024
138  return cpu,vmem,rss
139 else:
140  def pymon():
141  from os import getpid,sysconf
142  from resource import getrusage, RUSAGE_SELF
143  cpu = getrusage(RUSAGE_SELF)
144  cpu = (cpu.ru_utime+cpu.ru_stime) * 1e3 # in milliseconds
145  pageSize = sysconf('SC_PAGE_SIZE')/Units.MB
146  mem = open('/proc/%d/statm'%getpid(),'r')
147  mem = mem.readlines()[0].split()
148  vmem = int(mem[0])*pageSize
149  rss = int(mem[1])*pageSize
150  return cpu,vmem,rss
151 
153  import socket,commands
154  hostname = '<unknown>'
155  try:
156  hostname = socket.gethostname()
157  except Exception:
158  pass
159  sc,out = commands.getstatusoutput('which lshosts')
160  if sc != 0:
161  return ('no lshosts command',0.) # no lshosts could be found
162  cmd = out
163  sc,out = commands.getstatusoutput("%s %s"%(cmd,hostname))
164  if sc != 0:
165  return ('host not in db', 0.)
166  cpu_infos = {}
167  try:
168  title,data = out.splitlines()
169  title = title.split()
170  # title is of the form:
171  # HOST_NAME type model cpuf ncpus maxmem maxswp server RESOURCES
172  data = data.split()
173  for i,k in enumerate(title[:-1]): # dropping the 'RESOURCES' field
174  cpu_infos[k] = data[i]
175  except Exception as err:
176  return ('err', err)
177  return ('ok', cpu_infos)
178 
179 
read
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)
Definition: openCoraCool.cxx:569
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.PyMonUtils.Units
Definition: PyMonUtils.py:11
python.PyMonUtils.dump_smaps
def dump_smaps(fname=None)
Definition: PyMonUtils.py:81
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
python.PyMonUtils.pymon
def pymon()
Definition: PyMonUtils.py:122
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
python.PyMonUtils.mon_push_back
def mon_push_back(sgname='StoreGateSvc')
Definition: PyMonUtils.py:16
Trk::open
@ open
Definition: BinningType.h:40
python.PyMonUtils.lshosts_infos
def lshosts_infos()
Definition: PyMonUtils.py:152
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
python.PyMonUtils.loaded_libs
def loaded_libs(fname=None, pid=None, show=False)
Definition: PyMonUtils.py:93
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38