diff options
author | Andy McCurdy <andy@andymccurdy.com> | 2011-01-10 11:57:59 -0800 |
---|---|---|
committer | Andy McCurdy <andy@andymccurdy.com> | 2011-01-10 11:57:59 -0800 |
commit | f26de8ec0a2ae3dc97fc7be6ce65165a1fa17ca9 (patch) | |
tree | 80a2ac4aa2a2835e08f65676976b3103ce442a15 /redis | |
parent | 7112f5bc1115c099a4f7872b9088ce71b08f37ff (diff) | |
parent | dfde2fc04868849f2a1db62bd29821810bd9168d (diff) | |
download | redis-py-f26de8ec0a2ae3dc97fc7be6ce65165a1fa17ca9.tar.gz |
Merge branch 'master' of https://github.com/wcmaier/redis-py into logging
Diffstat (limited to 'redis')
-rw-r--r-- | redis/client.py | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/redis/client.py b/redis/client.py index 9ba3547..b80707e 100644 --- a/redis/client.py +++ b/redis/client.py @@ -1,5 +1,6 @@ import datetime import errno +import logging import socket import threading import time @@ -8,6 +9,16 @@ from itertools import chain, imap from redis.exceptions import ConnectionError, ResponseError, InvalidResponse, WatchError from redis.exceptions import RedisError, AuthenticationError +try: + NullHandler = logging.NullHandler +except AttributeError: + class NullHandler(logging.Handler): + def emit(self, record): pass + +log = logging.getLogger("redis") +# Add a no-op handler to avoid error messages if the importing module doesn't +# configure logging. +log.addHandler(NullHandler()) class ConnectionPool(threading.local): "Manages a list of connections on the local thread" @@ -47,6 +58,8 @@ class Connection(object): "Connects to the Redis server if not already connected" if self._sock: return + if log_enabled(log): + log.debug("connecting to %s:%d/%d", self.host, self.port, self.db) try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(self.socket_timeout) @@ -70,6 +83,8 @@ class Connection(object): "Disconnects from the Redis server" if self._sock is None: return + if log_enabled(log): + log.debug("disconnecting from %s:%d/%d", self.host, self.port, self.db) try: self._sock.close() except socket.error: @@ -148,6 +163,17 @@ def dict_merge(*dicts): [merged.update(d) for d in dicts] return merged +def log_enabled(log, level=logging.DEBUG): + return log.isEnabledFor(log, level) + +def repr_command(args): + "Represents a command as a string." + command = [args[0]] + if len(args) > 1: + command.extend(repr(x) for x in args[1:]) + + return ' '.join(command) + def parse_info(response): "Parse the result of Redis's INFO command into a Python dict" info = {} @@ -317,6 +343,9 @@ class Redis(threading.local): if self.subscribed and not subscription_command: raise RedisError("Cannot issue commands other than SUBSCRIBE and " "UNSUBSCRIBE while channels are open") + if log_enabled(log): + log.debug(repr_command(command)) + command = self._encode_command(command) try: self.connection.send(command, self) if subscription_command: @@ -328,14 +357,17 @@ class Redis(threading.local): if subscription_command: return None return self.parse_response(command_name, **options) + + def _encode_command(self, args): + cmds = ['$%s\r\n%s\r\n' % (len(enc_value), enc_value) + for enc_value in imap(self.encode, args)] + return '*%s\r\n%s' % (len(cmds), ''.join(cmds)) def execute_command(self, *args, **options): "Sends the command to the redis server and returns it's response" - cmds = ['$%s\r\n%s\r\n' % (len(enc_value), enc_value) - for enc_value in imap(self.encode, args)] return self._execute_command( args[0], - '*%s\r\n%s' % (len(cmds), ''.join(cmds)), + args, **options ) @@ -1407,11 +1439,16 @@ class Pipeline(Redis): def _execute_transaction(self, commands): # wrap the commands in MULTI ... EXEC statements to indicate an # atomic operation - all_cmds = ''.join([c for _1, c, _2 in chain( - (('', 'MULTI\r\n', ''),), + all_cmds = ''.join([self._encode_command(c) for _1, c, _2 in chain( + (('', ('MULTI',), ''),), commands, - (('', 'EXEC\r\n', ''),) + (('', ('EXEC',), ''),) )]) + if log_enabled(log): + log.debug("MULTI") + for command in commands: + log.debug("TRANSACTION> "+ repr_command(command[1])) + log.debug("EXEC") self.connection.send(all_cmds, self) # parse off the response for MULTI and all commands prior to EXEC for i in range(len(commands)+1): @@ -1436,7 +1473,10 @@ class Pipeline(Redis): def _execute_pipeline(self, commands): # build up all commands into a single request to increase network perf - all_cmds = ''.join([c for _1, c, _2 in commands]) + all_cmds = ''.join([self._encode_command(c) for _1, c, _2 in commands]) + if log_enabled(log): + for command in commands: + log.debug("PIPELINE> " + repr_command(command[1])) self.connection.send(all_cmds, self) data = [] for command_name, _, options in commands: |