whatap-python 1.8.10__tar.gz → 1.8.11__tar.gz
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.
Potentially problematic release.
This version of whatap-python might be problematic. Click here for more details.
- {whatap_python-1.8.10 → whatap_python-1.8.11}/PKG-INFO +1 -1
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/agent/linux/amd64/whatap_python +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/agent/linux/arm64/whatap_python +0 -0
- whatap_python-1.8.11/whatap/build.py +4 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/psycopg3.py +128 -58
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/sqlalchemy.py +4 -4
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/util.py +64 -7
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/trace_module_definition.py +2 -1
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap_python.egg-info/PKG-INFO +1 -1
- whatap_python-1.8.10/whatap/build.py +0 -4
- {whatap_python-1.8.10 → whatap_python-1.8.11}/README.md +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/setup.cfg +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/setup.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/LICENSE +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/README.rst +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/__main__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/agent/darwin/amd64/whatap_python +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/agent/darwin/arm64/whatap_python +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/bootstrap/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/bootstrap/sitecustomize.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/conf/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/conf/configuration.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/conf/configure.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/conf/license.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/control/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/counter/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/counter/counter_manager.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/counter/tasks/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/counter/tasks/openfiledescriptor.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/io/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/io/data_inputx.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/io/data_outputx.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/async_sender.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/packet_enum.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/packet_type_enum.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/param_def.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/stackhelper.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/udp_session.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/net/udp_thread.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/pack/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/pack/logSinkPack.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/pack/pack.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/pack/pack_enum.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/pack/tagCountPack.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/scripts/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/amqp/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/amqp/kombu.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/amqp/pika.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/bottle.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/celery.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/cherrypy.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/django.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/django_asgi.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/django_py3.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/fastapi.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/flask.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/frappe.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/graphql.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/nameko.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/odoo.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/starlette.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/tornado.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/application/wsgi.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/cxoracle.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/mongo.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/mysql.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/neo4j.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/psycopg2.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/redis.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/database/sqlite3.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/email/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/email/smtp.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/httpc/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/httpc/django.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/httpc/httplib.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/httpc/httpx.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/httpc/requests.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/httpc/urllib3.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/llm/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/llm/openai.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/logging.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/plugin.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/standalone/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/standalone/multiple.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/mod/standalone/single.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/simple_trace_context.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/trace_context.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/trace_context_manager.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/trace/trace_import.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/bit_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/cardinality/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/cardinality/hyperloglog.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/cardinality/murmurhash.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/cardinality/registerset.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/compare_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/date_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/debug_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/escape_literal_sql.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/hash_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/hexa32.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/int_set.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/ip_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/keygen.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/linked_list.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/linked_map.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/metering_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/request_double_queue.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/request_queue.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/string_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/throttle_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/util/userid_util.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/__init__.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/blob_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/boolean_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/decimal_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/double_summary.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/double_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/float_array.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/float_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/int_array.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/ip4_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/list_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/long_array.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/long_summary.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/map_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/null_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/number_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/summary_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/text_array.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/text_hash_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/text_value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/value.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/value/value_enum.py +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap/whatap.conf +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap_python.egg-info/SOURCES.txt +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap_python.egg-info/dependency_links.txt +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap_python.egg-info/entry_points.txt +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap_python.egg-info/not-zip-safe +0 -0
- {whatap_python-1.8.10 → whatap_python-1.8.11}/whatap_python.egg-info/top_level.txt +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
|
|
1
3
|
from whatap.trace.mod.application.wsgi import trace_handler
|
|
2
4
|
from whatap.trace.mod.database.util import (
|
|
3
5
|
interceptor_db_con, interceptor_db_execute, interceptor_db_close,
|
|
4
|
-
async_interceptor_db_con, async_interceptor_db_execute, async_interceptor_db_close
|
|
6
|
+
async_interceptor_db_con, async_interceptor_db_execute, async_interceptor_db_close,
|
|
7
|
+
interceptor_pool_get, interceptor_pool_release,
|
|
8
|
+
async_interceptor_pool_get, async_interceptor_pool_release
|
|
5
9
|
)
|
|
6
10
|
|
|
7
11
|
db_info = {}
|
|
@@ -11,6 +15,7 @@ class BaseCursor:
|
|
|
11
15
|
def __init__(self, cursor, db_info):
|
|
12
16
|
self._cursor = cursor
|
|
13
17
|
self._db_info = db_info
|
|
18
|
+
self._is_wrapped = True
|
|
14
19
|
|
|
15
20
|
def __getattr__(self, name):
|
|
16
21
|
return getattr(self._cursor, name)
|
|
@@ -45,28 +50,23 @@ class SyncCursor(BaseCursor):
|
|
|
45
50
|
return self._cursor.__exit__(exc_type, exc_val, exc_tb)
|
|
46
51
|
|
|
47
52
|
def execute(self, *args, **kwargs):
|
|
53
|
+
if hasattr(self._cursor, '_is_wrapped'):
|
|
54
|
+
return self._cursor.execute(*args, **kwargs)
|
|
48
55
|
real_execute = self._cursor.execute
|
|
49
56
|
safe_fn = self._execute_wrapper(real_execute)
|
|
50
|
-
|
|
51
|
-
callback = interceptor_db_execute(safe_fn,self._db_info,self._cursor,*args,**kwargs)
|
|
52
|
-
|
|
53
|
-
return callback
|
|
57
|
+
return interceptor_db_execute(safe_fn, self._db_info, self._cursor, *args, **kwargs)
|
|
54
58
|
|
|
55
59
|
def executemany(self, *args, **kwargs):
|
|
60
|
+
if hasattr(self._cursor, '_is_wrapped'):
|
|
61
|
+
return self._cursor.executemany(*args, **kwargs)
|
|
56
62
|
real_executemany = getattr(self._cursor, "executemany", None)
|
|
57
|
-
|
|
58
63
|
if real_executemany is None:
|
|
59
64
|
return self._cursor.executemany(*args, **kwargs)
|
|
60
|
-
|
|
61
65
|
safe_fn = self._execute_wrapper(real_executemany)
|
|
62
|
-
|
|
63
|
-
callback = interceptor_db_execute(safe_fn,self._db_info,self._cursor,*args,**kwargs)
|
|
64
|
-
|
|
65
|
-
return callback
|
|
66
|
+
return interceptor_db_execute(safe_fn, self._db_info, self._cursor, *args, **kwargs)
|
|
66
67
|
|
|
67
68
|
|
|
68
69
|
class AsyncCursor(BaseCursor):
|
|
69
|
-
|
|
70
70
|
async def __aenter__(self):
|
|
71
71
|
await self._cursor.__aenter__()
|
|
72
72
|
return self
|
|
@@ -85,30 +85,27 @@ class AsyncCursor(BaseCursor):
|
|
|
85
85
|
return async_safe_execute
|
|
86
86
|
|
|
87
87
|
async def execute(self, *args, **kwargs):
|
|
88
|
+
if hasattr(self._cursor, '_is_wrapped'):
|
|
89
|
+
return await self._cursor.execute(*args, **kwargs)
|
|
88
90
|
real_execute = self._cursor.execute
|
|
89
91
|
safe_fn = self._async_execute_wrapper(real_execute)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
callback = await async_interceptor_db_execute(safe_fn,self._db_info,self._cursor,*args,**kwargs)
|
|
93
|
-
|
|
94
|
-
return callback
|
|
92
|
+
return await async_interceptor_db_execute(safe_fn, self._db_info, self._cursor, *args, **kwargs)
|
|
95
93
|
|
|
96
94
|
async def executemany(self, *args, **kwargs):
|
|
95
|
+
if hasattr(self._cursor, '_is_wrapped'):
|
|
96
|
+
return await self._cursor.executemany(*args, **kwargs)
|
|
97
97
|
real_executemany = getattr(self._cursor, "executemany", None)
|
|
98
|
-
|
|
99
98
|
if real_executemany is None:
|
|
100
99
|
return await self._cursor.executemany(*args, **kwargs)
|
|
101
|
-
|
|
102
100
|
safe_fn = self._async_execute_wrapper(real_executemany)
|
|
103
|
-
|
|
104
|
-
callback = await async_interceptor_db_execute(safe_fn,self._db_info,self._cursor,*args,**kwargs)
|
|
105
|
-
return callback
|
|
101
|
+
return await async_interceptor_db_execute(safe_fn, self._db_info, self._cursor, *args, **kwargs)
|
|
106
102
|
|
|
107
103
|
|
|
108
104
|
class BaseConnection:
|
|
109
105
|
def __init__(self, connection, db_info):
|
|
110
106
|
self._connection = connection
|
|
111
107
|
self._db_info = db_info
|
|
108
|
+
self._is_wrapped = True
|
|
112
109
|
|
|
113
110
|
def __getattr__(self, name):
|
|
114
111
|
return getattr(self._connection, name)
|
|
@@ -129,15 +126,8 @@ class BaseConnection:
|
|
|
129
126
|
|
|
130
127
|
return safe_execute
|
|
131
128
|
|
|
132
|
-
def close(self, *args, **kwargs):
|
|
133
|
-
real_close = self._connection.close
|
|
134
|
-
|
|
135
|
-
callback = interceptor_db_close(real_close, *args, **kwargs)
|
|
136
|
-
return callback
|
|
137
|
-
|
|
138
129
|
|
|
139
130
|
class SyncConnection(BaseConnection):
|
|
140
|
-
|
|
141
131
|
def __enter__(self):
|
|
142
132
|
self._connection.__enter__()
|
|
143
133
|
return self
|
|
@@ -145,25 +135,31 @@ class SyncConnection(BaseConnection):
|
|
|
145
135
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
146
136
|
return self._connection.__exit__(exc_type, exc_val, exc_tb)
|
|
147
137
|
|
|
138
|
+
def close(self, *args, **kwargs):
|
|
139
|
+
if self._db_info.get("pool"):
|
|
140
|
+
interceptor_pool_release()
|
|
141
|
+
return self._connection.close(*args, **kwargs)
|
|
142
|
+
|
|
143
|
+
real_close = self._connection.close
|
|
144
|
+
return interceptor_db_close(real_close, *args, **kwargs)
|
|
145
|
+
|
|
148
146
|
def cursor(self, *args, **kwargs):
|
|
149
147
|
real_cursor = self._connection.cursor(*args, **kwargs)
|
|
148
|
+
if hasattr(real_cursor, '_is_wrapped'):
|
|
149
|
+
return real_cursor
|
|
150
150
|
return SyncCursor(real_cursor, self._db_info)
|
|
151
151
|
|
|
152
152
|
def execute(self, *args, **kwargs):
|
|
153
|
+
if hasattr(self._connection, '_is_wrapped'):
|
|
154
|
+
return self._connection.execute(*args, **kwargs)
|
|
153
155
|
real_execute = getattr(self._connection, "execute", None)
|
|
154
|
-
|
|
155
156
|
if real_execute is None:
|
|
156
157
|
return self._connection.execute(*args, **kwargs)
|
|
157
|
-
|
|
158
158
|
safe_fn = self._execute_wrapper(real_execute)
|
|
159
|
-
|
|
160
|
-
callback = interceptor_db_execute(safe_fn,self._db_info,self._cursor,*args,**kwargs)
|
|
161
|
-
|
|
162
|
-
return callback
|
|
159
|
+
return interceptor_db_execute(safe_fn, self._db_info, self._connection, *args, **kwargs)
|
|
163
160
|
|
|
164
161
|
|
|
165
162
|
class AsyncConnection(BaseConnection):
|
|
166
|
-
|
|
167
163
|
async def __aenter__(self):
|
|
168
164
|
await self._connection.__aenter__()
|
|
169
165
|
return self
|
|
@@ -173,6 +169,8 @@ class AsyncConnection(BaseConnection):
|
|
|
173
169
|
|
|
174
170
|
def cursor(self, *args, **kwargs):
|
|
175
171
|
real_cursor = self._connection.cursor(*args, **kwargs)
|
|
172
|
+
if hasattr(real_cursor, '_is_wrapped'):
|
|
173
|
+
return real_cursor
|
|
176
174
|
return AsyncCursor(real_cursor, self._db_info)
|
|
177
175
|
|
|
178
176
|
def _async_execute_wrapper(self, original_execute_method):
|
|
@@ -186,66 +184,138 @@ class AsyncConnection(BaseConnection):
|
|
|
186
184
|
return async_safe_execute
|
|
187
185
|
|
|
188
186
|
async def execute(self, *args, **kwargs):
|
|
187
|
+
if hasattr(self._connection, '_is_wrapped'):
|
|
188
|
+
return await self._connection.execute(*args, **kwargs)
|
|
189
189
|
real_execute = getattr(self._connection, "execute", None)
|
|
190
|
-
|
|
191
190
|
if real_execute is None:
|
|
192
191
|
return await self._connection.execute(*args, **kwargs)
|
|
193
|
-
|
|
194
192
|
safe_fn = self._async_execute_wrapper(real_execute)
|
|
195
|
-
|
|
196
|
-
callback = await async_interceptor_db_execute(safe_fn,self._db_info,self._connection,*args,**kwargs)
|
|
197
|
-
|
|
198
|
-
return callback
|
|
193
|
+
return await async_interceptor_db_execute(safe_fn, self._db_info, self._connection, *args, **kwargs)
|
|
199
194
|
|
|
200
195
|
async def close(self, *args, **kwargs):
|
|
196
|
+
if self._db_info.get("pool"):
|
|
197
|
+
await async_interceptor_pool_release()
|
|
198
|
+
return await self._connection.close(*args, **kwargs)
|
|
199
|
+
|
|
201
200
|
real_close = self._connection.close
|
|
201
|
+
return await async_interceptor_db_close(real_close, *args, **kwargs)
|
|
202
202
|
|
|
203
|
-
callback = await async_interceptor_db_close(real_close, *args, **kwargs)
|
|
204
203
|
|
|
205
|
-
|
|
204
|
+
def _is_called_by_pool():
|
|
205
|
+
try:
|
|
206
|
+
# 실제로 psycopg_pool은 보통 3-4 레벨 내에서 호출되므로 깊이 5로 결정.
|
|
207
|
+
filenames = [f.filename for f in inspect.stack(context=0)[2:7]]
|
|
208
|
+
return any('psycopg_pool' in f for f in filenames if f)
|
|
209
|
+
except Exception:
|
|
210
|
+
return False
|
|
206
211
|
|
|
207
212
|
|
|
208
213
|
def _sync_wrapper(fn):
|
|
209
|
-
|
|
210
214
|
@trace_handler(fn)
|
|
211
215
|
def wrapper(*args, **kwargs):
|
|
212
|
-
|
|
216
|
+
if _is_called_by_pool():
|
|
217
|
+
return fn(*args, **kwargs)
|
|
213
218
|
|
|
214
219
|
db_info = {"type": "postgresql"}
|
|
220
|
+
|
|
221
|
+
if args and isinstance(args[0], str) and '=' in args[0]:
|
|
222
|
+
conn_str = args[0]
|
|
223
|
+
parsed_kwargs = dict(
|
|
224
|
+
x.split('=') for x in conn_str.split()
|
|
225
|
+
)
|
|
226
|
+
kwargs.update(parsed_kwargs)
|
|
227
|
+
|
|
215
228
|
db_info.update(kwargs)
|
|
216
229
|
|
|
217
230
|
connection = interceptor_db_con(fn, db_info, *args, **kwargs)
|
|
218
|
-
|
|
231
|
+
if hasattr(connection, '_is_wrapped'):
|
|
232
|
+
return connection
|
|
219
233
|
return SyncConnection(connection, dict(db_info))
|
|
220
234
|
|
|
221
235
|
return wrapper
|
|
222
236
|
|
|
223
237
|
|
|
224
238
|
def _async_wrapper(fn):
|
|
225
|
-
|
|
226
239
|
@trace_handler(fn)
|
|
227
240
|
async def wrapper(*args, **kwargs):
|
|
228
|
-
|
|
241
|
+
if _is_called_by_pool():
|
|
242
|
+
return await fn(*args, **kwargs)
|
|
229
243
|
|
|
230
244
|
db_info = {"type": "postgresql"}
|
|
231
|
-
db_info.update(kwargs)
|
|
232
245
|
|
|
233
|
-
|
|
246
|
+
if args and isinstance(args[0], str) and '=' in args[0]:
|
|
247
|
+
conn_str = args[0]
|
|
248
|
+
parsed_kwargs = dict(
|
|
249
|
+
x.split('=') for x in conn_str.split()
|
|
250
|
+
)
|
|
251
|
+
kwargs.update(parsed_kwargs)
|
|
252
|
+
|
|
253
|
+
db_info.update(kwargs)
|
|
234
254
|
|
|
255
|
+
connection = await async_interceptor_db_con(fn, db_info, *args, **kwargs)
|
|
256
|
+
if hasattr(connection, '_is_wrapped'):
|
|
257
|
+
return connection
|
|
235
258
|
return AsyncConnection(connection, dict(db_info))
|
|
236
259
|
|
|
237
260
|
return wrapper
|
|
238
261
|
|
|
239
262
|
|
|
240
|
-
def
|
|
241
|
-
|
|
263
|
+
def _get_conn_info(connection):
|
|
264
|
+
conn_info = {}
|
|
265
|
+
try:
|
|
266
|
+
if hasattr(connection, 'info'):
|
|
267
|
+
conn_info['host'] = connection.info.host
|
|
268
|
+
conn_info['port'] = connection.info.port
|
|
269
|
+
conn_info['dbname'] = connection.info.dbname
|
|
270
|
+
conn_info['user'] = connection.info.user
|
|
271
|
+
elif hasattr(connection, 'dsn'):
|
|
272
|
+
import re
|
|
273
|
+
dsn_params = dict(x.split('=') for x in re.sub(r'\s*=\s*', '=', connection.dsn).split())
|
|
274
|
+
conn_info.update(dsn_params)
|
|
275
|
+
except Exception as e:
|
|
276
|
+
print(f"Failed to extract connection info: {e}")
|
|
277
|
+
return conn_info
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def _pool_getconn_wrapper(original_getconn):
|
|
281
|
+
@trace_handler(original_getconn)
|
|
282
|
+
def wrapper(self, *args, **kwargs):
|
|
283
|
+
connection = original_getconn(self, *args, **kwargs)
|
|
284
|
+
conn_info = _get_conn_info(connection)
|
|
285
|
+
db_info = {"type": "postgresql", "pool": True, **conn_info}
|
|
286
|
+
|
|
287
|
+
interceptor_pool_get(db_info)
|
|
288
|
+
|
|
289
|
+
return SyncConnection(connection, db_info)
|
|
290
|
+
|
|
291
|
+
return wrapper
|
|
292
|
+
|
|
242
293
|
|
|
294
|
+
def _async_pool_getconn_wrapper(original_getconn):
|
|
295
|
+
@trace_handler(original_getconn)
|
|
296
|
+
async def wrapper(self, *args, **kwargs):
|
|
297
|
+
connection = await original_getconn(self, *args, **kwargs)
|
|
298
|
+
conn_info = _get_conn_info(connection)
|
|
299
|
+
db_info = {"type": "postgresql", "pool": True, **conn_info}
|
|
300
|
+
|
|
301
|
+
await async_interceptor_pool_get(db_info)
|
|
302
|
+
|
|
303
|
+
return AsyncConnection(connection, db_info)
|
|
304
|
+
|
|
305
|
+
return wrapper
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def instrument_psycopg(module):
|
|
309
|
+
original_connect = module.connect
|
|
243
310
|
module.connect = _sync_wrapper(original_connect)
|
|
311
|
+
if hasattr(module, 'AsyncConnection') and hasattr(module.AsyncConnection, 'connect'):
|
|
312
|
+
original_async_connect = module.AsyncConnection.connect
|
|
313
|
+
module.AsyncConnection.connect = _async_wrapper(original_async_connect)
|
|
244
314
|
|
|
245
|
-
if hasattr(module, 'AsyncConnection'):
|
|
246
|
-
async_conn = module.AsyncConnection
|
|
247
315
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
316
|
+
def instrument_psycopg_pool(pool_module):
|
|
317
|
+
if hasattr(pool_module, 'ConnectionPool'):
|
|
318
|
+
pool_module.ConnectionPool.getconn = _pool_getconn_wrapper(pool_module.ConnectionPool.getconn)
|
|
319
|
+
if hasattr(pool_module, 'AsyncConnectionPool'):
|
|
320
|
+
pool_module.AsyncConnectionPool.getconn = _async_pool_getconn_wrapper(pool_module.AsyncConnectionPool.getconn)
|
|
251
321
|
|
|
@@ -49,7 +49,7 @@ def instrument_sqlalchemy_engine(module):
|
|
|
49
49
|
query = None
|
|
50
50
|
if len(args) > 3 and args[3]:
|
|
51
51
|
try:
|
|
52
|
-
##
|
|
52
|
+
##oracle을 사용하는 경우
|
|
53
53
|
if (type(args[3]) == dict) and (":" in args[2]) and ("oracle" in str(args[0])):
|
|
54
54
|
oracle_sql_query = args[2]
|
|
55
55
|
for k, v in args[3].items():
|
|
@@ -59,8 +59,8 @@ def instrument_sqlalchemy_engine(module):
|
|
|
59
59
|
replaced_value) if replaced_key in oracle_sql_query else None
|
|
60
60
|
query = oracle_sql_query
|
|
61
61
|
|
|
62
|
-
##
|
|
63
|
-
elif (type(args[3]) == tuple) and ("%s" in args[2]) and ("
|
|
62
|
+
##mysql를 사용하는 경우
|
|
63
|
+
elif (type(args[3]) == tuple) and ("%s" in args[2]) and ("mysql" in str(args[0])):
|
|
64
64
|
my_sql_query = args[2]
|
|
65
65
|
for v in args[3]:
|
|
66
66
|
replaced_value = f"'{v}'"
|
|
@@ -79,7 +79,7 @@ def instrument_sqlalchemy_engine(module):
|
|
|
79
79
|
query = str(args[2])
|
|
80
80
|
# print('instrument_sqlalchemy_engine 3:', query)
|
|
81
81
|
sqlalchemy_track_skip = False
|
|
82
|
-
except_track_module = ['pymysql', 'mysqldb', 'psycopg2']
|
|
82
|
+
except_track_module = ['pymysql', 'mysqldb', 'psycopg2','psycopg','sqlite3']
|
|
83
83
|
|
|
84
84
|
# 이미 DB드라이브 추적 모듈이 존재하면 sqlAlhechmy 의 추적 중지
|
|
85
85
|
if any(keyword in str(args[0]) for keyword in except_track_module):
|
|
@@ -63,7 +63,6 @@ def addQuoteMany(arg_list, query_template=None):
|
|
|
63
63
|
Returns:
|
|
64
64
|
str: 포매팅된 문자열
|
|
65
65
|
"""
|
|
66
|
-
print(arg_list)
|
|
67
66
|
if not arg_list:
|
|
68
67
|
return ""
|
|
69
68
|
|
|
@@ -110,7 +109,6 @@ def addQuoteMany(arg_list, query_template=None):
|
|
|
110
109
|
|
|
111
110
|
result = ";\n".join(queries)
|
|
112
111
|
|
|
113
|
-
print(result)
|
|
114
112
|
return result
|
|
115
113
|
|
|
116
114
|
except Exception as e:
|
|
@@ -228,7 +226,6 @@ def interceptor_db_execute(fn, db_info, *args, **kwargs):
|
|
|
228
226
|
self = args[0]
|
|
229
227
|
db_type = db_info.get('type')
|
|
230
228
|
query = None
|
|
231
|
-
|
|
232
229
|
if db_type == "neo4j":
|
|
233
230
|
try:
|
|
234
231
|
query = neo4jQuery(args[1], kwargs)
|
|
@@ -332,8 +329,6 @@ def interceptor_db_close(fn, *args, **kwargs):
|
|
|
332
329
|
async_sender.send_packet(PacketTypeEnum.TX_MSG, ctx, datas)
|
|
333
330
|
|
|
334
331
|
|
|
335
|
-
# ===== 비동기 버전 (새로 추가) =====
|
|
336
|
-
|
|
337
332
|
async def async_interceptor_db_con(fn, db_info, *args, **kwargs):
|
|
338
333
|
ctx = TraceContextManager.getLocalContext()
|
|
339
334
|
if not ctx:
|
|
@@ -381,7 +376,6 @@ async def async_interceptor_db_execute(fn, db_info, *args, **kwargs):
|
|
|
381
376
|
self = args[0]
|
|
382
377
|
db_type = db_info.get('type')
|
|
383
378
|
query = None
|
|
384
|
-
|
|
385
379
|
if db_type == "neo4j":
|
|
386
380
|
try:
|
|
387
381
|
query = neo4jQuery(args[1], kwargs)
|
|
@@ -491,4 +485,67 @@ async def async_interceptor_db_close(fn, *args, **kwargs):
|
|
|
491
485
|
text = 'DB: Close Connection.'
|
|
492
486
|
datas = [' ', ' ', text]
|
|
493
487
|
ctx.elapsed = DateUtil.nowSystem() - start_time
|
|
494
|
-
async_sender.send_packet(PacketTypeEnum.TX_MSG, ctx, datas)
|
|
488
|
+
async_sender.send_packet(PacketTypeEnum.TX_MSG, ctx, datas)
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def interceptor_pool_get(db_info):
|
|
492
|
+
ctx = TraceContextManager.getLocalContext()
|
|
493
|
+
if not ctx:
|
|
494
|
+
return
|
|
495
|
+
|
|
496
|
+
start_time = DateUtil.nowSystem()
|
|
497
|
+
|
|
498
|
+
db_type = db_info.get('type', 'db')
|
|
499
|
+
text = f"{db_type}://{db_info.get('user', '')}@{db_info.get('host', '')}/{db_info.get('dbname', '')}"
|
|
500
|
+
|
|
501
|
+
ctx.active_dbc = text
|
|
502
|
+
ctx.lctx['dbc'] = text
|
|
503
|
+
ctx.active_dbc = 0
|
|
504
|
+
|
|
505
|
+
datas = [text]
|
|
506
|
+
ctx.elapsed = DateUtil.nowSystem() - start_time
|
|
507
|
+
|
|
508
|
+
async_sender.send_packet(PacketTypeEnum.TX_DB_CONN, ctx, datas)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def interceptor_pool_release():
|
|
512
|
+
ctx = TraceContextManager.getLocalContext()
|
|
513
|
+
if not ctx or not conf.profile_dbc_close:
|
|
514
|
+
return
|
|
515
|
+
|
|
516
|
+
start_time = DateUtil.nowSystem()
|
|
517
|
+
text = 'DB: Close Connection.'
|
|
518
|
+
datas = [' ', ' ', text]
|
|
519
|
+
ctx.elapsed = DateUtil.nowSystem() - start_time
|
|
520
|
+
async_sender.send_packet(PacketTypeEnum.TX_MSG, ctx, datas)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
async def async_interceptor_pool_get(db_info):
|
|
524
|
+
ctx = TraceContextManager.getLocalContext()
|
|
525
|
+
if not ctx:
|
|
526
|
+
return
|
|
527
|
+
|
|
528
|
+
start_time = DateUtil.nowSystem()
|
|
529
|
+
|
|
530
|
+
db_type = db_info.get('type', 'db')
|
|
531
|
+
text = f"{db_type}://{db_info.get('user', '')}@{db_info.get('host', '')}/{db_info.get('dbname', '')}"
|
|
532
|
+
|
|
533
|
+
ctx.active_dbc = text
|
|
534
|
+
ctx.lctx['dbc'] = text
|
|
535
|
+
ctx.active_dbc = 0
|
|
536
|
+
|
|
537
|
+
datas = [text]
|
|
538
|
+
ctx.elapsed = DateUtil.nowSystem() - start_time
|
|
539
|
+
|
|
540
|
+
async_sender.send_packet(PacketTypeEnum.TX_DB_CONN, ctx, datas)
|
|
541
|
+
|
|
542
|
+
async def async_interceptor_pool_release():
|
|
543
|
+
ctx = TraceContextManager.getLocalContext()
|
|
544
|
+
if not ctx or not conf.profile_dbc_close:
|
|
545
|
+
return
|
|
546
|
+
|
|
547
|
+
start_time = DateUtil.nowSystem()
|
|
548
|
+
text = 'DB: Close Connection.'
|
|
549
|
+
datas = [' ', ' ', text]
|
|
550
|
+
ctx.elapsed = DateUtil.nowSystem() - start_time
|
|
551
|
+
async_sender.send_packet(PacketTypeEnum.TX_MSG, ctx, datas)
|
|
@@ -57,7 +57,8 @@ DEFINITION = {
|
|
|
57
57
|
('psycopg2.extensions', 'instrument_psycopg2_extensions'),
|
|
58
58
|
],
|
|
59
59
|
'database.psycopg3': [
|
|
60
|
-
('psycopg', '
|
|
60
|
+
('psycopg', 'instrument_psycopg'),
|
|
61
|
+
('psycopg_pool', 'instrument_psycopg_pool'),
|
|
61
62
|
],
|
|
62
63
|
|
|
63
64
|
'database.neo4j': [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|