Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/sentry_sdk/integrations/redis.py: 27%

61 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from __future__ import absolute_import 

2 

3from sentry_sdk import Hub 

4from sentry_sdk.utils import capture_internal_exceptions, logger 

5from sentry_sdk.integrations import Integration, DidNotEnable 

6 

7from sentry_sdk._types import MYPY 

8 

9if MYPY: 9 ↛ 10line 9 didn't jump to line 10, because the condition on line 9 was never true

10 from typing import Any 

11 

12_SINGLE_KEY_COMMANDS = frozenset( 

13 ["decr", "decrby", "get", "incr", "incrby", "pttl", "set", "setex", "setnx", "ttl"] 

14) 

15_MULTI_KEY_COMMANDS = frozenset(["del", "touch", "unlink"]) 

16 

17 

18def _patch_rediscluster(): 

19 # type: () -> None 

20 try: 

21 import rediscluster # type: ignore 

22 except ImportError: 

23 return 

24 

25 patch_redis_client(rediscluster.RedisCluster) 

26 

27 # up to v1.3.6, __version__ attribute is a tuple 

28 # from v2.0.0, __version__ is a string and VERSION a tuple 

29 version = getattr(rediscluster, "VERSION", rediscluster.__version__) 

30 

31 # StrictRedisCluster was introduced in v0.2.0 and removed in v2.0.0 

32 # https://github.com/Grokzen/redis-py-cluster/blob/master/docs/release-notes.rst 

33 if (0, 2, 0) < version < (2, 0, 0): 

34 patch_redis_client(rediscluster.StrictRedisCluster) 

35 

36 

37class RedisIntegration(Integration): 

38 identifier = "redis" 

39 

40 @staticmethod 

41 def setup_once(): 

42 # type: () -> None 

43 try: 

44 import redis 

45 except ImportError: 

46 raise DidNotEnable("Redis client not installed") 

47 

48 patch_redis_client(redis.StrictRedis) 

49 

50 try: 

51 import rb.clients # type: ignore 

52 except ImportError: 

53 pass 

54 else: 

55 patch_redis_client(rb.clients.FanoutClient) 

56 patch_redis_client(rb.clients.MappingClient) 

57 patch_redis_client(rb.clients.RoutingClient) 

58 

59 try: 

60 _patch_rediscluster() 

61 except Exception: 

62 logger.exception("Error occurred while patching `rediscluster` library") 

63 

64 

65def patch_redis_client(cls): 

66 # type: (Any) -> None 

67 """ 

68 This function can be used to instrument custom redis client classes or 

69 subclasses. 

70 """ 

71 

72 old_execute_command = cls.execute_command 

73 

74 def sentry_patched_execute_command(self, name, *args, **kwargs): 

75 # type: (Any, str, *Any, **Any) -> Any 

76 hub = Hub.current 

77 

78 if hub.get_integration(RedisIntegration) is None: 

79 return old_execute_command(self, name, *args, **kwargs) 

80 

81 description = name 

82 

83 with capture_internal_exceptions(): 

84 description_parts = [name] 

85 for i, arg in enumerate(args): 

86 if i > 10: 

87 break 

88 

89 description_parts.append(repr(arg)) 

90 

91 description = " ".join(description_parts) 

92 

93 with hub.start_span(op="redis", description=description) as span: 

94 if name: 

95 span.set_tag("redis.command", name) 

96 

97 if name and args: 

98 name_low = name.lower() 

99 if (name_low in _SINGLE_KEY_COMMANDS) or ( 

100 name_low in _MULTI_KEY_COMMANDS and len(args) == 1 

101 ): 

102 span.set_tag("redis.key", args[0]) 

103 

104 return old_execute_command(self, name, *args, **kwargs) 

105 

106 cls.execute_command = sentry_patched_execute_command