whatap-python 2.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. whatap/LICENSE +0 -0
  2. whatap/README.rst +49 -0
  3. whatap/__init__.py +923 -0
  4. whatap/__main__.py +4 -0
  5. whatap/agent/darwin/amd64/whatap_python +0 -0
  6. whatap/agent/darwin/arm64/whatap_python +0 -0
  7. whatap/agent/linux/amd64/whatap_python +0 -0
  8. whatap/agent/linux/arm64/whatap_python +0 -0
  9. whatap/agent/windows/whatap_python.exe +0 -0
  10. whatap/bootstrap/__init__.py +0 -0
  11. whatap/bootstrap/sitecustomize.py +19 -0
  12. whatap/build.py +4 -0
  13. whatap/conf/__init__.py +0 -0
  14. whatap/conf/configuration.py +280 -0
  15. whatap/conf/configure.py +105 -0
  16. whatap/conf/license.py +49 -0
  17. whatap/control/__init__.py +0 -0
  18. whatap/counter/__init__.py +14 -0
  19. whatap/counter/counter_manager.py +45 -0
  20. whatap/counter/tasks/__init__.py +3 -0
  21. whatap/counter/tasks/base_task.py +26 -0
  22. whatap/counter/tasks/llm_evaluator_task.py +501 -0
  23. whatap/counter/tasks/llm_log_sink_task.py +309 -0
  24. whatap/counter/tasks/llm_stat_task.py +78 -0
  25. whatap/counter/tasks/openfiledescriptor.py +67 -0
  26. whatap/io/__init__.py +1 -0
  27. whatap/io/data_inputx.py +161 -0
  28. whatap/io/data_outputx.py +262 -0
  29. whatap/llm/__init__.py +17 -0
  30. whatap/llm/definitions.py +43 -0
  31. whatap/llm/evaluators/__init__.py +136 -0
  32. whatap/llm/evaluators/base.py +114 -0
  33. whatap/llm/evaluators/builtins/__init__.py +91 -0
  34. whatap/llm/evaluators/builtins/answer_relevance.py +46 -0
  35. whatap/llm/evaluators/builtins/combined_judge.py +271 -0
  36. whatap/llm/evaluators/builtins/factuality.py +71 -0
  37. whatap/llm/evaluators/builtins/hallucination.py +97 -0
  38. whatap/llm/evaluators/builtins/llm_judge.py +516 -0
  39. whatap/llm/evaluators/builtins/pii_leak.py +214 -0
  40. whatap/llm/evaluators/builtins/prompt_injection.py +71 -0
  41. whatap/llm/evaluators/builtins/toxicity.py +53 -0
  42. whatap/llm/evaluators/builtins/url_scan.py +194 -0
  43. whatap/llm/evaluators/registry.py +192 -0
  44. whatap/llm/evaluators/sampler.py +83 -0
  45. whatap/llm/evaluators/scope.py +334 -0
  46. whatap/llm/features.py +66 -0
  47. whatap/llm/log_sink_packs/__init__.py +9 -0
  48. whatap/llm/log_sink_packs/llm_input_message.py +16 -0
  49. whatap/llm/log_sink_packs/llm_log_sink_pack.py +72 -0
  50. whatap/llm/log_sink_packs/llm_output_message.py +19 -0
  51. whatap/llm/log_sink_packs/llm_step_eval_status.py +94 -0
  52. whatap/llm/log_sink_packs/llm_step_status.py +118 -0
  53. whatap/llm/log_sink_packs/llm_system_message.py +16 -0
  54. whatap/llm/log_sink_packs/llm_tool_calls.py +44 -0
  55. whatap/llm/log_sink_packs/llm_tool_results.py +16 -0
  56. whatap/llm/log_sink_packs/llm_tx_status.py +108 -0
  57. whatap/llm/pricing.py +236 -0
  58. whatap/llm/prompt_meta.py +288 -0
  59. whatap/llm/providers/__init__.py +0 -0
  60. whatap/llm/providers/anthropic/__init__.py +37 -0
  61. whatap/llm/providers/anthropic/messages/__init__.py +0 -0
  62. whatap/llm/providers/anthropic/messages/messages.py +70 -0
  63. whatap/llm/providers/anthropic/messages/messages_context.py +76 -0
  64. whatap/llm/providers/anthropic/messages/messages_extractor.py +126 -0
  65. whatap/llm/providers/interceptor.py +182 -0
  66. whatap/llm/providers/openai/__init__.py +133 -0
  67. whatap/llm/providers/openai/chat/__init__.py +0 -0
  68. whatap/llm/providers/openai/chat/chat.py +82 -0
  69. whatap/llm/providers/openai/chat/chat_context.py +78 -0
  70. whatap/llm/providers/openai/chat/chat_extractor.py +127 -0
  71. whatap/llm/providers/openai/completions/__init__.py +0 -0
  72. whatap/llm/providers/openai/completions/completions.py +70 -0
  73. whatap/llm/providers/openai/completions/completions_context.py +31 -0
  74. whatap/llm/providers/openai/completions/completions_extractor.py +61 -0
  75. whatap/llm/providers/openai/content_parser.py +41 -0
  76. whatap/llm/providers/openai/embeddings/__init__.py +0 -0
  77. whatap/llm/providers/openai/embeddings/embeddings.py +59 -0
  78. whatap/llm/providers/openai/embeddings/embeddings_context.py +25 -0
  79. whatap/llm/providers/openai/embeddings/embeddings_extractor.py +26 -0
  80. whatap/llm/providers/openai/responses/__init__.py +0 -0
  81. whatap/llm/providers/openai/responses/responses.py +70 -0
  82. whatap/llm/providers/openai/responses/responses_context.py +88 -0
  83. whatap/llm/providers/openai/responses/responses_extractor.py +126 -0
  84. whatap/llm/providers/stream_accumulator.py +73 -0
  85. whatap/llm/stats/__init__.py +35 -0
  86. whatap/llm/stats/active_stat.py +86 -0
  87. whatap/llm/stats/answer_relevance_eval_stat.py +10 -0
  88. whatap/llm/stats/api_status_stat.py +35 -0
  89. whatap/llm/stats/base_stat.py +107 -0
  90. whatap/llm/stats/combined_judge_eval_stat.py +11 -0
  91. whatap/llm/stats/error_stat.py +59 -0
  92. whatap/llm/stats/eval_stat.py +225 -0
  93. whatap/llm/stats/factuality_eval_stat.py +10 -0
  94. whatap/llm/stats/feature_stat.py +104 -0
  95. whatap/llm/stats/finish_stat.py +105 -0
  96. whatap/llm/stats/hallucination_eval_stat.py +10 -0
  97. whatap/llm/stats/meter.py +18 -0
  98. whatap/llm/stats/perf_stat.py +117 -0
  99. whatap/llm/stats/pii_leak_eval_stat.py +12 -0
  100. whatap/llm/stats/prompt_injection_eval_stat.py +10 -0
  101. whatap/llm/stats/token_usage_stat.py +133 -0
  102. whatap/llm/stats/toxicity_eval_stat.py +10 -0
  103. whatap/llm/stats/url_scan_eval_stat.py +12 -0
  104. whatap/net/__init__.py +0 -0
  105. whatap/net/async_sender.py +107 -0
  106. whatap/net/packet_enum.py +44 -0
  107. whatap/net/packet_type_enum.py +31 -0
  108. whatap/net/param_def.py +69 -0
  109. whatap/net/stackhelper.py +87 -0
  110. whatap/net/udp_session.py +394 -0
  111. whatap/net/udp_thread.py +54 -0
  112. whatap/pack/__init__.py +0 -0
  113. whatap/pack/logSinkPack.py +77 -0
  114. whatap/pack/pack.py +34 -0
  115. whatap/pack/pack_enum.py +41 -0
  116. whatap/pack/tagCountPack.py +61 -0
  117. whatap/scripts/__init__.py +208 -0
  118. whatap/trace/__init__.py +12 -0
  119. whatap/trace/mod/__init__.py +0 -0
  120. whatap/trace/mod/amqp/__init__.py +0 -0
  121. whatap/trace/mod/amqp/kombu.py +122 -0
  122. whatap/trace/mod/amqp/pika.py +62 -0
  123. whatap/trace/mod/application/__init__.py +0 -0
  124. whatap/trace/mod/application/bottle.py +34 -0
  125. whatap/trace/mod/application/celery.py +81 -0
  126. whatap/trace/mod/application/cherrypy.py +30 -0
  127. whatap/trace/mod/application/django.py +287 -0
  128. whatap/trace/mod/application/django_asgi.py +266 -0
  129. whatap/trace/mod/application/django_py3.py +251 -0
  130. whatap/trace/mod/application/fastapi/__init__.py +31 -0
  131. whatap/trace/mod/application/fastapi/endpoint.py +73 -0
  132. whatap/trace/mod/application/fastapi/exception_log.py +63 -0
  133. whatap/trace/mod/application/fastapi/instrumentation.py +204 -0
  134. whatap/trace/mod/application/fastapi/scope.py +115 -0
  135. whatap/trace/mod/application/fastapi/transaction.py +67 -0
  136. whatap/trace/mod/application/flask.py +52 -0
  137. whatap/trace/mod/application/frappe.py +224 -0
  138. whatap/trace/mod/application/graphql.py +170 -0
  139. whatap/trace/mod/application/nameko.py +39 -0
  140. whatap/trace/mod/application/odoo.py +63 -0
  141. whatap/trace/mod/application/starlette.py +126 -0
  142. whatap/trace/mod/application/tornado.py +163 -0
  143. whatap/trace/mod/application/wsgi.py +195 -0
  144. whatap/trace/mod/database/__init__.py +0 -0
  145. whatap/trace/mod/database/cxoracle.py +49 -0
  146. whatap/trace/mod/database/mongo.py +169 -0
  147. whatap/trace/mod/database/mysql.py +80 -0
  148. whatap/trace/mod/database/neo4j.py +90 -0
  149. whatap/trace/mod/database/psycopg2.py +45 -0
  150. whatap/trace/mod/database/psycopg3.py +359 -0
  151. whatap/trace/mod/database/redis.py +122 -0
  152. whatap/trace/mod/database/sqlalchemy.py +213 -0
  153. whatap/trace/mod/database/sqlite3.py +130 -0
  154. whatap/trace/mod/database/util.py +630 -0
  155. whatap/trace/mod/email/__init__.py +0 -0
  156. whatap/trace/mod/email/smtp.py +78 -0
  157. whatap/trace/mod/httpc/__init__.py +0 -0
  158. whatap/trace/mod/httpc/django.py +31 -0
  159. whatap/trace/mod/httpc/httplib.py +70 -0
  160. whatap/trace/mod/httpc/httpx.py +62 -0
  161. whatap/trace/mod/httpc/requests.py +20 -0
  162. whatap/trace/mod/httpc/urllib3.py +27 -0
  163. whatap/trace/mod/httpc/util.py +388 -0
  164. whatap/trace/mod/logging.py +161 -0
  165. whatap/trace/mod/plugin.py +84 -0
  166. whatap/trace/mod/standalone/__init__.py +0 -0
  167. whatap/trace/mod/standalone/multiple.py +293 -0
  168. whatap/trace/mod/standalone/single.py +135 -0
  169. whatap/trace/simple_trace_context.py +18 -0
  170. whatap/trace/trace_context.py +212 -0
  171. whatap/trace/trace_context_manager.py +244 -0
  172. whatap/trace/trace_error.py +84 -0
  173. whatap/trace/trace_handler.py +89 -0
  174. whatap/trace/trace_import.py +91 -0
  175. whatap/trace/trace_module_definition.py +156 -0
  176. whatap/util/__init__.py +0 -0
  177. whatap/util/bit_util.py +49 -0
  178. whatap/util/cardinality/__init__.py +0 -0
  179. whatap/util/cardinality/hyperloglog.py +84 -0
  180. whatap/util/cardinality/murmurhash.py +20 -0
  181. whatap/util/cardinality/registerset.py +60 -0
  182. whatap/util/compare_util.py +19 -0
  183. whatap/util/date_util.py +55 -0
  184. whatap/util/debug_util.py +73 -0
  185. whatap/util/escape_literal_sql.py +233 -0
  186. whatap/util/frame_util.py +20 -0
  187. whatap/util/hash_util.py +103 -0
  188. whatap/util/hexa32.py +66 -0
  189. whatap/util/int_set.py +199 -0
  190. whatap/util/ip_util.py +63 -0
  191. whatap/util/keygen.py +11 -0
  192. whatap/util/linked_list.py +113 -0
  193. whatap/util/linked_map.py +359 -0
  194. whatap/util/metering_util.py +103 -0
  195. whatap/util/request_double_queue.py +68 -0
  196. whatap/util/request_queue.py +60 -0
  197. whatap/util/string_util.py +20 -0
  198. whatap/util/throttle_util.py +99 -0
  199. whatap/util/userid_util.py +134 -0
  200. whatap/value/__init__.py +1 -0
  201. whatap/value/blob_value.py +38 -0
  202. whatap/value/boolean_value.py +33 -0
  203. whatap/value/decimal_value.py +36 -0
  204. whatap/value/double_summary.py +86 -0
  205. whatap/value/double_value.py +33 -0
  206. whatap/value/float_array.py +42 -0
  207. whatap/value/float_value.py +34 -0
  208. whatap/value/int_array.py +42 -0
  209. whatap/value/ip4_value.py +50 -0
  210. whatap/value/list_value.py +105 -0
  211. whatap/value/long_array.py +44 -0
  212. whatap/value/long_summary.py +83 -0
  213. whatap/value/map_value.py +154 -0
  214. whatap/value/null_value.py +21 -0
  215. whatap/value/number_value.py +33 -0
  216. whatap/value/summary_value.py +39 -0
  217. whatap/value/text_array.py +58 -0
  218. whatap/value/text_hash_value.py +37 -0
  219. whatap/value/text_value.py +43 -0
  220. whatap/value/value.py +26 -0
  221. whatap/value/value_enum.py +80 -0
  222. whatap/whatap.conf +14 -0
  223. whatap_python-2.1.0.dist-info/METADATA +87 -0
  224. whatap_python-2.1.0.dist-info/RECORD +227 -0
  225. whatap_python-2.1.0.dist-info/WHEEL +5 -0
  226. whatap_python-2.1.0.dist-info/entry_points.txt +6 -0
  227. whatap_python-2.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,169 @@
1
+ import pymongo.monitoring
2
+ from whatap.trace import get_dict
3
+ from whatap.trace.trace_handler import trace_handler
4
+ from whatap.trace.trace_error import \
5
+ interceptor_step_error
6
+ from whatap.trace.trace_context_manager import TraceContextManager
7
+ import whatap.net.async_sender as async_sender
8
+ from whatap.net.packet_type_enum import PacketTypeEnum
9
+ from whatap.util.date_util import DateUtil
10
+ import os, sys, logging
11
+ import traceback
12
+
13
+ from whatap.util.frame_util import get_current_frame
14
+
15
+ from pprint import pprint, pformat
16
+
17
+ class WhatapMongoCmdEventListener(pymongo.monitoring.CommandListener):
18
+ def __init__(self):
19
+ pass
20
+
21
+ def started(self, event):
22
+ try:
23
+ self.__started(event)
24
+ except Exception as e:
25
+ ctx = TraceContextManager.getLocalContext()
26
+ if ctx:
27
+ logging.debug(e, extra={'id': 'MON22', 'ctx.id':ctx.id}, exc_info=True)
28
+ else:
29
+ logging.debug(e, extra={'id': 'MON22'}, exc_info=True)
30
+
31
+ def __started(self, event):
32
+ ctx = TraceContextManager.getLocalContext()
33
+ if not ctx:
34
+ return
35
+ start_time = DateUtil.nowSystem()
36
+ ctx.start_time = start_time
37
+
38
+ port_or_path = event.database_name
39
+ text = 'mongodb://'
40
+ if hasattr(event, 'connection_id') and len(event.connection_id) == 2:
41
+ text += '{}:{}'.format(*event.connection_id)
42
+
43
+ text += '/'
44
+ text += event.database_name
45
+ ctx.active_dbc = text
46
+ ctx.lctx['dbc'] = text
47
+
48
+ ctx.active_dbc = 0
49
+ ctx.db_opening = True
50
+ datas = [text]
51
+ ctx.elapsed = 0
52
+ async_sender.send_packet(PacketTypeEnum.TX_DB_CONN, ctx, datas)
53
+
54
+ start_time = DateUtil.nowSystem()
55
+ ctx.start_time = start_time
56
+
57
+ def succeeded(self, event):
58
+ try:
59
+ self.__succeeded(event)
60
+ except Exception as e:
61
+ ctx = TraceContextManager.getLocalContext()
62
+ if ctx:
63
+ logging.debug(e, extra={'id': 'MON60', 'ctx.id':ctx.id}, exc_info=True)
64
+ else:
65
+ logging.debug(e, extra={'id': 'MON60'}, exc_info=True)
66
+
67
+
68
+ def __succeeded(self, event):
69
+ ctx = TraceContextManager.getLocalContext()
70
+ if not ctx:
71
+ return
72
+ query = 'command: {}, operation_id: {} '.format(event.command_name, event.operation_id)
73
+ if ctx.active_sqlhash:
74
+ query +=' query: {}'.format(ctx.active_sqlhash)
75
+
76
+ ctx.db_opening = False
77
+ datas = [ctx.lctx.get('dbc', ''), query, 0]
78
+ ctx.elapsed = int(event.duration_micros / 1000)
79
+ async_sender.send_packet(PacketTypeEnum.TX_SQL, ctx,
80
+ datas)
81
+
82
+ def failed(self, event):
83
+ try:
84
+ self.__failed(event)
85
+ except Exception as e:
86
+ ctx = TraceContextManager.getLocalContext()
87
+ if ctx:
88
+ logging.debug(e, extra={'id': 'MON85', 'ctx.id':ctx.id}, exc_info=True)
89
+ else:
90
+ logging.debug(e, extra={'id': 'MON85'}, exc_info=True)
91
+
92
+ def __failed(self, event):
93
+ ctx = TraceContextManager.getLocalContext()
94
+ if not ctx:
95
+ return
96
+
97
+ if hasattr(event, 'errtype'):
98
+ ctx.error_step = event.errtype
99
+ if not ctx.error:
100
+ ctx.error = 1
101
+
102
+ errors = []
103
+ if hasattr(event, 'errtype'):
104
+ errors.append(event.errtype)
105
+ else:
106
+ errors.append(str())
107
+ errors.append(str())
108
+
109
+ error = 'command: {}, operation_id: {}'.format(event.command_name, event.operation_id)
110
+ if ctx.active_sqlhash:
111
+ error +=' query: {}'.format(ctx.active_sqlhash)
112
+ frame = get_current_frame(ctx)
113
+ if not frame:
114
+ return
115
+
116
+ for stack in traceback.extract_stack(frame):
117
+ line = stack[0]
118
+ line_num = stack[1]
119
+ method_name = stack[2]
120
+
121
+ if 'whatap' + os.sep + 'trace' in line or 'threading.py' in line:
122
+ continue
123
+ error += '{} ({}:{})\n'.format(method_name,line, line_num)
124
+
125
+ errors.append(error)
126
+ ctx.elapsed = int(event.duration_micros / 1000)
127
+ async_sender.send_packet(PacketTypeEnum.TX_ERROR, ctx, errors)
128
+
129
+ def instrument_mongo_client(module):
130
+
131
+ def wrapper_init(fn):
132
+ def trace(*args, **kwargs):
133
+ _kwargs = dict()
134
+ if kwargs:
135
+ _kwargs.update(kwargs)
136
+
137
+ event_listeners = [WhatapMongoCmdEventListener()]
138
+ if 'event_listeners' in _kwargs:
139
+ if isinstance(_kwargs['event_listeners'], list):
140
+ event_listeners += _kwargs['event_listeners']
141
+ else:
142
+ event_listeners = _kwargs['event_listeners']
143
+ _kwargs['event_listeners'] = event_listeners
144
+
145
+ callback = fn(*args, **_kwargs)
146
+ return callback
147
+
148
+ return trace
149
+
150
+ def wrapper_find(fn):
151
+ def trace(*args, **kwargs):
152
+ ctx = TraceContextManager.getLocalContext()
153
+ if ctx:
154
+ if len(args) > 1 and isinstance(args[1], dict):
155
+ query = pformat(args[1], compact=True)
156
+
157
+ ctx.active_sqlhash = query
158
+ callback = fn(*args, **kwargs)
159
+ return callback
160
+ return trace
161
+
162
+ if hasattr(module, 'version_tuple'):
163
+ (major, minor, buildno) = module.version_tuple
164
+ if major >= 3:
165
+ if hasattr(module, 'monitoring'):
166
+ # module.MongoClient.__init__ = wrapper_init(module.MongoClient.__init__)
167
+ module.monitoring.register(WhatapMongoCmdEventListener())
168
+ if hasattr(module, 'collection') and hasattr(module.collection, 'Collection'):
169
+ module.collection.Collection.find = wrapper_find(module.collection.Collection.find)
@@ -0,0 +1,80 @@
1
+ from whatap.trace import get_dict
2
+ from whatap.trace.trace_handler import trace_handler
3
+ from whatap.trace.mod.database.util import interceptor_db_con, interceptor_db_execute, interceptor_db_close
4
+ db_info = {}
5
+
6
+ def _preload_mysql_db_info(*args, **kwargs):
7
+ global db_info
8
+ db_info = {'type': 'mysql'}
9
+ db_info.update(kwargs)
10
+
11
+ def instrument_MySQLdb(module):
12
+ def wrapper(fn):
13
+ @trace_handler(fn, preload=_preload_mysql_db_info)
14
+ def trace(*args, **kwargs):
15
+ callback = interceptor_db_con(fn, db_info, *args, **kwargs)
16
+ return callback
17
+
18
+ return trace
19
+
20
+ if hasattr(module, "connect"):
21
+ module.connect = wrapper(module.connect)
22
+
23
+ def wrapper(fn):
24
+ @trace_handler(fn)
25
+ def trace(*args, **kwargs):
26
+ callback = interceptor_db_close(fn, *args, **kwargs)
27
+ return callback
28
+
29
+ return trace
30
+
31
+ if hasattr(module, "connection") and hasattr(module.connection, "close"):
32
+ get_dict(module.connection)['close'] = wrapper(
33
+ module.connection.close)
34
+
35
+
36
+ def instrument_MySQLdb_cursors(module):
37
+ def wrapper(fn):
38
+ @trace_handler(fn)
39
+ def trace(*args, **kwargs):
40
+ callback = interceptor_db_execute(fn, db_info, *args, **kwargs)
41
+ return callback
42
+
43
+ return trace
44
+
45
+ module.BaseCursor.execute = wrapper(module.BaseCursor.execute)
46
+ if hasattr(module.BaseCursor, 'callproc'):
47
+ module.BaseCursor.callproc = wrapper(module.BaseCursor.callproc)
48
+
49
+ def instrument_pymysql(module):
50
+ def wrapper(fn):
51
+ @trace_handler(fn, preload=_preload_mysql_db_info)
52
+ def trace(*args, **kwargs):
53
+ callback = interceptor_db_con(fn, db_info, *args, **kwargs)
54
+ return callback
55
+
56
+ return trace
57
+
58
+ module.connect = wrapper(module.connect)
59
+
60
+ def wrapper(fn):
61
+ @trace_handler(fn)
62
+ def trace(*args, **kwargs):
63
+ callback = interceptor_db_close(fn, *args, **kwargs)
64
+ return callback
65
+
66
+ return trace
67
+
68
+ module.connections.Connection.close = wrapper(
69
+ module.connections.Connection.close)
70
+
71
+ def instrument_pymysql_cursors(module):
72
+ def wrapper(fn):
73
+ @trace_handler(fn)
74
+ def trace(*args, **kwargs):
75
+ callback = interceptor_db_execute(fn, db_info, *args, **kwargs)
76
+ return callback
77
+
78
+ return trace
79
+
80
+ module.Cursor.execute = wrapper(module.Cursor.execute)
@@ -0,0 +1,90 @@
1
+ from whatap.trace.trace_handler import trace_handler
2
+ from whatap.trace.mod.database.util import interceptor_db_con, interceptor_db_execute, interceptor_db_close
3
+
4
+ db_info = {}
5
+
6
+
7
+
8
+
9
+
10
+ def instrument_neo4j(module):
11
+
12
+ if hasattr(module, 'GraphDatabase'):
13
+ orig_driver = module.GraphDatabase.driver
14
+ def wrapper(fn):
15
+ @trace_handler(fn)
16
+ def trace(*args, **kwargs):
17
+ db_info = {'type': 'neo4j'}
18
+
19
+ if args:
20
+ db_info['uri'] = args[0]
21
+
22
+ auth = kwargs.get('auth') or (args[1] if len(args) > 1 else None)
23
+ if auth:
24
+ user = getattr(auth, 'principal', None) or (auth[0] if isinstance(auth, tuple) else None)
25
+ if user:
26
+ db_info['user'] = user
27
+
28
+ callback = interceptor_db_con(fn, db_info, *args, **kwargs)
29
+ return callback
30
+
31
+ return trace
32
+ module.GraphDatabase.driver = wrapper(orig_driver)
33
+
34
+
35
+
36
+ if hasattr(module, 'Driver'):
37
+ orig_driver_close = module.Driver.close
38
+ def wrapper(fn):
39
+ @trace_handler(fn)
40
+ def trace(driver, *args, **kwargs):
41
+ callback = interceptor_db_close(fn, driver, *args, **kwargs)
42
+ return callback
43
+
44
+ return trace
45
+
46
+ module.Driver.close = wrapper(orig_driver_close)
47
+
48
+ orig = module.Session.run
49
+ def wrapper(fn):
50
+ @trace_handler(fn)
51
+ def trace(session, *args, **kwargs):
52
+ db_info = {'type': 'neo4j'}
53
+ try:
54
+ setattr(session, 'rowcount', -1)
55
+ except Exception as e:
56
+ raise e
57
+ callback = interceptor_db_execute(fn, db_info, session, *args, **kwargs)
58
+
59
+ return callback
60
+ return trace
61
+ module.Session.run = wrapper(orig)
62
+
63
+ def wrapper(fn):
64
+ @trace_handler(fn)
65
+ def trace(tx, *args, **kwargs):
66
+ session = None
67
+ try:
68
+ session = tx._on_closed.__self__
69
+ except AttributeError:
70
+ return fn(tx, *args, **kwargs)
71
+ db_info = {'type': 'neo4j'}
72
+ try:
73
+ setattr(tx, 'rowcount', -1)
74
+ except Exception:
75
+ pass
76
+ callback = interceptor_db_execute(fn, db_info, tx, *args, **kwargs)
77
+ return callback
78
+
79
+ return trace
80
+
81
+ tx_classes_to_patch = ['Transaction', 'ManagedTransaction', 'BoltTransaction']
82
+ for class_name in tx_classes_to_patch:
83
+ if hasattr(module, class_name):
84
+ TxClass = getattr(module, class_name)
85
+ if hasattr(TxClass, 'run'):
86
+ original_run = getattr(TxClass, 'run')
87
+ setattr(TxClass, 'run', wrapper(original_run))
88
+
89
+
90
+
@@ -0,0 +1,45 @@
1
+ from whatap.trace import get_dict
2
+ from whatap.trace.trace_handler import trace_handler
3
+ from whatap.trace.mod.database.util import interceptor_db_con, interceptor_db_execute, interceptor_db_close
4
+
5
+ db_info = {}
6
+
7
+ def _preload_pg_db_info(*args, **kwargs):
8
+ global db_info
9
+ db_info = {'type': 'postgresql'}
10
+ db_info.update(kwargs)
11
+
12
+ def instrument_psycopg2(module):
13
+ def wrapper(fn):
14
+ @trace_handler(fn, preload=_preload_pg_db_info)
15
+ def trace(*args, **kwargs):
16
+ callback = interceptor_db_con(fn, db_info, *args, **kwargs)
17
+ return callback
18
+
19
+ return trace
20
+
21
+ module.connect = wrapper(module.connect)
22
+
23
+
24
+ def instrument_psycopg2_connection(module):
25
+ def wrapper(fn):
26
+ @trace_handler(fn)
27
+ def trace(*args, **kwargs):
28
+ callback = interceptor_db_close(fn, *args, **kwargs)
29
+ return callback
30
+
31
+ return trace
32
+
33
+ get_dict(module.connection)['close'] = wrapper(module.connection.close)
34
+
35
+
36
+ def instrument_psycopg2_extensions(module):
37
+ def wrapper(fn):
38
+ @trace_handler(fn)
39
+ def trace(*args, **kwargs):
40
+ callback = interceptor_db_execute(fn, db_info, *args, **kwargs)
41
+ return callback
42
+
43
+ return trace
44
+
45
+ get_dict(module.cursor)['execute'] = wrapper(module.cursor.execute)