Commit 47ef5fd6 authored by Kirill Smelkov's avatar Kirill Smelkov

X on zobjtrace

To know through which ZODB object A another ZODB object B is accessed.
parent fc4c86e6
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2020 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
#
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
"""zobjtrace is python interpreter that traces ZODB object access.
XXX
"""
from __future__ import print_function, absolute_import
# patch Persistent to trace access
import persistent
origPersistent = persistent.Persistent
# TracePersistent is Persistent that traces through which persistent object an
# persistent object was accessed.
class TracePersistent(origPersistent):
def __getattribute__(self, name):
obj = origPersistent.__getattribute__(self, name)
if isinstance(obj, origPersistent):
traceAccess('get .%s' % name, self, obj)
return obj
def __setattr__(self, name, value):
origPersistent.__setattr__(self, name, value)
if isinstance(value, origPersistent):
traceAccess('set .%s' % name, self, value)
# XXX __delattr__
# XXX __getitem__ ?
# XXX __setitem__
# XXX __delitem__
# XXX __missing__
# XXX __iter__
# XXX __reversed__
# XXX __contains__
# XXX __get__/__set__/__delete__ ?
persistent.Persistent = TracePersistent
# XXX patch BTrees to trace item access
# traceAccess traces access from persistent object a to b.
def traceAccess(op, a, b):
assert isinstance(a, origPersistent)
assert isinstance(b, origPersistent)
#print('%s\tobj<%s|%s> -> obj<%s|%s>' %
# (op, oidstr(a._p_oid), typeof(a), oidstr(b._p_oid), typeof(b)))
print('%s\t%s(%s) -> %s(%s)' %
(op, oidstr(a._p_oid), typeof(a), oidstr(b._p_oid), typeof(b)))
# oidstr returns string representation of object ID.
# it is either %d(ID) or ø if oid was not yet assigned.
def oidstr(oid):
if oid is None:
return 'ø'
return '%d' % u64(oid)
# u64 = ZODB.utils.u64, but we don't want to preimport ZODB yet
import struct
_oid_struct = struct.Struct('>Q')
def u64(oid):
assert isinstance(oid, bytes)
assert len(oid) == 8
return _oid_struct.unpack(oid)[0]
# typeof returns fully qualified type of object.
def typeof(obj): # -> str
typ = type(obj)
return "%s.%s" % (typ.__module__, typ.__name__)
# tail to pymain with already patched Persistent
import sys
from gpython import pymain
def main():
# XXX sys.executable = sys.argv[0]
pymain(sys.argv[1:])
if __name__ == '__main__':
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment