1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4""" 5Backend management. 6 7 8Creating new backends 9--------------------- 10 11A new backend named 'foo-bar' corresponds to Python module 12'tracetool/backend/foo_bar.py'. 13 14A backend module should provide a docstring, whose first non-empty line will be 15considered its short description. 16 17All backends must generate their contents through the 'tracetool.out' routine. 18 19 20Backend attributes 21------------------ 22 23========= ==================================================================== 24Attribute Description 25========= ==================================================================== 26PUBLIC If exists and is set to 'True', the backend is considered "public". 27========= ==================================================================== 28 29 30Backend functions 31----------------- 32 33All the following functions are optional, and no output will be generated if 34they do not exist. 35 36=============================== ============================================== 37Function Description 38=============================== ============================================== 39generate_<format>_begin(events) Generate backend- and format-specific file 40 header contents. 41generate_<format>_end(events) Generate backend- and format-specific file 42 footer contents. 43generate_<format>(event) Generate backend- and format-specific contents 44 for the given event. 45=============================== ============================================== 46 47""" 48 49__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" 50__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>" 51__license__ = "GPL version 2 or (at your option) any later version" 52 53__maintainer__ = "Stefan Hajnoczi" 54__email__ = "stefanha@linux.vnet.ibm.com" 55 56 57import os 58 59import tracetool 60 61 62def get_list(only_public = False): 63 """Get a list of (name, description) pairs.""" 64 res = [("nop", "Tracing disabled.")] 65 modnames = [] 66 for filename in os.listdir(tracetool.backend.__path__[0]): 67 if filename.endswith('.py') and filename != '__init__.py': 68 modnames.append(filename.rsplit('.', 1)[0]) 69 for modname in sorted(modnames): 70 module = tracetool.try_import("tracetool.backend." + modname) 71 72 # just in case; should never fail unless non-module files are put there 73 if not module[0]: 74 continue 75 module = module[1] 76 77 public = getattr(module, "PUBLIC", False) 78 if only_public and not public: 79 continue 80 81 doc = module.__doc__ 82 if doc is None: 83 doc = "" 84 doc = doc.strip().split("\n")[0] 85 86 name = modname.replace("_", "-") 87 res.append((name, doc)) 88 return res 89 90 91def exists(name): 92 """Return whether the given backend exists.""" 93 if len(name) == 0: 94 return False 95 if name == "nop": 96 return True 97 name = name.replace("-", "_") 98 return tracetool.try_import("tracetool.backend." + name)[1] 99 100 101class Wrapper: 102 def __init__(self, backends, format): 103 self._backends = [backend.replace("-", "_") for backend in backends] 104 self._format = format.replace("-", "_") 105 for backend in self._backends: 106 assert exists(backend) 107 assert tracetool.format.exists(self._format) 108 109 def _run_function(self, name, *args, **kwargs): 110 for backend in self._backends: 111 func = tracetool.try_import("tracetool.backend." + backend, 112 name % self._format, None)[1] 113 if func is not None: 114 func(*args, **kwargs) 115 116 def generate_begin(self, events, group): 117 self._run_function("generate_%s_begin", events, group) 118 119 def generate(self, event, group): 120 self._run_function("generate_%s", event, group) 121 122 def generate_end(self, events, group): 123 self._run_function("generate_%s_end", events, group) 124