Commit b0e9a9c7 authored by Jim Fulton's avatar Jim Fulton

ZEO clients now support a client_label constructor argument and

  client-label configuration-file option to specify a label for a
  client in server logs. This makes it easier to identify specific
  clients corresponding to server log entries, especially when there
  are multiple clients originating from the same machine.
parent 949014af
...@@ -21,6 +21,12 @@ New Features ...@@ -21,6 +21,12 @@ New Features
information the number of clients, lock requests and general information the number of clients, lock requests and general
statistics. statistics.
- ZEO clients now support a client_label constructor argument and
client-label configuration-file option to specify a label for a
client in server logs. This makes it easier to identify specific
clients corresponding to server log entries, especially when there
are multiple clients originating from the same machine.
- The mkzeoinst script has been moved to a separate project: - The mkzeoinst script has been moved to a separate project:
http://pypi.python.org/pypi/zope.mkzeoinstance http://pypi.python.org/pypi/zope.mkzeoinstance
......
...@@ -123,6 +123,7 @@ class ClientStorage(object): ...@@ -123,6 +123,7 @@ class ClientStorage(object):
username='', password='', realm=None, username='', password='', realm=None,
blob_dir=None, shared_blob_dir=False, blob_dir=None, shared_blob_dir=False,
blob_cache_size=None, blob_cache_size_check=10, blob_cache_size=None, blob_cache_size_check=10,
client_label=None,
): ):
"""ClientStorage constructor. """ClientStorage constructor.
...@@ -234,6 +235,9 @@ class ClientStorage(object): ...@@ -234,6 +235,9 @@ class ClientStorage(object):
loaded into the cache. Defaults to 10% of the blob cache loaded into the cache. Defaults to 10% of the blob cache
size. This option is ignored if shared_blob_dir is true. size. This option is ignored if shared_blob_dir is true.
client_label
A label to include in server log messages for the client.
Note that the authentication protocol is defined by the server Note that the authentication protocol is defined by the server
and is detected by the ClientStorage upon connecting (see and is detected by the ClientStorage upon connecting (see
testConnection() and doAuth() for details). testConnection() and doAuth() for details).
...@@ -317,6 +321,8 @@ class ClientStorage(object): ...@@ -317,6 +321,8 @@ class ClientStorage(object):
# _server_addr is used by sortKey() # _server_addr is used by sortKey()
self._server_addr = None self._server_addr = None
self._client_label = client_label
self._pickler = self._tfile = None self._pickler = self._tfile = None
self._info = {'length': 0, 'size': 0, 'name': 'ZEO Client', self._info = {'length': 0, 'size': 0, 'name': 'ZEO Client',
...@@ -622,6 +628,10 @@ class ClientStorage(object): ...@@ -622,6 +628,10 @@ class ClientStorage(object):
self.__name__, self._server_addr) self.__name__, self._server_addr)
stub = self.StorageServerStubClass(conn) stub = self.StorageServerStubClass(conn)
if self._client_label and conn.peer_protocol_version >= "Z310":
stub.set_client_label(self._client_label)
self._oids = [] self._oids = []
self.verify_cache(stub) self.verify_cache(stub)
......
...@@ -299,6 +299,9 @@ class StorageServer: ...@@ -299,6 +299,9 @@ class StorageServer:
def server_status(self): def server_status(self):
return self.rpc.call("server_status") return self.rpc.call("server_status")
def set_client_label(self, label):
return self.rpc.callAsync('set_client_label', label)
class StorageServer308(StorageServer): class StorageServer308(StorageServer):
def __init__(self, rpc): def __init__(self, rpc):
......
...@@ -759,6 +759,9 @@ class ZEOStorage: ...@@ -759,6 +759,9 @@ class ZEOStorage:
def server_status(self): def server_status(self):
return self.server.server_status(self) return self.server.server_status(self)
def set_client_label(self, label):
self.log_label = str(label)+' '+_addr_label(self.connection.addr)
class StorageServerDB: class StorageServerDB:
def __init__(self, server, storage_id): def __init__(self, server, storage_id):
......
...@@ -1295,6 +1295,42 @@ def test_server_status(): ...@@ -1295,6 +1295,42 @@ def test_server_status():
>>> db.close() >>> db.close()
""" """
def client_labels():
"""
When looking at server logs, for servers with lots of clients coming
from the same machine, it can be very difficult to correlate server
log entries with actual clients. It's possible, sort of, but tedious.
You can make this easier by passing a label to the ClientStorage
constructor.
>>> addr, _ = start_server()
>>> db = ZEO.DB(addr, client_label='test-label-1')
>>> db.close()
>>> for line in open('server-%s.log' % addr[1]):
... if 'test-label-1' in line:
... print line.split()[1:4]
['INFO', 'ZEO.StorageServer', '(test-label-1']
You can specify the client label via a configuration file as well:
>>> import ZODB.config
>>> db = ZODB.config.databaseFromString('''
... <zodb>
... <zeoclient>
... server :%s
... client-label test-label-2
... </zeoclient>
... </zodb>
... ''' % addr[1])
>>> db.close()
>>> for line in open('server-%s.log' % addr[1]):
... if 'test-label-2' in line:
... print line.split()[1:4]
['INFO', 'ZEO.StorageServer', '(test-label-2']
"""
if sys.version_info >= (2, 6): if sys.version_info >= (2, 6):
import multiprocessing import multiprocessing
......
...@@ -216,6 +216,11 @@ ...@@ -216,6 +216,11 @@
instead of an expensive verification. instead of an expensive verification.
</description> </description>
</key> </key>
<key name="client-label" required="no">
<description>
A label for the client in server logs
</description>
</key>
</sectiontype> </sectiontype>
<sectiontype name="demostorage" datatype=".DemoStorage" <sectiontype name="demostorage" datatype=".DemoStorage"
......
...@@ -188,6 +188,8 @@ class ZEOClient(BaseConfig): ...@@ -188,6 +188,8 @@ class ZEOClient(BaseConfig):
options['blob_cache_size'] = self.config.blob_cache_size options['blob_cache_size'] = self.config.blob_cache_size
if self.config.blob_cache_size_check is not None: if self.config.blob_cache_size_check is not None:
options['blob_cache_size_check'] = self.config.blob_cache_size_check options['blob_cache_size_check'] = self.config.blob_cache_size_check
if self.config.client_label is not None:
options['client_label'] = self.config.client_label
return ClientStorage( return ClientStorage(
L, L,
......
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