#!/usr/bin/env python # -*- coding: utf-8 -*- """ Backend management. Creating new backends --------------------- A new backend named 'foo-bar' corresponds to Python module 'tracetool/backend/foo_bar.py'. A backend module should provide a docstring, whose first non-empty line will be considered its short description. All backends must generate their contents through the 'tracetool.out' routine. Backend attributes ------------------ ========= ==================================================================== Attribute Description ========= ==================================================================== PUBLIC If exists and is set to 'True', the backend is considered "public". ========= ==================================================================== Backend functions ----------------- ======== ======================================================================= Function Description ======== ======================================================================= Called to generate the format- and backend-specific code for each of the specified events. If the function does not exist, the backend is considered not compatible with the given format. ======== ======================================================================= """ __author__ = "Lluís Vilanova " __copyright__ = "Copyright 2012, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@linux.vnet.ibm.com" import os import tracetool def get_list(only_public = False): """Get a list of (name, description) pairs.""" res = [("nop", "Tracing disabled.")] modnames = [] for filename in os.listdir(tracetool.backend.__path__[0]): if filename.endswith('.py') and filename != '__init__.py': modnames.append(filename.rsplit('.', 1)[0]) for modname in modnames: module = tracetool.try_import("tracetool.backend." + modname) # just in case; should never fail unless non-module files are put there if not module[0]: continue module = module[1] public = getattr(module, "PUBLIC", False) if only_public and not public: continue doc = module.__doc__ if doc is None: doc = "" doc = doc.strip().split("\n")[0] name = modname.replace("_", "-") res.append((name, doc)) return res def exists(name): """Return whether the given backend exists.""" if len(name) == 0: return False if name == "nop": return True name = name.replace("-", "_") return tracetool.try_import("tracetool.backend." + name)[1] def compatible(backend, format): """Whether a backend is compatible with the given format.""" if not exists(backend): raise ValueError("unknown backend: %s" % backend) backend = backend.replace("-", "_") format = format.replace("-", "_") if backend == "nop": return True else: func = tracetool.try_import("tracetool.backend." + backend, format, None)[1] return func is not None def _empty(events): pass def generate(backend, format, events): """Generate the per-event output for the given (backend, format) pair.""" if not compatible(backend, format): raise ValueError("backend '%s' not compatible with format '%s'" % (backend, format)) backend = backend.replace("-", "_") format = format.replace("-", "_") if backend == "nop": func = tracetool.try_import("tracetool.format." + format, "nop", _empty)[1] else: func = tracetool.try_import("tracetool.backend." + backend, format, None)[1] func(events)