[Checkins] SVN: z3c.zodbtracing/ Package is meant to aid debugging/tracing ZODB.

Adam Groszer adamg at fw.hu
Mon Mar 5 12:51:18 EST 2007


Log message for revision 72994:
  Package is meant to aid debugging/tracing ZODB.
  A special case was to determine from which point of the application
  a huge amount of object loading comes.
  

Changed:
  A   z3c.zodbtracing/branches/
  A   z3c.zodbtracing/tags/
  A   z3c.zodbtracing/trunk/
  A   z3c.zodbtracing/trunk/src/
  A   z3c.zodbtracing/trunk/src/z3c/
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/README.txt
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/TODO.txt
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/TracingStorage.py
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/__init__.py
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/events.py
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/tests.py
  A   z3c.zodbtracing/trunk/src/z3c/zodbtracing/tracer.py

-=-
Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/README.txt
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/README.txt	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/README.txt	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,37 @@
+ZODB tracing
+============
+
+Package is meant to aid debugging/tracing ZODB.
+A special case was to determine from which point of the application
+a huge amount of object loading comes.
+
+TracingStorage:
+---------------
+A ZODB storage that allows tracing the calls going to the real storage.
+Should be able to trace any type of storage.
+Emits events using zope.notify on method calls.
+A `statCollector` object can be installed, which can collect data.
+
+Sample usage::
+
+	collector = textStatCollector('/tmp/1.txt')
+	storage     = TracingStorage(FileStorage.FileStorage(Path),
+								 statCollector=coll)
+    #instead of this:
+	#storage     = FileStorage.FileStorage(Path)
+    
+	db          = DB(storage,
+					 pool_size=pool_size,
+					 cache_size=cache_size)
+	connection  = db.open(transaction_manager=tm)
+	root        = connection.root()
+	return (root,connection,db,storage,tm)
+
+Usage with Zope::
+
+N/A yet, ZConfig has to be modified!
+
+textStatCollector:
+------------------
+`statCollector` class to dump _every_ possible data regarding the method call
+to a text file. Be careful, that will be a HUGE amount of data!
\ No newline at end of file


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/README.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/TODO.txt
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/TODO.txt	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/TODO.txt	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,6 @@
+Handle more methods of the storage. If somebody needs that, please do it.
+
+Tracing for the Connection might be possible by replacing ZODB.DB.klass
+with our own proxy.
+
+Bit more tests
\ No newline at end of file


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/TODO.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/TracingStorage.py
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/TracingStorage.py	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/TracingStorage.py	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,85 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+"""A ZODB storage that allows tracing the calls going to the real storage.
+
+"""
+__docformat__ = "reStructuredText"
+
+from zope.interface import implements
+from zope.event import notify
+from zope.proxy import getProxiedObject, non_overridable
+from zope.proxy.decorator import SpecificationDecoratorBase
+
+from z3c.zodbtracing import events
+
+class TracingStorage(SpecificationDecoratorBase):
+    """A storage to support tracing the calls going to the real storage."""
+
+    # Proxies can't have a __dict__ so specifying __slots__ here allows
+    # us to have instance attributes explicitly on the proxy.
+    __slots__ = ('statCollector')
+
+    def __new__(self, storage, statCollector=None):
+        return SpecificationDecoratorBase.__new__(self, storage)
+
+    def __init__(self, storage, statCollector=None):
+        SpecificationDecoratorBase.__init__(self, storage)
+        
+        self.statCollector = statCollector
+        
+        if self.statCollector is not None:
+            self.statCollector.initCalled()
+
+    @non_overridable
+    def __repr__(self):
+        normal_storage = getProxiedObject(self)
+        return '<TracingStorage proxy for %r at %s>' % (normal_storage,
+                                                     hex(id(self)))
+    
+    def methodCalled(self, name, *arg, **kw):
+        unproxied = getProxiedObject(self)
+        func = getattr(unproxied, name)
+        result = func(*arg, **kw)
+        
+        if self.statCollector is not None:
+            self.statCollector.methodCalled(name, result, *arg, **kw)
+        
+        eventKlass = events.EVENTMAP[name]
+        eventObj = eventKlass(result, *arg, **kw)
+        notify(eventObj)
+        return result
+    
+    @non_overridable
+    def load(self, *arg, **kw):
+        return self.methodCalled('load', *arg, **kw)
+
+    @non_overridable
+    def store(self, *arg, **kw):
+        return self.methodCalled('store', *arg, **kw)
+    
+    @non_overridable
+    def close(self, *arg, **kw):
+        return self.methodCalled('close', *arg, **kw)
+    
+    @non_overridable
+    def cleanup(self, *arg, **kw):
+        return self.methodCalled('cleanup', *arg, **kw)
+    
+    @non_overridable
+    def lastSerial(self, *arg, **kw):
+        return self.methodCalled('lastSerial', *arg, **kw)
+    
+    @non_overridable
+    def lastTransaction(self, *arg, **kw):
+        return self.methodCalled('lastTransaction', *arg, **kw)
\ No newline at end of file


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/TracingStorage.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/__init__.py
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/__init__.py	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/__init__.py	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+#
+# This file is necessary to make this directory a package.
+
+__version__ = "0.0.1"
+__license__ = "ZPL"
+__title__ = u"ZODB tracing storage"
\ No newline at end of file


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/events.py
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/events.py	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/events.py	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+"""A ZODB storage that allows tracing the calls going to the real storage.
+
+"""
+__docformat__ = "reStructuredText"
+
+from zope.interface import Interface
+from zope.interface import Attribute
+from zope.interface import implements
+
+    #A subclass must define the following methods:
+    #load()
+    #store()
+    #close()
+    #cleanup()
+    #lastSerial()
+    #lastTransaction()
+    #
+    #It must override these hooks:
+    #_begin()
+    #_vote()
+    #_abort()
+    #_finish()
+    #_clear_temp()
+    #
+    #If it stores multiple revisions, it should implement
+    #loadSerial()
+    #loadBefore()
+    #iterator()
+    #
+    #If the subclass wants to implement undo, it should implement the
+    #multiple revision methods and:
+    #undo()
+    #undoInfo()
+    #undoLog()
+    #
+    #If the subclass wants to implement versions, it must implement:
+    #abortVersion()
+    #commitVersion()
+    #modifiedInVersion()
+    #versionEmpty()
+    #versions()
+
+class ITracingStorageEvent(Interface):
+    """base IF for events
+    all derived events will have the name
+    ITracingStorageEvent_<method name>"""
+    args = Attribute("Arguments")
+    kw = Attribute("Keyword Arguments")
+    result = Attribute("Base storage call result")
+
+class ITracingStorageEvent_load(ITracingStorageEvent):
+    pass
+
+class ITracingStorageEvent_store(ITracingStorageEvent):
+    pass
+
+class ITracingStorageEvent_close(ITracingStorageEvent):
+    pass
+
+class ITracingStorageEvent_cleanup(ITracingStorageEvent):
+    pass
+
+class ITracingStorageEvent_lastSerial(ITracingStorageEvent):
+    pass
+
+class ITracingStorageEvent_lastTransaction(ITracingStorageEvent):
+    pass
+
+class TracingStorageEvent(object):
+    """base class for events
+    all derived events will have the name
+    TracingStorageEvent_<method name>"""
+    
+    implements(ITracingStorageEvent)
+    
+    def __init__(self, result_=None, *args, **kw):
+        self.args = args
+        self.kw = kw
+        self.result = result_
+
+class TracingStorageEvent_load(TracingStorageEvent):
+    implements(ITracingStorageEvent_load)
+
+class TracingStorageEvent_store(TracingStorageEvent):
+    implements(ITracingStorageEvent_store)
+
+class TracingStorageEvent_close(TracingStorageEvent):
+    implements(ITracingStorageEvent_close)
+
+class TracingStorageEvent_cleanup(TracingStorageEvent):
+    implements(ITracingStorageEvent_cleanup)
+
+class TracingStorageEvent_lastSerial(TracingStorageEvent):
+    implements(ITracingStorageEvent_lastSerial)
+
+class TracingStorageEvent_lastTransaction(TracingStorageEvent):
+    implements(ITracingStorageEvent_lastTransaction)
+
+EVENTMAP = {
+    'load': TracingStorageEvent_load,
+    'store': TracingStorageEvent_store,
+    'close': TracingStorageEvent_close,
+    'cleanup': TracingStorageEvent_cleanup,
+    'lastSerial': TracingStorageEvent_lastSerial,
+    'lastTransaction': TracingStorageEvent_lastTransaction
+}
\ No newline at end of file


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/events.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/tests.py
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/tests.py	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/tests.py	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+
+import os, unittest
+import ZODB.FileStorage
+
+
+from ZODB.tests.testFileStorage import FileStorageTests
+from z3c.zodbtracing.TracingStorage import TracingStorage
+
+class TracingFileStorageTests(FileStorageTests):
+    def open(self, **kwargs):
+        #self._storage = ZODB.FileStorage.FileStorage('FileStorageTests.fs',
+        #                                             **kwargs)
+        self._storage = TracingStorage(
+            ZODB.FileStorage.FileStorage('FileStorageTests.fs',
+                                                     **kwargs))
+
+#class BaseFileStorageTests(StorageTestBase.StorageTestBase):
+#
+#    def open(self, **kwargs):
+#        self._storage = ZODB.FileStorage.FileStorage('FileStorageTests.fs',
+#                                                     **kwargs)
+#
+#    def setUp(self):
+#        self.open(create=1)
+#
+#    def tearDown(self):
+#        self._storage.close()
+#        self._storage.cleanup()
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TracingFileStorageTests,
+                                     prefix="check"))
+    return suite
+
+if __name__=='__main__':
+    #unittest.main()
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/tests.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native

Added: z3c.zodbtracing/trunk/src/z3c/zodbtracing/tracer.py
===================================================================
--- z3c.zodbtracing/trunk/src/z3c/zodbtracing/tracer.py	2007-03-05 17:30:17 UTC (rev 72993)
+++ z3c.zodbtracing/trunk/src/z3c/zodbtracing/tracer.py	2007-03-05 17:51:17 UTC (rev 72994)
@@ -0,0 +1,96 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+"""A ZODB storage that allows tracing the calls going to the real storage.
+
+"""
+__docformat__ = "reStructuredText"
+
+import os
+import time
+import pprint
+import traceback
+import threading
+import cStringIO
+
+class baseStatCollector(object):
+    """base class for collecting info
+    subclass and override"""
+    def initCalled(self):
+        pass
+    
+    def methodCalled(self, methodName, result_, *args, **kw):
+        pass
+
+class textStatCollector(baseStatCollector):
+    """WARNING!!!
+    this class will dump a HUGE amount of data to the text file,
+    so be careful!!!
+    By default it dumps also a stack traceback too!
+    """
+    
+    fhnd = None # will be closed when the object gets destroyed
+    counter = 0 # might be useful to set breakpoints
+    printTB = True # dump traceback?
+    txtFileName = None
+    
+    def __init__(self, txtFileName):
+        self.txtFileName = txtFileName
+        
+        #create+truncate the file
+        open(txtFileName, 'wb').close()
+        
+        #seems that methods can be called from multiple threads
+        #that breaks havoc with file write buffering
+        l = threading.Lock()
+        self._lock_acquire = l.acquire
+        self._lock_release = l.release
+    
+    def _printTB(self):
+        if self.printTB:
+            self.fhnd.write("Traceback:\n")
+            traceback.print_stack(file=self.fhnd)
+    
+    def _print(self, header, value):
+        self.fhnd.write("%s\n" % header)
+        tmp = cStringIO.StringIO()
+        pprint.pprint(value, tmp)
+        if tmp.tell()>512:
+            tmp.seek(0)
+            self.fhnd.write(tmp.read(512))
+            self.fhnd.write("...\n")
+        else:
+            self.fhnd.write(tmp.getvalue())
+    
+    def methodCalled(self, methodName, result_, *args, **kw):
+        self._lock_acquire()
+        
+        self.fhnd = open(self.txtFileName, 'ab', 0)
+        
+        self.fhnd.write("Counter: %d\n" % self.counter)
+        self.fhnd.write("Time: %f\n" % time.time())
+        self.fhnd.write("Method: %s\n" % methodName)
+        
+        self._print("Result:", result_)
+        self._print("Args:", args)
+        self._print("KW:", kw)
+        
+        self._printTB()
+        
+        self.fhnd.write("-------------\n")
+        self.fhnd.flush()
+        self.fhnd.close()
+        
+        self.counter += 1
+        
+        self._lock_release()


Property changes on: z3c.zodbtracing/trunk/src/z3c/zodbtracing/tracer.py
___________________________________________________________________
Name: svn:keywords
   + Date Author Id Revision
Name: svn:eol-style
   + native



More information about the Checkins mailing list