[Checkins] SVN: mongopersist/trunk/ Added quite detailed debug logging around collection methods
Adam Groszer
cvs-admin at zope.org
Wed Mar 28 14:51:51 UTC 2012
Log message for revision 124772:
Added quite detailed debug logging around collection methods
Changed:
U mongopersist/trunk/CHANGES.txt
U mongopersist/trunk/setup.py
U mongopersist/trunk/src/mongopersist/datamanager.py
U mongopersist/trunk/src/mongopersist/serialize.py
-=-
Modified: mongopersist/trunk/CHANGES.txt
===================================================================
--- mongopersist/trunk/CHANGES.txt 2012-03-28 14:46:09 UTC (rev 124771)
+++ mongopersist/trunk/CHANGES.txt 2012-03-28 14:51:47 UTC (rev 124772)
@@ -5,7 +5,7 @@
0.6.1 (unreleased)
------------------
-- ...
+- Added quite detailed debug logging around collection methods
0.6.0 (2012-03-12)
------------------
Modified: mongopersist/trunk/setup.py
===================================================================
--- mongopersist/trunk/setup.py 2012-03-28 14:46:09 UTC (rev 124771)
+++ mongopersist/trunk/setup.py 2012-03-28 14:51:47 UTC (rev 124772)
@@ -45,6 +45,7 @@
'setuptools',
'zope.dottedname',
'zope.interface',
+ 'zope.exceptions >=3.7.1', # required for extract_stack
],
include_package_data = True,
zip_safe = False,
Modified: mongopersist/trunk/src/mongopersist/datamanager.py
===================================================================
--- mongopersist/trunk/src/mongopersist/datamanager.py 2012-03-28 14:46:09 UTC (rev 124771)
+++ mongopersist/trunk/src/mongopersist/datamanager.py 2012-03-28 14:51:47 UTC (rev 124772)
@@ -14,14 +14,20 @@
"""Mongo Persistent Data Manager"""
from __future__ import absolute_import
import UserDict
+import logging
import persistent
import pymongo
import pymongo.dbref
import transaction
+import traceback
+import sys
import zope.interface
+from zope.exceptions import exceptionformatter
from mongopersist import interfaces, serialize
+COLLECTION_LOG = logging.getLogger('mongopersist.collection')
+
def create_conflict_error(obj, new_doc):
return interfaces.ConflictError(
None, obj,
@@ -67,8 +73,39 @@
kwargs['query'] = process_spec(self.collection, kwargs['query'])
return self.function(*args, **kwargs)
+class LoggingDecorator(object):
+
+ # these are here to be easily patched
+ ADDTB = True
+ TB_LIMIT = 10 # 10 should be sufficient to figure
+
+ def __init__(self, collection, function):
+ self.collection = collection
+ self.function = function
+
+ def __call__(self, *args, **kwargs):
+ if self.ADDTB:
+ try:
+ raise ValueError('boom')
+ except:
+ # we need here exceptionformatter, otherwise __traceback_info__
+ # is not added
+ tb = ''.join(exceptionformatter.extract_stack(
+ sys.exc_info()[2].tb_frame.f_back, limit=self.TB_LIMIT))
+ else:
+ tb = '<omitted>'
+
+ COLLECTION_LOG.debug(
+ "collection: %s.%s %s,\n args:%r,\n kwargs:%r, \n tb:\n%s",
+ self.collection.database.name, self.collection.name,
+ self.function.__name__, args, kwargs, tb)
+
+ return self.function(*args, **kwargs)
+
class CollectionWrapper(object):
+ LOGGED_METHODS = ['insert', 'update', 'remove', 'save',
+ 'find_and_modify', 'find_one', 'find', 'count']
QUERY_METHODS = ['group', 'map_reduce', 'inline_map_reduce', 'find_one',
'find', 'find_and_modify']
PROCESS_SPEC_METHODS = ['find_and_modify', 'find_one', 'find']
@@ -79,6 +116,8 @@
def __getattr__(self, name):
attr = getattr(self.collection, name)
+ if name in self.LOGGED_METHODS:
+ attr = LoggingDecorator(self.collection, attr)
if name in self.QUERY_METHODS:
attr = FlushDecorator(self._datamanager, attr)
if name in self.PROCESS_SPEC_METHODS:
@@ -254,7 +293,7 @@
if obj._p_changed is None:
self.setstate(obj)
# Now we remove the object from Mongo.
- coll = self._get_collection_from_object(obj)
+ coll = self.get_collection_from_object(obj)
coll.remove({'_id': obj._p_oid.id})
self._removed_objects.append(obj)
# Just in case the object was modified before removal, let's remove it
@@ -291,16 +330,16 @@
# Aborting the transaction requires three steps:
# 1. Remove any inserted objects.
for obj in self._inserted_objects:
- coll = self._get_collection_from_object(obj)
+ coll = self.get_collection_from_object(obj)
coll.remove({'_id': obj._p_oid.id})
# 2. Re-insert any removed objects.
for obj in self._removed_objects:
- coll = self._get_collection_from_object(obj)
+ coll = self.get_collection_from_object(obj)
coll.insert(self._original_states[obj._p_oid])
del self._original_states[obj._p_oid]
# 3. Reset any changed states.
for db_ref, state in self._original_states.items():
- coll = self._get_collection(db_ref.database, db_ref.collection)
+ coll = self.get_collection(db_ref.database, db_ref.collection)
coll.update({'_id': db_ref.id}, state, True)
self.reset()
Modified: mongopersist/trunk/src/mongopersist/serialize.py
===================================================================
--- mongopersist/trunk/src/mongopersist/serialize.py 2012-03-28 14:46:09 UTC (rev 124771)
+++ mongopersist/trunk/src/mongopersist/serialize.py 2012-03-28 14:51:47 UTC (rev 124772)
@@ -73,6 +73,7 @@
self._jar = jar
def get_collection_name(self, obj):
+ __traceback_info__ = obj
db_name = getattr(obj, '_p_mongo_database', self._jar.default_database)
try:
coll_name = obj._p_mongo_collection
@@ -211,11 +212,13 @@
return self.get_non_persistent_state(obj, seen)
def store(self, obj, ref_only=False):
+ __traceback_info__ = (obj, ref_only)
+
db_name, coll_name = self.get_collection_name(obj)
- coll = self._jar._get_collection(db_name, coll_name)
+ coll = self._jar.get_collection(db_name, coll_name)
if ref_only:
# We only want to get OID quickly. Trying to reduce the full state
- # might cause infinite recusrion loop. (Example: 2 new objects
+ # might cause infinite recursion loop. (Example: 2 new objects
# reference each other.)
doc = {}
# Make sure that the object gets saved fully later.
@@ -255,6 +258,7 @@
return resolve(path)
def resolve(self, dbref):
+ __traceback_info__ = dbref
try:
return OID_CLASS_LRU[dbref.id]
except KeyError:
@@ -282,7 +286,7 @@
# Multiple object types are stored in the collection. We have to
# look at the object to find out the type.
obj_doc = self._jar\
- ._get_collection(dbref.database, dbref.collection).find_one(
+ .get_collection(dbref.database, dbref.collection).find_one(
dbref.id, fields=('_py_persistent_type',))
if '_py_persistent_type' in obj_doc:
klass = self.simple_resolve(obj_doc['_py_persistent_type'])
@@ -374,9 +378,10 @@
return state
def set_ghost_state(self, obj, doc=None):
+ __traceback_info__ = (obj, doc)
# Look up the object state by coll_name and oid.
if doc is None:
- coll = self._jar._get_collection(
+ coll = self._jar.get_collection(
obj._p_oid.database, obj._p_oid.collection)
doc = coll.find_one({'_id': obj._p_oid.id})
# Remove unwanted attributes.
More information about the checkins
mailing list