[Zodb-checkins] CVS: ZODB3/ZEO - DebugServer.py:1.1 runsvr.py:1.30
Jeremy Hylton
jeremy@zope.com
Wed, 15 Jan 2003 16:26:57 -0500
Update of /cvs-repository/ZODB3/ZEO
In directory cvs.zope.org:/tmp/cvs-serv21452/ZEO
Modified Files:
runsvr.py
Added Files:
DebugServer.py
Log Message:
Add minimal progress on debugger/recorder for ZEO.
Handing off to Barry.
=== Added File ZODB3/ZEO/DebugServer.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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 debugging version of the server that records network activity."""
from __future__ import nested_scopes
import struct
import time
from ZEO.StorageServer import StorageServer, ZEOStorage, log
from ZEO.zrpc.server import ManagedServerConnection
# a bunch of codes
NEW_CONN = 1
CLOSE_CONN = 2
DATA = 3
ERROR = 4
class DebugManagedServerConnection(ManagedServerConnection):
def __init__(self, sock, addr, obj, mgr):
# mgr is the DebugServer instance
self.mgr = mgr
self.__super_init(sock, addr, obj)
record_id = mgr._record_connection(addr)
self._record = lambda code, data: mgr._record(record_id, code, data)
self.obj.notifyConnected(self)
def close(self):
self._record(CLOSE_CONN, "")
ManagedServerConnection.close(self)
# override the lowest-level of asyncore's connection
def recv(self, buffer_size):
try:
data = self.socket.recv(buffer_size)
if not data:
# a closed connection is indicated by signaling
# a read condition, and having recv() return 0.
self.handle_close()
return ''
else:
self._record(DATA, data)
return data
except socket.error, why:
# winsock sometimes throws ENOTCONN
self._record(ERROR, why)
if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:
self.handle_close()
return ''
else:
raise socket.error, why
class DebugServer(StorageServer):
ZEOStorageClass = DebugZEOStorage
ManagedServerConnectionClass = DebugManagerConnection
def __init__(self, *args, **kwargs):
StorageServer.__init__(*args, **kwargs)
self._setup_record(kwargs["record"])
self._conn_counter = 1
def _setup_record(self, path):
try:
self._recordfile = open(path, "ab")
except IOError, msg:
self._recordfile = None
log("failed to open recordfile %s: %s" % (path, msg))
def _record_connection(self, addr):
cid = self._conn_counter
self._conn_counter += 1
self._record(cid, NEW_CONN, str(addr))
return cid
def _record(self, conn, code, data):
s = struct.pack(">iii", code, time.time(), len(data)) + data
self._recordfile.write(s)
=== ZODB3/ZEO/runsvr.py 1.29 => 1.30 ===
--- ZODB3/ZEO/runsvr.py:1.29 Fri Jan 10 13:38:02 2003
+++ ZODB3/ZEO/runsvr.py Wed Jan 15 16:26:53 2003
@@ -23,6 +23,7 @@
-f/--filename FILENAME -- filename for FileStorage
-h/--help -- print this usage message and exit
-m/--monitor ADDRESS -- address of monitor server
+-r/--record -- path of file to record low-level network activity
Unless -C is specified, -a and -f are required.
"""
@@ -176,18 +177,20 @@
transaction_timeout = None
invalidation_queue_size = None
monitor_address = None
+ record = None
family = None # set by -a; AF_UNIX or AF_INET
address = None # set by -a; string or (host, port)
storages = None # set by -f
- _short_options = "a:C:f:hm:"
+ _short_options = "a:C:f:hm:r:"
_long_options = [
"address=",
"configuration=",
"filename=",
"help",
"monitor=",
+ "record=",
]
def handle_option(self, opt, arg):
@@ -225,6 +228,8 @@
key = str(1 + len(self.storages))
conf = FSConfig(key, arg)
self.storages[key] = FileStorage(conf)
+ elif opt in ("-r", "--record"):
+ self.record = arg
else:
# Pass it to the base class, for --help/-h
Options.handle_option(self, opt, arg)