Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If index 3 is not a list, assume Redis Enterprise and return index 4 as slowlog command #1352

Merged
merged 2 commits into from
May 18, 2021

Conversation

ian28223
Copy link
Contributor

@ian28223 ian28223 commented Jun 15, 2020

Pull Request check-list

Please make sure to review and check all of these items:

  • Does $ tox pass with this change (including linting)?
  • Does travis tests pass with this change (enable it first in your forked repo and wait for the travis build to finish)?
  • Is the new or changed code fully tested?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?

NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.

Description of change

Some redis instances, Redislabs for example, return slowlog entries with the commands at item[4] instead of item[3].

command is always a list; return item[4] if item[3] is not a list.

Example:

 1) 1) (integer) 4764
    2) (integer) 1592198570
    3) (integer) 3
    4)
    5) 1) "LPUSH"
       2) "testkey2"
       3) "0.7346415842722306"
 2) 1) (integer) 4763
    2) (integer) 1592198570
    3) (integer) 3
    4)
    5) 1) "LPUSH"
       2) "testkey2"
       3) "0.6277650251277609"
 3) 1) (integer) 4762
    2) (integer) 1592198570
    3) (integer) 4
    4)
    5) 1) "LPUSH"
       2) "testkey2"
       3) "0.7646428397907798"
 4) 1) (integer) 4761
    2) (integer) 1592198570
    3) (integer) 3
    4)
    5) 1) "LPUSH"
       2) "testkey2"
       3) "0.7501418278370815"

@andymccurdy
Copy link
Contributor

@ian28223 The command is never the last item in Redis server 4.0 or later. I'm not sure what extra entires (if any) Redis Labs returns, but this change won't work for the open source version.

@RoeyPrat
Copy link

Hi @ian28223,
Thank you for bringing this up.

It seems Redis Enterprise injects another entry at index [3], which has the complexity info (i.e. the value of N in case the command has an O(N) complexity).
Whatever the schema of this response is, we need it to be standardized and documented in order to introduce it to redis-py, otherwise it might change it a way we can't predict.
I'll reach out to the relevant developers in Redislabs, to get the Redis Enterprise slowlog get schema standardized and documented, but this is outside the scope of redis-py.

For now, I'm creating a new issue to support the Client IP address and port and Client name added in v4 of Redis OSS
#1374.

@RoeyPrat RoeyPrat closed this Jul 28, 2020
@RoeyPrat RoeyPrat reopened this Jul 28, 2020
@oranagra
Copy link
Member

I think the right way to work around this incompatibility of RE (until it gets fixed), is to look at the entry at [3] and see if it's an array or a string.
The command arguments will always be a multi-bulk, so if we see that [3] is an array, we can assume this is the OSS redis format, and if we see [3] is a string, we can assume that's RE complexity field, and shift all the fields forward by one, i.e. the command is at [4], and the client details at [5] and [6] (instead of [4], [5] like in OSS redis)

@RoeyPrat RoeyPrat linked an issue Aug 2, 2020 that may be closed by this pull request
sileht added a commit to sileht/mergify-community that referenced this pull request Feb 17, 2021
It's not clear why it doesn't work, maybe redis/redis-py#1352

So disable it

(pkg/collector/runner/runner.go:292 in work) | Error running check redisdb: [{"message": "sequence item 0: expected a bytes-like object, int found", "traceback": "Traceback (most recent call last):
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/base/checks/base.py\", line 876, in run
    self.check(instance)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/redisdb/redisdb.py\", line 501, in check
    self._check_slowlog()
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/redisdb/redisdb.py\", line 452, in _check_slowlog
    slowlogs = conn.slowlog_get(max_slow_entries)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 1466, in slowlog_get
    return self.execute_command(*args, decode_responses=decode_responses)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 901, in execute_command
    return self.parse_response(conn, command_name, **options)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 921, in parse_response
    return self.response_callbacks[command_name](response, **options)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 415, in parse_slowlog_get
    return [{
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 419, in <listcomp>
    'command': space.join(item[3])
TypeError: sequence item 0: expected a bytes-like object, int found
"}]
mergify bot pushed a commit to Mergifyio/mergify that referenced this pull request Feb 17, 2021
It's not clear why it doesn't work, maybe redis/redis-py#1352

So disable it

(pkg/collector/runner/runner.go:292 in work) | Error running check redisdb: [{"message": "sequence item 0: expected a bytes-like object, int found", "traceback": "Traceback (most recent call last):
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/base/checks/base.py\", line 876, in run
    self.check(instance)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/redisdb/redisdb.py\", line 501, in check
    self._check_slowlog()
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/datadog_checks/redisdb/redisdb.py\", line 452, in _check_slowlog
    slowlogs = conn.slowlog_get(max_slow_entries)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 1466, in slowlog_get
    return self.execute_command(*args, decode_responses=decode_responses)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 901, in execute_command
    return self.parse_response(conn, command_name, **options)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 921, in parse_response
    return self.response_callbacks[command_name](response, **options)
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 415, in parse_slowlog_get
    return [{
  File \"/app/.apt/opt/datadog-agent/embedded/lib/python3.8/site-packages/redis/client.py\", line 419, in <listcomp>
    'command': space.join(item[3])
TypeError: sequence item 0: expected a bytes-like object, int found
"}]
@hithwen
Copy link

hithwen commented Apr 14, 2021

@oranagra

I think the right way to work around this incompatibility of RE (until it gets fixed), is to look at the entry at [3] and see if it's an array or a string.

I think in case of Redis Enterprise the field is an int as @ RoeyPrat said

It seems Redis Enterprise injects another entry at index [3], which has the complexity info (i.e. the value of N in case the command has an O(N) complexity).

In either case checking if it's a string might still be the solution

@oranagra
Copy link
Member

by [3] i meant 0 based. the output posted above is from redis-cli which is 1 based.
in that example the field is empty, but had this response been from standard redis, it would have been the arguments array.

@ian28223 ian28223 changed the title Treat last item of Slowlog entries as commands If index 3 is not a list, assume Redis Enterprise and return index 4 as slowlog command Apr 15, 2021
@ian28223
Copy link
Contributor Author

I've applied the suggestion which is to return index 4 as the command if index 3 is not a list.

@hithwen
Copy link

hithwen commented Apr 15, 2021

Seems the build has failed due to a pull limit. Is there a way to rerun it?

@andymccurdy
Copy link
Contributor

@ian28223 Nit-picky, but can you fix the flake8 error please? Looks like the line is too long now.

@andymccurdy
Copy link
Contributor

The error that Travis is reporting doesn't seem related to this PR. It looks like a test case that mixes mocks and threading is failing on PyPy3 suddenly. Not sure why off the top of my head, but I'll look into it this afternoon.

@ian28223
Copy link
Contributor Author

ian28223 commented May 7, 2021

The error that Travis is reporting doesn't seem related to this PR. It looks like a test case that mixes mocks and threading is failing on PyPy3 suddenly. Not sure why off the top of my head, but I'll look into it this afternoon.

Any updates as to why the unrelated test is failing?

@codecov-commenter
Copy link

codecov-commenter commented May 17, 2021

Codecov Report

Merging #1352 (ab7b09b) into master (15dafb1) will increase coverage by 0.68%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1352      +/-   ##
==========================================
+ Coverage   85.90%   86.58%   +0.68%     
==========================================
  Files           6        7       +1     
  Lines        2894     2914      +20     
==========================================
+ Hits         2486     2523      +37     
+ Misses        408      391      -17     
Impacted Files Coverage Δ
redis/client.py 87.02% <100.00%> (+1.09%) ⬆️
redis/lock.py 100.00% <0.00%> (ø)
redis/__init__.py 83.33% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7e466f7...ab7b09b. Read the comment docs.

@hithwen
Copy link

hithwen commented May 17, 2021

Seems builds are green now. Can we get this in?

@andymccurdy
Copy link
Contributor

@ian28223 Can you rebase your PR off of the latest master? Thanks.

command is always a list. If index 3 is not a list, assume Redis Enterprise and return index 4 instead
@hithwen
Copy link

hithwen commented May 18, 2021

Seems an unrelated test is failing after rebasing?

@andymccurdy andymccurdy merged commit bc58542 into redis:master May 18, 2021
@andymccurdy
Copy link
Contributor

I haven't tracked down the PyPy error yet, but it's definitely not related to this change. Thanks for putting this together.

@ian28223
Copy link
Contributor Author

I haven't tracked down the PyPy error yet, but it's definitely not related to this change. Thanks for putting this together.

Much appreciated for the merge! Any chance we can get a new release including it? A 3.5.4 perchance?

@hithwen
Copy link

hithwen commented May 31, 2021

When is next release planed? It's been a year since the latest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

slowlog get - does not include fields added in Redis version 4
6 participants