Commit 6d2da919 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Catch exceptions at higher to log informations pre-mortem.

- Unify log methods among classes.
- Define log() on event manager

git-svn-id: https://svn.erp5.org/repos/neo/trunk@2123 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 34f64582
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from time import time from time import time
from neo import logging
from neo.epoll import Epoll from neo.epoll import Epoll
from neo.profiling import profiler_decorator from neo.profiling import profiler_decorator
...@@ -183,5 +183,15 @@ class EpollEventManager(object): ...@@ -183,5 +183,15 @@ class EpollEventManager(object):
self.writer_set.remove(fd) self.writer_set.remove(fd)
self.epoll.modify(fd, fd in self.reader_set, 0) self.epoll.modify(fd, fd in self.reader_set, 0)
def log(self):
logging.info('Event Manager:')
logging.info(' Readers: %r', [x for x in self.reader_set])
logging.info(' Writers: %r', [x for x in self.writer_set])
logging.info(' Connections:')
pending_set = set(self._pending_processing)
for fd, conn in self.connection_dict.items():
logging.info(' %r: %r (pending=%r)', fd, conn, conn in pending_set)
# Default to EpollEventManager. # Default to EpollEventManager.
EventManager = EpollEventManager EventManager = EpollEventManager
...@@ -96,6 +96,17 @@ class Application(object): ...@@ -96,6 +96,17 @@ class Application(object):
registerLiveDebugger() registerLiveDebugger()
def run(self): def run(self):
try:
self._run()
except:
logging.info('\nPre-mortem informations:')
self.em.log()
self.nm.log()
self.pt.log()
self.tm.log()
raise
def _run(self):
"""Make sure that the status is sane and start a loop.""" """Make sure that the status is sane and start a loop."""
bootstrap = True bootstrap = True
......
...@@ -241,3 +241,11 @@ class TransactionManager(object): ...@@ -241,3 +241,11 @@ class TransactionManager(object):
# discard node entry # discard node entry
del self._node_dict[node] del self._node_dict[node]
def log(self):
logging.info('Transactions:')
for node, tid_dict in self._node_dict.items():
if not len(tid_dict):
continue
logging.info(' %r: %r', dump(node.getUUID()), [dump(x) for x in
tid_dict.keys()])
...@@ -475,12 +475,12 @@ class NodeManager(object): ...@@ -475,12 +475,12 @@ class NodeManager(object):
self.log() self.log()
def log(self): def log(self):
logging.debug('Node manager : %d nodes' % len(self._node_set)) logging.info('Node manager : %d nodes' % len(self._node_set))
for node in sorted(list(self._node_set)): for node in sorted(list(self._node_set)):
uuid = dump(node.getUUID()) or '-' * 32 uuid = dump(node.getUUID()) or '-' * 32
address = node.getAddress() or '' address = node.getAddress() or ''
if address: if address:
address = '%s:%d' % address address = '%s:%d' % address
logging.debug(' * %32s | %8s | %22s | %s' % ( logging.info(' * %32s | %8s | %22s | %s' % (
uuid, node.getType(), address, node.getState())) uuid, node.getType(), address, node.getState()))
...@@ -145,6 +145,18 @@ class Application(object): ...@@ -145,6 +145,18 @@ class Application(object):
self.pt.update(ptid, new_cell_list, self.nm) self.pt.update(ptid, new_cell_list, self.nm)
def run(self): def run(self):
try:
self._run()
except:
logging.info('\nPre-mortem informations:')
self.em.log()
self.nm.log()
self.pt.log()
self.tm.log()
self.logQueuedEvents()
raise
def _run(self):
"""Make sure that the status is sane and start a loop.""" """Make sure that the status is sane and start a loop."""
if len(self.name) == 0: if len(self.name) == 0:
raise RuntimeError, 'cluster name must be non-empty' raise RuntimeError, 'cluster name must be non-empty'
...@@ -301,6 +313,15 @@ class Application(object): ...@@ -301,6 +313,15 @@ class Application(object):
conn.setPeerId(msg_id) conn.setPeerId(msg_id)
some_callable(conn, *args, **kwargs) some_callable(conn, *args, **kwargs)
def logQueuedEvents(self):
if self.event_queue is None:
return
logging.info("Pending events:")
for event, _msg_id, _conn, args, _kwargs in self.event_queue:
oid, serial, _compression, _checksum, data, tid, time = args
logging.info(' %r: %r:%r by %r -> %r (%r)', event.__name__, dump(oid),
dump(serial), dump(tid), data, time)
def shutdown(self, erase=False): def shutdown(self, erase=False):
"""Close all connections and exit""" """Close all connections and exit"""
for c in self.em.getConnectionList(): for c in self.em.getConnectionList():
......
...@@ -280,3 +280,13 @@ class TransactionManager(object): ...@@ -280,3 +280,13 @@ class TransactionManager(object):
def loadLocked(self, oid): def loadLocked(self, oid):
return oid in self._load_lock_dict return oid in self._load_lock_dict
def log(self):
logging.info("Transactions: %r",
[dump(x) for x in self._transaction_dict.keys()])
logging.info(' Read locks:')
for oid, tid in self._load_lock_dict.items():
logging.info(' %r by %r', dump(oid), dump(tid))
logging.info(' Write locks:')
for oid, tid in self._store_lock_dict.items():
logging.info(' %r by %r', dump(oid), dump(tid))
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