From b104390b8cddef9fc5275b973a70578bb6c72ca1 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Thu, 27 Sep 2012 08:58:54 -0400 Subject: [PATCH] Add --trace-libvirt option to see every libvirt API call --- src/virt-manager.py.in | 10 +++++ src/virtManager/module_trace.py | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/virtManager/module_trace.py diff --git a/src/virt-manager.py.in b/src/virt-manager.py.in index 1f93d229..174978e6 100755 --- a/src/virt-manager.py.in +++ b/src/virt-manager.py.in @@ -117,6 +117,10 @@ def parse_commandline(): optParser.add_option("--profile", dest="profile", help=optparse.SUPPRESS_HELP, metavar="FILE") + # Trace every libvirt API call to debug output + optParser.add_option("--trace-libvirt", dest="tracelibvirt", + help=optparse.SUPPRESS_HELP, action="store_true") + optParser.add_option("-c", "--connect", dest="uri", help="Connect to hypervisor at URI", metavar="URI") optParser.add_option("--debug", action="store_true", dest="debug", @@ -301,6 +305,12 @@ def main(): cli.check_virtinst_version(virtinst_str) + if options.tracelibvirt: + logging.debug("Libvirt tracing requested") + import virtManager.module_trace + import libvirt + libvirt = virtManager.module_trace.wrap_module(libvirt) + # Add our icon dir to icon theme icon_theme = gtk.icon_theme_get_default() icon_theme.prepend_search_path(icon_dir) diff --git a/src/virtManager/module_trace.py b/src/virtManager/module_trace.py new file mode 100644 index 00000000..d393c809 --- /dev/null +++ b/src/virtManager/module_trace.py @@ -0,0 +1,79 @@ +# +# Copyright (C) 2011 Red Hat, Inc. +# Copyright (C) 2011 Cole Robinson +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. +# + +# This module provides a simple way to trace any activity on a specific +# python class or module. The trace output is logged using the regular +# logging infrastructure. Invoke this with virt-manager --trace-libvirt + +import logging +import time +import re +import traceback + +from types import FunctionType +from types import ClassType +from types import MethodType + +_debug = False + +def generate_wrapper(origfunc, name, tb): + def newfunc(*args, **kwargs): + logging.debug("TRACE %s: %s %s %s" % (time.time(), name, args, kwargs)) + if tb: + logging.debug("BACKTRACE '%s'" % "".join(traceback.format_stack())) + return origfunc(*args, **kwargs) + + return newfunc + +def wrap_func(module, funcobj, tb): + name = funcobj.__name__ + if _debug: + logging.debug("wrapfunc %s %s" % (funcobj, name)) + + newfunc = generate_wrapper(funcobj, name, tb) + setattr(module, name, newfunc) + +def wrap_method(classobj, methodobj, tb): + name = methodobj.__name__ + fullname = classobj.__name__ + "." + name + if _debug: + logging.debug("wrapmeth %s" % (fullname)) + + newfunc = generate_wrapper(methodobj, fullname, tb) + setattr(classobj, name, newfunc) + +def wrap_class(classobj, tb): + if _debug: + logging.debug("wrapclas %s %s" % (classobj, classobj.__name__)) + + for name in dir(classobj): + obj = getattr(classobj, name) + if type(obj) is MethodType: + wrap_method(classobj, obj, tb) + +def wrap_module(module, regex=None, tb=False): + for name in dir(module): + if regex and not re.match(regex, name): + continue + obj = getattr(module, name) + if type(obj) is FunctionType: + wrap_func(module, obj, tb) + if type(obj) is ClassType: + wrap_class(obj, tb)