CMS 3D CMS Logo

cmsswConfigtrace.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 from __future__ import print_function
3 import os
4 import re
5 import six
6 import sys
7 import inspect
8 import sqlite3
9 import tempfile
10 import traceback
11 import subprocess
12 from shutil import copy, rmtree
13 from collections import defaultdict
14 
15 
16 SERVE_PORT = 1234
17 
18 OUTFILE_TREE = "configtree.sqlite"
19 IGNORE_PACKAGES = ['FWCore/ParameterSet', 'DQMOffline/Configuration/scripts', "cmsRun"]
20 STRIPPATHS = [ # we will add the base dir from CMSSWCALLBASE env var here
21  os.environ["CMSSW_BASE"] + "/python/", os.environ["CMSSW_RELEASE_BASE"] + "/python/",
22  os.environ["CMSSW_BASE"] + "/cfipython/", os.environ["CMSSW_RELEASE_BASE"] + "/cfipython/"]
23 PREFIXINFO = [] # what we will show as "source" later
24 ARGV0 = "" # set in main
25 
26 
27 
28 # this already does a good job, but it is not enough
29 #import FWCore.GuiBrowsers.EnablePSetHistory
30 
31 # we need to patch out this to allow printing unlabled things
33 del FWCore.ParameterSet.Mixins._Labelable.__str__
34 
35 # then also trace Sequence construction so we can get a full tree
36 # (PSetHistory only tracks leaves)
38  # stolen from FWCore.GuiBrowsers.EnablePSetHistory, but needs more black-list
39  stack = inspect.stack()
40  i = 0
41  while i < len(stack) and len(stack[i])>=2 and any(map(lambda p: p in stack[i][1], IGNORE_PACKAGES)):
42  i += 1
43  res = stack[i: ]
44  j = 0
45  # for the other end we only use cmsRun (instead of IGNORE_PACKAGES) to avoid
46  # cutting traces in the middle that enter and leave IGNORE_PACKAGES
47  while j < len(res) and not 'cmsRun' in res[j][1]:
48  j += 1
49  res = res[:j]
50  if len(res)>=1 and len(res[0])>=3:
51  return res
52  else:
53  return [("unknown","unknown","unknown")]
54 
55 def trace_location(thing, name, extra = lambda thing, *args, **kwargs: thing):
56  old_method = getattr(thing, name)
57  def trace_location_hook(self, *args, **kwargs):
58  retval = old_method(self, *args, **kwargs)
59  where = auto_inspect()
60  #print("Called %s::%s at %s" % (thing.__name__, name, where[0][1:3]))
61  event = (name, tuple(w[1:3] for w in where), extra(self, *args, **kwargs))
62  if hasattr(self, "_trace_events"):
63  getattr(self, "_trace_events").append(event)
64  else:
65  # this bypasses setattr checks
66  self.__dict__["_trace_events"] = [ event ]
67 
68  return retval
69  setattr(thing, name, trace_location_hook)
70 
71 def flatten(*args):
72  # that was surprisingly hard...
73  return [x for x in args if not isinstance(x, list)] + sum(
74  [flatten(*x) for x in args if isinstance(x, list)], [])
75 
76 from FWCore.ParameterSet.SequenceTypes import _ModuleSequenceType, _SequenceCollection, Task, _UnarySequenceOperator, Schedule
77 from FWCore.ParameterSet.Modules import _Module, Source, ESSource, ESPrefer, ESProducer, Service, Looper
78 from FWCore.ParameterSet.Config import Process
79 # with this we can also track the '+' and '*' of modules, but it is slow
80 trace_location(_SequenceCollection, '__init__')
81 trace_location(_Module, '__init__')
82 trace_location(Source, '__init__')
83 trace_location(ESSource, '__init__')
84 trace_location(ESPrefer, '__init__')
85 trace_location(ESProducer, '__init__')
86 trace_location(Service, '__init__')
87 trace_location(Looper, '__init__')
88 trace_location(Process, '__init__')
89 trace_location(_UnarySequenceOperator, '__init__')
90 # lambda agrument names all match the original declarations, to make kwargs work
91 trace_location(_ModuleSequenceType, '__init__', lambda self, *arg: {'args': list(arg)})
92 trace_location(_ModuleSequenceType, 'copy')
93 trace_location(_ModuleSequenceType, 'associate', lambda self, *tasks: {'args': list(tasks)})
94 trace_location(_ModuleSequenceType, '__imul__', lambda self, rhs: {'rhs': rhs})
95 trace_location(_ModuleSequenceType, '__iadd__', lambda self, rhs: {'rhs': rhs})
96 trace_location(_ModuleSequenceType, 'copyAndExclude', lambda self, listOfModulesToExclude: {'olds': list(listOfModulesToExclude)})
97 trace_location(_ModuleSequenceType, 'replace', lambda self, original, replacement: {'old': original, 'new': replacement})
98 trace_location(_ModuleSequenceType, 'insert', lambda self, index, item: {'rhs': item})
99 trace_location(_ModuleSequenceType, 'remove', lambda self, something: {'old': something})
100 trace_location(Task, '__init__')
101 trace_location(Task, 'add', lambda self, *items: {'args': list(items)})
102 trace_location(Task, 'copy')
103 trace_location(Task, 'copyAndExclude', lambda self, listOfModulesToExclude: {'olds': list(listOfModulesToExclude)})
104 trace_location(Schedule, '__init__', lambda self, *args, **kwargs: {'args': flatten(list(args), kwargs.values())})
105 trace_location(Schedule, 'associate', lambda self, *tasks: {'args': list(tasks)})
106 trace_location(Schedule, 'copy')
107 # TODO: we could go deeper into Types and PSet, but that should not be needed for now.
108 
109 # lifted from EnablePSetHistory, we don't need all of that stuff.
110 def new_items_(self):
111  items = []
112  if self.source:
113  items += [("source", self.source)]
114  if self.looper:
115  items += [("looper", self.looper)]
116  #items += self.moduleItems_()
117  items += self.outputModules.items()
118  #items += self.sequences.items() # TODO: we don't need sequences that are not paths?
119  items += six.iteritems(self.paths)
120  items += self.endpaths.items()
121  items += self.services.items()
122  items += self.es_producers.items()
123  items += self.es_sources.items()
124  items += self.es_prefers.items()
125  #items += self.psets.items()
126  #items += self.vpsets.items()
127  if self.schedule:
128  items += [("schedule", self.schedule)]
129  return tuple(items)
130 Process.items_=new_items_
131 
132 
133 
134 def collect_trace(thing, name, graph, parent):
135  # thing is what to look at, graph is the output list (of child, parent tuple pairs)
136  # thing could be pretty much anything.
137  classname = thing.__class__.__name__
138  if hasattr(thing, '_trace_events'):
139  events = list(getattr(thing, '_trace_events'))
140  getattr(thing, '_trace_events')[:] = [] # erase events so we can't end up in cycles
141  for action, loc, extra in events:
142  entry = (action, classname, loc)
143  graph.append((entry, parent, name))
144 
145  # items shall be a list of tuples (type, object) of the immediate children of the thing.
146  items = []
147  if hasattr(extra, 'items_'): # for cms.Process
148  items += extra.items_()
149  if hasattr(extra, '_seq'): # for sequences and similar
150  seq = getattr(extra, '_seq')
151  if seq:
152  items += [('seqitem', x) for x in getattr(seq, '_collection')]
153  if hasattr(extra, '_tasks'): # same
154  items += [('task', x) for x in getattr(extra, '_tasks')]
155  if hasattr(extra, '_collection'): # for cms.Task
156  items += [('subtask', x) for x in getattr(extra, '_collection')]
157  if hasattr(extra, '_operand'): # for _SeqenceNegation etc.
158  items += [('operand', getattr(extra, '_operand'))]
159  if isinstance(extra, dict): # stuff that we track explicitly^
160  for key, value in extra.items():
161  if isinstance(value, list):
162  items += [(key, x) for x in value]
163  else:
164  items += [(key, value)]
165 
166  for name, child in items:
167  collect_trace(child, name, graph, entry)
168 
169  else:
170  if not thing is None:
171  print("No _trace_events found in %s.\nMaybe turn on tracing for %s?" % (thing, classname))
172  print(" Found in %s" % (parent,))
173 
174 
175 def writeoutput(graph):
176  progname = " ".join(PREFIXINFO)
177  print("+Done running %s, writing output..." % progname)
178 
179  def formatfile(filename):
180  filename = os.path.abspath(filename)
181  for pfx in STRIPPATHS:
182  if filename.startswith(pfx):
183  filename = filename[len(pfx):]
184  return filename
185 
186  files = set()
187  for child, parent, relation in graph:
188  files.add(child[2][0][0])
189  files.add(parent[2][0][0])
190 
191  conn = sqlite3.connect(os.environ["CMSSWCALLTREE"])
192  cur = conn.cursor()
193  cur.executescript("""
194  CREATE TABLE IF NOT EXISTS file(id INTEGER PRIMARY KEY,
195  name TEXT, UNIQUE(name)
196  );
197  CREATE TABLE IF NOT EXISTS trace(id INTEGER PRIMARY KEY,
198  parent INTEGER, -- points into same table, recursively
199  file INTEGER, line INTEGER,
200  FOREIGN KEY(parent) REFERENCES trace(id),
201  FOREIGN KEY(file) REFERENCES file(id),
202  UNIQUE(parent, file, line)
203  );
204  CREATE TABLE IF NOT EXISTS relation(id INTEGER PRIMARY KEY,
205  place INTEGER,
206  place_type TEXT,
207  usedby INTEGER,
208  usedby_type TEXT,
209  relation TEXT,
210  source TEXT,
211  FOREIGN KEY(place) REFERENCES trace(id),
212  FOREIGN KEY(usedby) REFERENCES trace(id)
213  );
214  CREATE INDEX IF NOT EXISTS placeidx ON relation(place);
215  CREATE INDEX IF NOT EXISTS usedbyidx ON relation(usedby);
216  CREATE INDEX IF NOT EXISTS traceidx ON trace(file);
217  -- SQLite does not optimise that one well, but a VIEW is still nice to have...
218  CREATE VIEW IF NOT EXISTS fulltrace AS
219  WITH RECURSIVE fulltrace(level, baseid, parent, file, name, line) AS (
220  SELECT 1 AS level, trace.id, parent, trace.file, file.name, line FROM trace
221  INNER JOIN file ON file.id = trace.file
222  UNION SELECT level+1, baseid, trace.parent, trace.file, file.name, trace.line FROM fulltrace
223  INNER JOIN trace ON trace.id = fulltrace.parent
224  INNER JOIN file ON file.id = trace.file)
225  SELECT * FROM fulltrace;
226  """)
227  cur.executemany("INSERT OR IGNORE INTO file(name) VALUES (?);",
228  ((formatfile(f),) for f in files))
229  def inserttrace(loc):
230  parent = 0
231  for filename, line in reversed(loc):
232  conn.execute("INSERT OR IGNORE INTO trace(parent, file, line) SELECT ?, id, ? FROM file WHERE name == ?;", (parent, line, formatfile(filename)))
233  cur = conn.execute("SELECT trace.id FROM trace LEFT JOIN file ON trace.file == file.id WHERE trace.parent = ? AND file.name = ? AND trace.line = ?;", (parent, formatfile(filename), line))
234  for row in cur:
235  parent = row[0]
236  return parent
237 
238  for child, parent, relation in graph:
239  cevt, cclassname, cloc = child
240  pevt, pclassname, ploc = parent
241  place = inserttrace(cloc)
242  usedby = inserttrace(ploc)
243  cur.execute("INSERT OR IGNORE INTO relation(place, place_type, usedby, usedby_type, relation, source) VALUES (?,?,?,?,?,?);", (
244  place, "%s::%s" % (cclassname, cevt),
245  usedby, "%s::%s" % (pclassname, pevt),
246  relation, progname
247  ))
248  conn.commit()
249  conn.close()
250 
251 
252 
253 def addprefixinfo(argv):
254  cwd = os.path.abspath(os.getcwd())
255  wf = re.match(".*/(\d+\.\d+)_", cwd)
256  if wf:
257  PREFIXINFO.append("wf")
258  PREFIXINFO.append(wf.groups()[0])
259  online = re.match("(.*/)?(.*)_dqm_sourceclient-live_cfg\.py", argv[0])
260  if online:
261  PREFIXINFO.append("online")
262  PREFIXINFO.append(online.groups()[1])
263  step = re.match("(step\d+)_.*\.py", argv[0])
264  if step:
265  PREFIXINFO.append(step.groups()[0])
266  processing = re.match("step\d+_.*(RECO|ALCA|HARVEST).*\.py", argv[0])
267  if processing:
268  PREFIXINFO.append(processing.groups()[0])
269  if not PREFIXINFO:
270  PREFIXINFO.append(argv[0])
271 
272 def setupenv():
273  bindir = tempfile.mkdtemp()
274  print("+Setting up in ", bindir)
275  os.symlink(ARGV0, bindir + "/cmsRun")
276  os.environ["PATH"] = bindir + ":" + os.environ["PATH"]
277  os.environ["CMSSWCALLTREE"] = bindir + "/" + OUTFILE_TREE
278  os.environ["CMSSWCALLBASE"] = os.path.abspath(os.getcwd()) + "/"
279  with open(os.environ["CMSSWCALLTREE"], "w") as f:
280  pass
281  return bindir
282 
283 def cleanupenv(tmpdir):
284  print("+Cleaning up ", tmpdir)
285  copy(os.environ["CMSSWCALLTREE"], ".")
286  rmtree(tmpdir)
287 
288 
289 def trace_command(argv):
290  tmpdir = None
291  if not "CMSSWCALLTREE" in os.environ:
292  tmpdir = setupenv()
293 
294  subprocess.call(argv)
295 
296  if tmpdir:
297  cleanupenv(tmpdir)
298 
299 def trace_python(prog_argv, path):
300  graph = []
301  sys.argv = prog_argv
302  progname = prog_argv[0]
303  file_path = searchinpath(progname, path)
304  try:
305  with open(file_path) as fp:
306  code = compile(fp.read(), progname, 'exec')
307  globals = {}
308  try:
309  exec code in globals, globals
310  except:
311  print(traceback.format_exc())
312  finally:
313  # reporting is only possible if the config was executed successfully.
314  # we still do it in case of an exception, which can happen after convertToUnscheduled()
315  print("+Collecting trace information from %s..." % globals["process"])
316  collect_trace(globals["process"], 'cmsrun', graph, ('cmsRun', '', ((progname, 0),)))
317  writeoutput(graph)
318 
319  except OSError as err:
320  print("+Cannot run file %r because: %s" % (sys.argv[0], err))
321  sys.exit(1)
322  except SystemExit:
323  pass
324  # this is not necessarily reached at all.
325  sys.exit(0)
326 
327 def searchinpath(progname, path):
328  # Search $PATH. There seems to be no pre-made function for this.
329  for entry in path:
330  file_path = os.path.join(entry, progname)
331  if os.path.isfile(file_path):
332  break
333  if not os.path.isfile(file_path):
334  print("+Cannot find program (%s) in modified $PATH (%s)." % (progname, path))
335  sys.exit(1)
336  print("+Found %s as %s in %s." % (progname, file_path, path))
337  return file_path
338 
339 
340 def help():
341  print("Usage: %s <some cmssw commandline>" % (sys.argv[0]))
342  print(" The given programs will be executed, instrumenting calls to cmsRun.")
343  print(" cmsRun will not actually run cmssw, but all the Python code will be executed and instrumentd. The results are written to the file `%s` in the same directory." % OUTFILE_TREE)
344  print(" The callgraph output lists edges pointing from each function to the one calling it.")
345  print(" To view the results using a simple webpage, use\n %s serve" % sys.argv[0])
346  print("Examples:")
347  print(" %s runTheMatrix.py -l 1000 --ibeos" % sys.argv[0])
348 
349 def main():
350  print("+Running cmsswConfigtrace...")
351  global ARGV0
352  ARGV0 = sys.argv[0]
353  if sys.argv[0].endswith('cmsRun'):
354  print("+Wrapping cmsRun...")
355  addprefixinfo(sys.argv[1:])
356  STRIPPATHS.append(os.environ["CMSSWCALLBASE"])
357  trace_python(sys.argv[1:], ["."])
358  return
359  if len(sys.argv) <= 1:
360  help()
361  return
362  # else
363  print("+Running command with tracing %s..." % sys.argv[1:])
364  trace_command(sys.argv[1:])
365 
366 
367 
369  # we use STRIPPATHS as a search path to find code files.
370  STRIPPATHS.append(os.path.abspath(os.getcwd()) + "/")
371 
372  import SimpleHTTPServer
373  import SocketServer
374  import urllib
375 
376  conn = sqlite3.connect(OUTFILE_TREE)
377 
378  def escape(s):
379  return str(s).replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;")
380 
381  def formatsource(source, formatstr = '<em class="%s">%s</em>'):
382  processings = ["ALCA", "RECO", "HARVEST", "online"]
383  info = source.split(" ")
384  processing = " ".join(filter(lambda x: x in processings, info))
385  source = " ".join(filter(lambda x: x not in processings, info))
386  return formatstr % (processing, escape(source))
387 
388  def formatplace(filename, line):
389  MAXLEN = 80
390  shortname = filename[ :(MAXLEN-3)/2] + "..." + filename[-(MAXLEN-3)/2: ] if len(filename) > MAXLEN else filename
391  return '<a href="/%s#%s" target="_blank">%s:%s</a>' % (escape(filename), line, escape(shortname), line)
392 
393  def index():
394  out = [escape('goto to /<filename> for info about a file')]
395 
396  wfs = defaultdict(list)
397  for source, wf in conn.execute(""" -- some SQL hackery here to parse "source"
398  SELECT DISTINCT source, substr(source, instr(source, "wf ")+3)*1 FROM relation ORDER BY 2, 1;"""):
399  wfs[wf].append('<a href="/workflow/%s">%s</a>' % (urllib.quote(source), formatsource(source)))
400  out.append("<ul>")
401  for wf in wfs:
402  out.append('<li>' + " ".join(wfs[wf]) + "</li>")
403  out.append("</ul>")
404 
405  out.append("<ul>")
406  for f in conn.execute("SELECT name FROM file ORDER BY name;"):
407  name = escape(f[0])
408  out.append('<li><a href="/%s">%s</a></li>' % (name, name))
409  out.append("</ul>")
410 
411  return "\n".join(out)
412 
413  def showworkflow(source):
414  source = urllib.unquote(source)
415  cur = conn.execute("""
416  SELECT DISTINCT file.name FROM relation
417  INNER JOIN trace ON place = trace.id
418  INNER JOIN file ON file.id = trace.file
419  WHERE relation.source = ?
420  ORDER BY file.name;
421  """, (source, ))
422  out = ["Files used by workflow %s: <ul>" % formatsource(source)]
423  for f in cur:
424  name = escape(f[0])
425  out.append('<li><a href="/%s">%s</a></li>' % (name, name))
426  out.append("</ul>")
427  return "\n".join(out)
428 
429  def showfile(filename):
430  out = []
431  out.append('<script src="https://rawgit.com/google/code-prettify/master/src/prettify.js"></script>')
432  out.append('<link rel="stylesheet" href="https://rawgit.com/google/code-prettify/master/src/prettify.css"></link>')
433 
434  lines = None
435  for d in STRIPPATHS:
436  try:
437  with open(d + filename) as f:
438  lines = f.readlines()
439  out.append("Read %s" % f.name)
440  break
441  except:
442  pass
443 
444  if lines:
445  cur = conn.execute("""
446  SELECT DISTINCT trace.line, source FROM relation
447  INNER JOIN trace on relation.place = trace.id
448  INNER JOIN file ON trace.file == file.id
449  WHERE file.name == ? ORDER BY line, source;""", (filename,))
450  sourceinfo = defaultdict(list)
451  for line, source in cur:
452  sourceinfo[line].append(source)
453 
454  out.append('<pre class="prettyprint linenums">')
455  for i, l in enumerate(lines):
456  # put the text into data-tag here and move it later, to not mess up syntax HL
457  tags = [formatsource(source, '<em class="%%s" data-tag="%%s" data-line="%d"></em>' % (i+1)) for source in sourceinfo[i+1]]
458  out.append(escape(l).rstrip() + "".join(tags))
459  out.append('</pre>')
460 
461  out.append("""<script type="text/javascript">
462  PR.prettyPrint();
463  clickfunc = function(evt) {
464  document.querySelectorAll("li > iframe, li > br").forEach(function(e) {e.remove()});
465  dest = "/info" + window.location.pathname + ":" + this.getAttribute("data-line");
466  this.parentElement.insertAdjacentHTML("beforeend", '<br><iframe width="90%" height="500px" frameborder="0" src="' + dest + '"></iframe><br>');
467  };
468  document.querySelectorAll("li > em").forEach(function(e) {
469  e.innerText = e.getAttribute("data-tag");
470  e.onclick = clickfunc;
471  })
472 
473  n = 1*window.location.hash.replace("#", "");
474  if (n > 0) {
475  li = document.querySelectorAll("li")[n-1];
476  li.style = "background: #ee7";
477  li.scrollIntoView();
478  }
479  </script>""")
480 
481  else:
482  out.append("Could not find %s" % filename)
483 
484  return "\n".join(out)
485 
486 
487  def showinfo(filename, line):
488  line = int(line)
489  out = []
490  def queryandoutput(startfrom, to, directiontext):
491  # we format in the side of the relation to query for here...
492  cur = conn.execute("""
493  SELECT place_type, -- why did we trace this line?
494  <to>file.name, <to>trace.line, -- where was it used?
495  usedby, usedby_type, relation, -- what was it used for?
496  place, source -- why did this code run?
497  FROM relation
498  INNER JOIN trace AS placetrace ON placetrace.id = relation.place
499  INNER JOIN trace AS usedbytrace ON usedbytrace.id = relation.usedby
500  INNER JOIN file AS placefile ON placefile.id = placetrace.file
501  INNER JOIN file AS usedbyfile ON usedbyfile.id = usedbytrace.file
502  WHERE <from>file.name = ? AND <from>trace.line = ?
503  LIMIT 1000; """
504  .replace("<from>", startfrom).replace("<to>", to), (filename, line))
505  out.append("<p>%s %s <ul>" % (formatplace(filename, line), directiontext))
506  for place_type, pname, pline, usedby, usedby_type, relation, place, source in cur:
507  out.append(
508  '<li><tt>%s</tt> at %s by <tt>%s</tt> as <a href="/why/%d">%s</a> <a href="/why/%d">in</a> %s</li>'
509  % (escape(place_type), formatplace(pname, pline), escape(usedby_type), usedby, escape(relation), place, formatsource(source)))
510  out.append("</ul></p>")
511 
512  queryandoutput("place", "usedby", "is used as")
513  queryandoutput("usedby", "place", "uses")
514 
515  return "\n".join(out)
516 
517  def showwhy(id):
518  id = int(id)
519  # this (WHERE before recursion) will optimize better than the view.
520  cur = conn.execute("""
521  WITH RECURSIVE fulltrace(level, baseid, parent, file, name, line) AS (
522  SELECT 1 AS level, trace.id, parent, trace.file, file.name, line FROM trace
523  INNER JOIN file ON file.id = trace.file
524  WHERE trace.id = ?
525  UNION SELECT level+1, baseid, trace.parent, trace.file, file.name, trace.line FROM fulltrace
526  INNER JOIN trace ON trace.id = fulltrace.parent
527  INNER JOIN file ON file.id = trace.file)
528  SELECT name, line FROM fulltrace ORDER BY level;""", (id,))
529  out = []
530  out.append("Full stack trace:<ul>")
531  for name, line in cur:
532  out.append('<li>%s</li>' % formatplace(name, line))
533  out.append("</ul>")
534  return "\n".join(out)
535 
536  ROUTES = [
537  (re.compile('/workflow/(.*)$'), showworkflow),
538  (re.compile('/info/(.*):(\d+)$'), showinfo),
539  (re.compile('/why/(\d+)$'), showwhy),
540  (re.compile('/([^.]*[.]?[^.]+[.]?[^.]*)$'), showfile),
541  (re.compile('/$'), index),
542  ]
543 
544  def do_GET(self):
545  try:
546  res = None
547  for pattern, func in ROUTES:
548  m = pattern.match(self.path)
549  if m:
550  res = func(*m.groups())
551  break
552 
553  if res:
554  self.send_response(200, "Here you go")
555  self.send_header("Content-Type", "text/html; charset=utf-8")
556  self.end_headers()
557  self.wfile.write("""<html><style>
558  body {
559  font-family: sans;
560  }
561  em {
562  cursor: pointer;
563  padding: 0 2px;
564  margin: 1 2px;
565  background: #999;
566  }
567  em.ALCA {background: #ee9; }
568  em.RECO {background: #9e9; }
569  em.HARVEST {background: #99e; }
570  em.online {background: #e99; }
571  </style><body>""")
572  self.wfile.write(res)
573  self.wfile.write("</body></html>")
574  self.wfile.close()
575  else:
576  self.send_response(400, "Something went wrong")
577  except:
578  trace = traceback.format_exc()
579  self.send_response(500, "Things went very wrong")
580  self.send_header("Content-Type", "text/plain; charset=utf-8")
581  self.end_headers()
582  self.wfile.write(trace)
583  self.wfile.close()
584 
585  Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
586  Handler.do_GET = do_GET
587  httpd = SocketServer.TCPServer(("",SERVE_PORT), Handler)
588  print("serving at port", SERVE_PORT)
589  httpd.serve_forever()
590 
591 if __name__ == '__main__':
592  if sys.argv[1] == "serve":
593  serve_main()
594  else:
595  main()
596 
filterCSVwithJSON.copy
copy
Definition: filterCSVwithJSON.py:36
cmsswConfigtrace.new_items_
def new_items_(self)
Definition: cmsswConfigtrace.py:110
cmsswConfigtrace.help
def help()
Definition: cmsswConfigtrace.py:340
cmsswConfigtrace.trace_command
def trace_command(argv)
Definition: cmsswConfigtrace.py:289
join
static std::string join(char **cmd)
Definition: RemoteFile.cc:17
cmsswConfigtrace.flatten
def flatten(*args)
Definition: cmsswConfigtrace.py:71
cmsswConfigtrace.searchinpath
def searchinpath(progname, path)
Definition: cmsswConfigtrace.py:327
cmsswConfigtrace.writeoutput
def writeoutput(graph)
Definition: cmsswConfigtrace.py:175
mps_monitormerge.items
list items
Definition: mps_monitormerge.py:29
any
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:38
cmsswConfigtrace.serve_main
def serve_main()
Definition: cmsswConfigtrace.py:368
str
#define str(s)
Definition: TestProcessor.cc:52
ALCARECOTkAlBeamHalo_cff.filter
filter
Definition: ALCARECOTkAlBeamHalo_cff.py:27
cmsswConfigtrace.collect_trace
def collect_trace(thing, name, graph, parent)
Definition: cmsswConfigtrace.py:134
cmsswConfigtrace.cleanupenv
def cleanupenv(tmpdir)
Definition: cmsswConfigtrace.py:283
print
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:46
mps_setup.append
append
Definition: mps_setup.py:85
cmsswConfigtrace.trace_python
def trace_python(prog_argv, path)
Definition: cmsswConfigtrace.py:299
createfilelist.int
int
Definition: createfilelist.py:10
cmsswFiletrace.formatfile
def formatfile(filename)
Definition: cmsswFiletrace.py:87
TrackCollections2monitor_cff.func
func
Definition: TrackCollections2monitor_cff.py:359
cmsswConfigtrace.main
def main()
Definition: cmsswConfigtrace.py:349
main
Definition: main.py:1
writeEcalDQMStatus.write
write
Definition: writeEcalDQMStatus.py:48
Mixins
cmsswConfigtrace.auto_inspect
def auto_inspect()
Definition: cmsswConfigtrace.py:37
cmsswConfigtrace.addprefixinfo
def addprefixinfo(argv)
Definition: cmsswConfigtrace.py:253
AlignmentPI::index
index
Definition: AlignmentPayloadInspectorHelper.h:46
cmsswConfigtrace.setupenv
def setupenv()
Definition: cmsswConfigtrace.py:272
genParticles_cff.map
map
Definition: genParticles_cff.py:11
cmsswConfigtrace.trace_location
def trace_location(thing, name, extra=lambda thing, *args, **thing kwargs)
Definition: cmsswConfigtrace.py:55
SequenceTypes
python.rootplot.root2matplotlib.replace
def replace(string, replacements)
Definition: root2matplotlib.py:444