summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhuangwei-ds5 <huangwei-ds5@gome.com.cn>2019-08-09 15:54:57 +0800
committerAndy McCurdy <andy@andymccurdy.com>2019-08-19 12:30:39 -0700
commitd811ae71dbdbeeb4fc0ee73a96b7fbdb1aec8522 (patch)
tree928cee652b10c7ae6d0ba974ef47423f60a9f94f
parentf0516c9f7589557883a5eb23a44531066e275950 (diff)
downloadredis-py-d811ae71dbdbeeb4fc0ee73a96b7fbdb1aec8522.tar.gz
version 3.3.8, fix MONITOR output to account for all types of clients3.3.8
The client section of MONITOR output varies for TCP connections, unix socket connections and commands executed from Lua scripts. Account for each of these cases by including an additional key `client_type` in the MONITOR output. `client_type` will be one of ('tcp', 'unix', 'lua'). `client_address` and `client_port` vary based on the `client_type`. Fixes #1201
-rw-r--r--CHANGES3
-rw-r--r--redis/__init__.py2
-rwxr-xr-xredis/client.py18
-rw-r--r--tests/test_monitor.py11
4 files changed, 31 insertions, 3 deletions
diff --git a/CHANGES b/CHANGES
index eda80b6..37b2830 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+* 3.3.8
+ * Fixed MONITOR parsing to properly parse IPv6 client addresses, unix
+ socket connections and commands issued from Lua. Thanks @kukey. #1201
* 3.3.7
* Fixed a regression introduced in 3.3.0 where socket.error exceptions
(or subclasses) could potentially be raised instead of
diff --git a/redis/__init__.py b/redis/__init__.py
index bfd1839..9395147 100644
--- a/redis/__init__.py
+++ b/redis/__init__.py
@@ -29,7 +29,7 @@ def int_or_str(value):
return value
-__version__ = '3.3.7'
+__version__ = '3.3.8'
VERSION = tuple(map(int_or_str, __version__.split('.')))
__all__ = [
diff --git a/redis/client.py b/redis/client.py
index c13ccff..df1ebfd 100755
--- a/redis/client.py
+++ b/redis/client.py
@@ -3002,7 +3002,7 @@ class Monitor(object):
next_command() method returns one command from monitor
listen() method yields commands from monitor.
"""
- monitor_re = re.compile(r'\[(\d+) (.+):(\d+)\] (.*)')
+ monitor_re = re.compile(r'\[(\d+) (.*)\] (.*)')
command_re = re.compile(r'"(.*?)(?<!\\)"')
def __init__(self, connection_pool):
@@ -3028,14 +3028,28 @@ class Monitor(object):
response = self.connection.encoder.decode(response, force=True)
command_time, command_data = response.split(' ', 1)
m = self.monitor_re.match(command_data)
- db_id, client_address, client_port, command = m.groups()
+ db_id, client_info, command = m.groups()
command = ' '.join(self.command_re.findall(command))
command = command.replace('\\"', '"').replace('\\\\', '\\')
+
+ if client_info == 'lua':
+ client_address = 'lua'
+ client_port = ''
+ client_type = 'lua'
+ elif client_info.startswith('unix'):
+ client_address = 'unix'
+ client_port = client_info[5:]
+ client_type = 'unix'
+ else:
+ # use rsplit as ipv6 addresses contain colons
+ client_address, client_port = client_info.rsplit(':', 1)
+ client_type = 'tcp'
return {
'time': float(command_time),
'db': int(db_id),
'client_address': client_address,
'client_port': client_port,
+ 'client_type': client_type,
'command': command
}
diff --git a/tests/test_monitor.py b/tests/test_monitor.py
index 9e9ee83..09ec21b 100644
--- a/tests/test_monitor.py
+++ b/tests/test_monitor.py
@@ -29,6 +29,7 @@ class TestPipeline(object):
response = wait_for_command(r, m, 'PING')
assert isinstance(response['time'], float)
assert response['db'] == 9
+ assert response['client_type'] in ('tcp', 'unix')
assert isinstance(response['client_address'], unicode)
assert isinstance(response['client_port'], unicode)
assert response['command'] == 'PING'
@@ -45,3 +46,13 @@ class TestPipeline(object):
r.get(byte_string)
response = wait_for_command(r, m, 'GET foo\\x92')
assert response['command'] == 'GET foo\\x92'
+
+ def test_lua_script(self, r):
+ with r.monitor() as m:
+ script = 'return redis.call("GET", "foo")'
+ assert r.eval(script, 0) is None
+ response = wait_for_command(r, m, 'GET foo')
+ assert response['command'] == 'GET foo'
+ assert response['client_type'] == 'lua'
+ assert response['client_address'] == 'lua'
+ assert response['client_port'] == ''