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.
- whatap/LICENSE +0 -0
- whatap/README.rst +49 -0
- whatap/__init__.py +923 -0
- whatap/__main__.py +4 -0
- whatap/agent/darwin/amd64/whatap_python +0 -0
- whatap/agent/darwin/arm64/whatap_python +0 -0
- whatap/agent/linux/amd64/whatap_python +0 -0
- whatap/agent/linux/arm64/whatap_python +0 -0
- whatap/agent/windows/whatap_python.exe +0 -0
- whatap/bootstrap/__init__.py +0 -0
- whatap/bootstrap/sitecustomize.py +19 -0
- whatap/build.py +4 -0
- whatap/conf/__init__.py +0 -0
- whatap/conf/configuration.py +280 -0
- whatap/conf/configure.py +105 -0
- whatap/conf/license.py +49 -0
- whatap/control/__init__.py +0 -0
- whatap/counter/__init__.py +14 -0
- whatap/counter/counter_manager.py +45 -0
- whatap/counter/tasks/__init__.py +3 -0
- whatap/counter/tasks/base_task.py +26 -0
- whatap/counter/tasks/llm_evaluator_task.py +501 -0
- whatap/counter/tasks/llm_log_sink_task.py +309 -0
- whatap/counter/tasks/llm_stat_task.py +78 -0
- whatap/counter/tasks/openfiledescriptor.py +67 -0
- whatap/io/__init__.py +1 -0
- whatap/io/data_inputx.py +161 -0
- whatap/io/data_outputx.py +262 -0
- whatap/llm/__init__.py +17 -0
- whatap/llm/definitions.py +43 -0
- whatap/llm/evaluators/__init__.py +136 -0
- whatap/llm/evaluators/base.py +114 -0
- whatap/llm/evaluators/builtins/__init__.py +91 -0
- whatap/llm/evaluators/builtins/answer_relevance.py +46 -0
- whatap/llm/evaluators/builtins/combined_judge.py +271 -0
- whatap/llm/evaluators/builtins/factuality.py +71 -0
- whatap/llm/evaluators/builtins/hallucination.py +97 -0
- whatap/llm/evaluators/builtins/llm_judge.py +516 -0
- whatap/llm/evaluators/builtins/pii_leak.py +214 -0
- whatap/llm/evaluators/builtins/prompt_injection.py +71 -0
- whatap/llm/evaluators/builtins/toxicity.py +53 -0
- whatap/llm/evaluators/builtins/url_scan.py +194 -0
- whatap/llm/evaluators/registry.py +192 -0
- whatap/llm/evaluators/sampler.py +83 -0
- whatap/llm/evaluators/scope.py +334 -0
- whatap/llm/features.py +66 -0
- whatap/llm/log_sink_packs/__init__.py +9 -0
- whatap/llm/log_sink_packs/llm_input_message.py +16 -0
- whatap/llm/log_sink_packs/llm_log_sink_pack.py +72 -0
- whatap/llm/log_sink_packs/llm_output_message.py +19 -0
- whatap/llm/log_sink_packs/llm_step_eval_status.py +94 -0
- whatap/llm/log_sink_packs/llm_step_status.py +118 -0
- whatap/llm/log_sink_packs/llm_system_message.py +16 -0
- whatap/llm/log_sink_packs/llm_tool_calls.py +44 -0
- whatap/llm/log_sink_packs/llm_tool_results.py +16 -0
- whatap/llm/log_sink_packs/llm_tx_status.py +108 -0
- whatap/llm/pricing.py +236 -0
- whatap/llm/prompt_meta.py +288 -0
- whatap/llm/providers/__init__.py +0 -0
- whatap/llm/providers/anthropic/__init__.py +37 -0
- whatap/llm/providers/anthropic/messages/__init__.py +0 -0
- whatap/llm/providers/anthropic/messages/messages.py +70 -0
- whatap/llm/providers/anthropic/messages/messages_context.py +76 -0
- whatap/llm/providers/anthropic/messages/messages_extractor.py +126 -0
- whatap/llm/providers/interceptor.py +182 -0
- whatap/llm/providers/openai/__init__.py +133 -0
- whatap/llm/providers/openai/chat/__init__.py +0 -0
- whatap/llm/providers/openai/chat/chat.py +82 -0
- whatap/llm/providers/openai/chat/chat_context.py +78 -0
- whatap/llm/providers/openai/chat/chat_extractor.py +127 -0
- whatap/llm/providers/openai/completions/__init__.py +0 -0
- whatap/llm/providers/openai/completions/completions.py +70 -0
- whatap/llm/providers/openai/completions/completions_context.py +31 -0
- whatap/llm/providers/openai/completions/completions_extractor.py +61 -0
- whatap/llm/providers/openai/content_parser.py +41 -0
- whatap/llm/providers/openai/embeddings/__init__.py +0 -0
- whatap/llm/providers/openai/embeddings/embeddings.py +59 -0
- whatap/llm/providers/openai/embeddings/embeddings_context.py +25 -0
- whatap/llm/providers/openai/embeddings/embeddings_extractor.py +26 -0
- whatap/llm/providers/openai/responses/__init__.py +0 -0
- whatap/llm/providers/openai/responses/responses.py +70 -0
- whatap/llm/providers/openai/responses/responses_context.py +88 -0
- whatap/llm/providers/openai/responses/responses_extractor.py +126 -0
- whatap/llm/providers/stream_accumulator.py +73 -0
- whatap/llm/stats/__init__.py +35 -0
- whatap/llm/stats/active_stat.py +86 -0
- whatap/llm/stats/answer_relevance_eval_stat.py +10 -0
- whatap/llm/stats/api_status_stat.py +35 -0
- whatap/llm/stats/base_stat.py +107 -0
- whatap/llm/stats/combined_judge_eval_stat.py +11 -0
- whatap/llm/stats/error_stat.py +59 -0
- whatap/llm/stats/eval_stat.py +225 -0
- whatap/llm/stats/factuality_eval_stat.py +10 -0
- whatap/llm/stats/feature_stat.py +104 -0
- whatap/llm/stats/finish_stat.py +105 -0
- whatap/llm/stats/hallucination_eval_stat.py +10 -0
- whatap/llm/stats/meter.py +18 -0
- whatap/llm/stats/perf_stat.py +117 -0
- whatap/llm/stats/pii_leak_eval_stat.py +12 -0
- whatap/llm/stats/prompt_injection_eval_stat.py +10 -0
- whatap/llm/stats/token_usage_stat.py +133 -0
- whatap/llm/stats/toxicity_eval_stat.py +10 -0
- whatap/llm/stats/url_scan_eval_stat.py +12 -0
- whatap/net/__init__.py +0 -0
- whatap/net/async_sender.py +107 -0
- whatap/net/packet_enum.py +44 -0
- whatap/net/packet_type_enum.py +31 -0
- whatap/net/param_def.py +69 -0
- whatap/net/stackhelper.py +87 -0
- whatap/net/udp_session.py +394 -0
- whatap/net/udp_thread.py +54 -0
- whatap/pack/__init__.py +0 -0
- whatap/pack/logSinkPack.py +77 -0
- whatap/pack/pack.py +34 -0
- whatap/pack/pack_enum.py +41 -0
- whatap/pack/tagCountPack.py +61 -0
- whatap/scripts/__init__.py +208 -0
- whatap/trace/__init__.py +12 -0
- whatap/trace/mod/__init__.py +0 -0
- whatap/trace/mod/amqp/__init__.py +0 -0
- whatap/trace/mod/amqp/kombu.py +122 -0
- whatap/trace/mod/amqp/pika.py +62 -0
- whatap/trace/mod/application/__init__.py +0 -0
- whatap/trace/mod/application/bottle.py +34 -0
- whatap/trace/mod/application/celery.py +81 -0
- whatap/trace/mod/application/cherrypy.py +30 -0
- whatap/trace/mod/application/django.py +287 -0
- whatap/trace/mod/application/django_asgi.py +266 -0
- whatap/trace/mod/application/django_py3.py +251 -0
- whatap/trace/mod/application/fastapi/__init__.py +31 -0
- whatap/trace/mod/application/fastapi/endpoint.py +73 -0
- whatap/trace/mod/application/fastapi/exception_log.py +63 -0
- whatap/trace/mod/application/fastapi/instrumentation.py +204 -0
- whatap/trace/mod/application/fastapi/scope.py +115 -0
- whatap/trace/mod/application/fastapi/transaction.py +67 -0
- whatap/trace/mod/application/flask.py +52 -0
- whatap/trace/mod/application/frappe.py +224 -0
- whatap/trace/mod/application/graphql.py +170 -0
- whatap/trace/mod/application/nameko.py +39 -0
- whatap/trace/mod/application/odoo.py +63 -0
- whatap/trace/mod/application/starlette.py +126 -0
- whatap/trace/mod/application/tornado.py +163 -0
- whatap/trace/mod/application/wsgi.py +195 -0
- whatap/trace/mod/database/__init__.py +0 -0
- whatap/trace/mod/database/cxoracle.py +49 -0
- whatap/trace/mod/database/mongo.py +169 -0
- whatap/trace/mod/database/mysql.py +80 -0
- whatap/trace/mod/database/neo4j.py +90 -0
- whatap/trace/mod/database/psycopg2.py +45 -0
- whatap/trace/mod/database/psycopg3.py +359 -0
- whatap/trace/mod/database/redis.py +122 -0
- whatap/trace/mod/database/sqlalchemy.py +213 -0
- whatap/trace/mod/database/sqlite3.py +130 -0
- whatap/trace/mod/database/util.py +630 -0
- whatap/trace/mod/email/__init__.py +0 -0
- whatap/trace/mod/email/smtp.py +78 -0
- whatap/trace/mod/httpc/__init__.py +0 -0
- whatap/trace/mod/httpc/django.py +31 -0
- whatap/trace/mod/httpc/httplib.py +70 -0
- whatap/trace/mod/httpc/httpx.py +62 -0
- whatap/trace/mod/httpc/requests.py +20 -0
- whatap/trace/mod/httpc/urllib3.py +27 -0
- whatap/trace/mod/httpc/util.py +388 -0
- whatap/trace/mod/logging.py +161 -0
- whatap/trace/mod/plugin.py +84 -0
- whatap/trace/mod/standalone/__init__.py +0 -0
- whatap/trace/mod/standalone/multiple.py +293 -0
- whatap/trace/mod/standalone/single.py +135 -0
- whatap/trace/simple_trace_context.py +18 -0
- whatap/trace/trace_context.py +212 -0
- whatap/trace/trace_context_manager.py +244 -0
- whatap/trace/trace_error.py +84 -0
- whatap/trace/trace_handler.py +89 -0
- whatap/trace/trace_import.py +91 -0
- whatap/trace/trace_module_definition.py +156 -0
- whatap/util/__init__.py +0 -0
- whatap/util/bit_util.py +49 -0
- whatap/util/cardinality/__init__.py +0 -0
- whatap/util/cardinality/hyperloglog.py +84 -0
- whatap/util/cardinality/murmurhash.py +20 -0
- whatap/util/cardinality/registerset.py +60 -0
- whatap/util/compare_util.py +19 -0
- whatap/util/date_util.py +55 -0
- whatap/util/debug_util.py +73 -0
- whatap/util/escape_literal_sql.py +233 -0
- whatap/util/frame_util.py +20 -0
- whatap/util/hash_util.py +103 -0
- whatap/util/hexa32.py +66 -0
- whatap/util/int_set.py +199 -0
- whatap/util/ip_util.py +63 -0
- whatap/util/keygen.py +11 -0
- whatap/util/linked_list.py +113 -0
- whatap/util/linked_map.py +359 -0
- whatap/util/metering_util.py +103 -0
- whatap/util/request_double_queue.py +68 -0
- whatap/util/request_queue.py +60 -0
- whatap/util/string_util.py +20 -0
- whatap/util/throttle_util.py +99 -0
- whatap/util/userid_util.py +134 -0
- whatap/value/__init__.py +1 -0
- whatap/value/blob_value.py +38 -0
- whatap/value/boolean_value.py +33 -0
- whatap/value/decimal_value.py +36 -0
- whatap/value/double_summary.py +86 -0
- whatap/value/double_value.py +33 -0
- whatap/value/float_array.py +42 -0
- whatap/value/float_value.py +34 -0
- whatap/value/int_array.py +42 -0
- whatap/value/ip4_value.py +50 -0
- whatap/value/list_value.py +105 -0
- whatap/value/long_array.py +44 -0
- whatap/value/long_summary.py +83 -0
- whatap/value/map_value.py +154 -0
- whatap/value/null_value.py +21 -0
- whatap/value/number_value.py +33 -0
- whatap/value/summary_value.py +39 -0
- whatap/value/text_array.py +58 -0
- whatap/value/text_hash_value.py +37 -0
- whatap/value/text_value.py +43 -0
- whatap/value/value.py +26 -0
- whatap/value/value_enum.py +80 -0
- whatap/whatap.conf +14 -0
- whatap_python-2.1.0.dist-info/METADATA +87 -0
- whatap_python-2.1.0.dist-info/RECORD +227 -0
- whatap_python-2.1.0.dist-info/WHEEL +5 -0
- whatap_python-2.1.0.dist-info/entry_points.txt +6 -0
- whatap_python-2.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from importlib.util import find_spec
|
|
5
|
+
from importlib.abc import MetaPathFinder
|
|
6
|
+
except ImportError:
|
|
7
|
+
find_spec = None
|
|
8
|
+
|
|
9
|
+
from whatap.trace.trace_module_definition import IMPORT_HOOKS, PLUGIN
|
|
10
|
+
|
|
11
|
+
from whatap import logging
|
|
12
|
+
from whatap.conf.configure import Configure as conf
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def load_module(module, fullname):
|
|
16
|
+
# if conf.dev:
|
|
17
|
+
# logging.debug(fullname)
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
if fullname in IMPORT_HOOKS:
|
|
21
|
+
wfullname = IMPORT_HOOKS[fullname]['module']
|
|
22
|
+
wmodule = sys.modules.get(wfullname)
|
|
23
|
+
if not wmodule:
|
|
24
|
+
__import__(wfullname)
|
|
25
|
+
wmodule = sys.modules.get(wfullname)
|
|
26
|
+
|
|
27
|
+
if wfullname.endswith('plugin'):
|
|
28
|
+
module = {'module': module, 'class_defs': PLUGIN[fullname]}
|
|
29
|
+
|
|
30
|
+
getattr(wmodule,
|
|
31
|
+
IMPORT_HOOKS[fullname]['def'])(module)
|
|
32
|
+
logging.info("successfully injected %s as %s", fullname, wfullname)
|
|
33
|
+
else:
|
|
34
|
+
if conf.debug:
|
|
35
|
+
logging.info("non-injected module %s ", fullname)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
logging.debug(e, exc_info=True)
|
|
38
|
+
finally:
|
|
39
|
+
return module
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class _ImportHookLoader(object):
|
|
43
|
+
def load_module(self, fullname):
|
|
44
|
+
module = sys.modules[fullname]
|
|
45
|
+
return load_module(module, fullname)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class _ImportHookChainedLoader(object):
|
|
49
|
+
def __init__(self, loader):
|
|
50
|
+
self.loader = loader
|
|
51
|
+
|
|
52
|
+
def load_module(self, fullname):
|
|
53
|
+
module = self.loader.load_module(fullname)
|
|
54
|
+
return load_module(module, fullname)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ImportFinder(MetaPathFinder):
|
|
58
|
+
def __init__(self):
|
|
59
|
+
self._hooks = {}
|
|
60
|
+
|
|
61
|
+
def find_spec(self, fullname, path=None, target=None):
|
|
62
|
+
if fullname not in IMPORT_HOOKS \
|
|
63
|
+
or fullname.startswith('whatap') \
|
|
64
|
+
or fullname.startswith('pip'):
|
|
65
|
+
|
|
66
|
+
if conf.debug:
|
|
67
|
+
logging.info("non-injected module %s ", fullname)
|
|
68
|
+
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
if fullname in self._hooks:
|
|
72
|
+
return None
|
|
73
|
+
self._hooks[fullname] = True
|
|
74
|
+
|
|
75
|
+
# if conf.dev:
|
|
76
|
+
# logging.debug(fullname)
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
if find_spec:
|
|
80
|
+
spec = find_spec(fullname, path)
|
|
81
|
+
if spec and spec.loader:
|
|
82
|
+
spec.loader = _ImportHookChainedLoader(spec.loader)
|
|
83
|
+
return spec
|
|
84
|
+
else:
|
|
85
|
+
__import__(fullname)
|
|
86
|
+
return _ImportHookLoader()
|
|
87
|
+
|
|
88
|
+
except Exception as e:
|
|
89
|
+
if conf.dev:
|
|
90
|
+
print(e)
|
|
91
|
+
return
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
PLUGIN = {}
|
|
2
|
+
IMPORT_HOOKS = {}
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
DEFINITION = {
|
|
7
|
+
'plugin': [
|
|
8
|
+
('', 'instrument_plugin'),
|
|
9
|
+
],
|
|
10
|
+
'standalone': [
|
|
11
|
+
('', 'instrument_standalone_single'),
|
|
12
|
+
('', 'instrument_standalone_multiple')
|
|
13
|
+
],
|
|
14
|
+
'email.smtp': [
|
|
15
|
+
('smtplib', 'instrument_smtp'),
|
|
16
|
+
],
|
|
17
|
+
'amqp.pika': [
|
|
18
|
+
('pika.channel', 'instrument_pika'),
|
|
19
|
+
],
|
|
20
|
+
'llm.openai': [
|
|
21
|
+
('openai', 'instrument_openai', 'whatap.llm.providers.openai')
|
|
22
|
+
],
|
|
23
|
+
'llm.anthropic': [
|
|
24
|
+
('anthropic', 'instrument_anthropic', 'whatap.llm.providers.anthropic')
|
|
25
|
+
],
|
|
26
|
+
'logging': [
|
|
27
|
+
('logging.handlers', 'instrument_logging'),
|
|
28
|
+
('loguru._handler', 'instrument_loguru'),
|
|
29
|
+
],
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
'httpc.httplib': [
|
|
33
|
+
('httplib', 'instrument_httplib'),
|
|
34
|
+
('http.client', 'instrument_httplib'),
|
|
35
|
+
('httplib2', 'instrument_httplib2'),
|
|
36
|
+
],
|
|
37
|
+
'httpc.requests': [
|
|
38
|
+
('requests.sessions', 'instrument_requests'),
|
|
39
|
+
],
|
|
40
|
+
'httpc.urllib3': [
|
|
41
|
+
('urllib3.request', 'instrument_urllib3'),
|
|
42
|
+
],
|
|
43
|
+
'httpc.django': [
|
|
44
|
+
('revproxy.views', 'instrument_revproxy_views'),
|
|
45
|
+
],
|
|
46
|
+
'httpc.httpx' : [
|
|
47
|
+
('httpx', 'instrument_httpx')
|
|
48
|
+
],
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
'database.mysql': [
|
|
52
|
+
('MySQLdb', 'instrument_MySQLdb'),
|
|
53
|
+
('MySQLdb.cursors', 'instrument_MySQLdb_cursors'),
|
|
54
|
+
('pymysql', 'instrument_pymysql'),
|
|
55
|
+
('pymysql.cursors', 'instrument_pymysql_cursors'),
|
|
56
|
+
],
|
|
57
|
+
'database.psycopg2': [
|
|
58
|
+
('psycopg2', 'instrument_psycopg2'),
|
|
59
|
+
('psycopg2._psycopg', 'instrument_psycopg2_connection'),
|
|
60
|
+
('psycopg2.extensions', 'instrument_psycopg2_extensions'),
|
|
61
|
+
],
|
|
62
|
+
'database.psycopg3': [
|
|
63
|
+
('psycopg', 'instrument_psycopg'),
|
|
64
|
+
('psycopg_pool', 'instrument_psycopg_pool'),
|
|
65
|
+
],
|
|
66
|
+
|
|
67
|
+
'database.neo4j': [
|
|
68
|
+
('neo4j', 'instrument_neo4j')
|
|
69
|
+
],
|
|
70
|
+
'database.sqlite3': [
|
|
71
|
+
('sqlite3', 'instrument_sqlite3')
|
|
72
|
+
],
|
|
73
|
+
'database.cxoracle':[
|
|
74
|
+
('cx_Oracle', 'instrument_oracle_client'),
|
|
75
|
+
],
|
|
76
|
+
'database.redis': [
|
|
77
|
+
('redis', 'instrument_redis_connection'),
|
|
78
|
+
],
|
|
79
|
+
'database.mongo': [
|
|
80
|
+
('pymongo', 'instrument_mongo_client'),
|
|
81
|
+
],
|
|
82
|
+
'database.sqlalchemy': [
|
|
83
|
+
('sqlalchemy.orm.session', 'instrument_sqlalchemy'),
|
|
84
|
+
('sqlalchemy.engine.default', 'instrument_sqlalchemy_engine'),
|
|
85
|
+
('sqlalchemy.engine.create', 'instrument_sqlalchemy_engine_basic'),
|
|
86
|
+
('sqlalchemy.engine', 'instrument_sqlalchemy_engine_basic'),
|
|
87
|
+
],
|
|
88
|
+
'database.util': [
|
|
89
|
+
('', ''),
|
|
90
|
+
],
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
'application.starlette' : [
|
|
94
|
+
('starlette.websockets' , 'instrument_starlette_websocket'),
|
|
95
|
+
],
|
|
96
|
+
'application.wsgi': [
|
|
97
|
+
('', ''),
|
|
98
|
+
],
|
|
99
|
+
'application.bottle': [
|
|
100
|
+
('bottle', 'instrument'),
|
|
101
|
+
],
|
|
102
|
+
'application.cherrypy': [
|
|
103
|
+
('cherrypy', 'instrument'),
|
|
104
|
+
],
|
|
105
|
+
'application.django': [
|
|
106
|
+
('django.core.handlers.wsgi', 'instrument'),
|
|
107
|
+
('django.core.handlers.base', 'instrument_handlers_base'),
|
|
108
|
+
('django.views.generic.base', 'instrument_generic_base'),
|
|
109
|
+
('django.contrib.staticfiles.handlers', 'instrument_handlers_static'),
|
|
110
|
+
('channels.http', 'instrument_handlers_channels'),
|
|
111
|
+
|
|
112
|
+
# Django==1.10
|
|
113
|
+
('django.urls.resolvers', 'instrument_url_resolvers', False),
|
|
114
|
+
('django.urls.base', 'instrument_urls_base', False),
|
|
115
|
+
('django.core.handlers.exception', 'instrument_handlers_exception',
|
|
116
|
+
False),
|
|
117
|
+
|
|
118
|
+
],
|
|
119
|
+
'application.django_asgi': [
|
|
120
|
+
('django.core.handlers.asgi', 'instrument_asgi'),
|
|
121
|
+
],
|
|
122
|
+
'application.flask': [
|
|
123
|
+
('flask', 'instrument'),
|
|
124
|
+
],
|
|
125
|
+
'application.tornado': [
|
|
126
|
+
('tornado.web', 'instrument'),
|
|
127
|
+
],
|
|
128
|
+
'application.celery': [
|
|
129
|
+
('celery.execute.trace', 'instrument_celery_execute_trace'),
|
|
130
|
+
('celery.task.trace', 'instrument_celery_execute_trace'),
|
|
131
|
+
('celery.app.trace', 'instrument_celery_execute_trace'),
|
|
132
|
+
],
|
|
133
|
+
'application.nameko': [
|
|
134
|
+
('nameko.containers', 'instrument_nameko_spawn_worker'),
|
|
135
|
+
('spsengine.containers', 'instrument_nameko_spawn_worker'),
|
|
136
|
+
],
|
|
137
|
+
'application.graphql':[
|
|
138
|
+
#graphen-core 3.x~
|
|
139
|
+
('graphql.execution.execute','instrument_graphql'),
|
|
140
|
+
|
|
141
|
+
#graphen-core 2.x
|
|
142
|
+
('graphql.execution.executor','instrument_graphql'),
|
|
143
|
+
],
|
|
144
|
+
'application.fastapi': [
|
|
145
|
+
('fastapi.applications', 'instrument_applications'),
|
|
146
|
+
('fastapi.routing', 'instrument'),
|
|
147
|
+
('fastapi.dependencies.utils', 'instrument_util'),
|
|
148
|
+
|
|
149
|
+
],
|
|
150
|
+
'application.frappe': [
|
|
151
|
+
('frappe.app', 'instrument'),
|
|
152
|
+
],
|
|
153
|
+
'application.odoo': [
|
|
154
|
+
('odoo', 'instrument'),
|
|
155
|
+
],
|
|
156
|
+
}
|
whatap/util/__init__.py
ADDED
|
File without changes
|
whatap/util/bit_util.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
BYTE_MIN_VALUE = -128
|
|
2
|
+
BYTE_MAX_VALUE = 127
|
|
3
|
+
SHORT_MIN_VALUE = -32768
|
|
4
|
+
SHORT_MAX_VALUE = 32767
|
|
5
|
+
INT3_MIN_VALUE = -0x800000
|
|
6
|
+
INT3_MAX_VALUE = 0x007fffff
|
|
7
|
+
INT_MIN_VALUE = -0x80000000
|
|
8
|
+
INT_MAX_VALUE = 0x7fffffff
|
|
9
|
+
LONG5_MIN_VALUE = -0x8000000000
|
|
10
|
+
LONG5_MAX_VALUE = 0x0000007fffffffff
|
|
11
|
+
LONG_MIN_VALUE = -0x8000000000000000
|
|
12
|
+
LONG_MAX_VALUE = 0x7fffffffffffffff
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BitUtil(object):
|
|
16
|
+
@staticmethod
|
|
17
|
+
def composite(hkey, wkey):
|
|
18
|
+
if BYTE_MIN_VALUE <= wkey <= BYTE_MAX_VALUE:
|
|
19
|
+
return (hkey << 8) | (wkey & 0xff)
|
|
20
|
+
elif SHORT_MIN_VALUE <= wkey <= SHORT_MAX_VALUE:
|
|
21
|
+
return (hkey << 16) | (wkey & 0xffff)
|
|
22
|
+
elif INT_MIN_VALUE <= wkey <= INT_MAX_VALUE:
|
|
23
|
+
return (hkey << 32) | (wkey & 0xffffffff)
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def setHigh(src, hkey):
|
|
27
|
+
return (src & 0x00000000ffffffff) | (hkey << 32)
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def setLow(src, wkey):
|
|
31
|
+
return (src & 0xffffffff00000000) | (wkey & 0xffffffff)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def getHigh(key):
|
|
35
|
+
if SHORT_MIN_VALUE <= key <= SHORT_MAX_VALUE:
|
|
36
|
+
return ((key >> 8) % 0x100000000) & 0xff
|
|
37
|
+
elif INT_MIN_VALUE <= key <= INT_MAX_VALUE:
|
|
38
|
+
return ((key >> 16) % 0x100000000) & 0xffff
|
|
39
|
+
elif LONG_MIN_VALUE <= key <= LONG_MAX_VALUE:
|
|
40
|
+
return ((key >> 32) % 0x100000000) & 0xffffffff
|
|
41
|
+
|
|
42
|
+
@staticmethod
|
|
43
|
+
def getLow(key):
|
|
44
|
+
if SHORT_MIN_VALUE <= key <= SHORT_MAX_VALUE:
|
|
45
|
+
return key & 0xff
|
|
46
|
+
elif INT_MIN_VALUE <= key <= INT_MAX_VALUE:
|
|
47
|
+
return key & 0xffff
|
|
48
|
+
elif LONG_MIN_VALUE <= key <= LONG_MAX_VALUE:
|
|
49
|
+
return key & 0xffffffff
|
|
File without changes
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
from whatap.io.data_outputx import DataOutputX
|
|
4
|
+
from whatap.util.cardinality.murmurhash import MurMurHash
|
|
5
|
+
from whatap.util.cardinality.registerset import RegisterSet
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def getAlphaMM(p, m):
|
|
9
|
+
if p == 4:
|
|
10
|
+
return 0.673 * m * m
|
|
11
|
+
elif p == 5:
|
|
12
|
+
return 0.697 * m * m
|
|
13
|
+
elif p == 6:
|
|
14
|
+
return 0.709 * m * m
|
|
15
|
+
else:
|
|
16
|
+
return (0.7213 / (1 + 1.079 / m)) * m * m
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def linearCounting(m, V):
|
|
20
|
+
return m * math.log(m / V)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def numberOfLeadingZeros(i):
|
|
24
|
+
if not i:
|
|
25
|
+
return 32
|
|
26
|
+
|
|
27
|
+
n = 1
|
|
28
|
+
if (i % 0x100000000) >> 16 == 0:
|
|
29
|
+
n += 16
|
|
30
|
+
i <<= 16
|
|
31
|
+
if (i % 0x100000000) >> 24 == 0:
|
|
32
|
+
n += 8
|
|
33
|
+
i <<= 8
|
|
34
|
+
if (i % 0x100000000) >> 28 == 0:
|
|
35
|
+
n += 4
|
|
36
|
+
i <<= 4
|
|
37
|
+
if (i % 0x100000000) >> 30 == 0:
|
|
38
|
+
n += 2
|
|
39
|
+
i <<= 2
|
|
40
|
+
|
|
41
|
+
n -= (i % 0x100000000) >> 31
|
|
42
|
+
return n
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class HyperLogLog(object):
|
|
46
|
+
def __init__(self):
|
|
47
|
+
self.log2m = 10
|
|
48
|
+
self.registerSet = RegisterSet(1 << self.log2m)
|
|
49
|
+
m = 1 << self.log2m
|
|
50
|
+
self.alphaMM = getAlphaMM(self.log2m, m)
|
|
51
|
+
|
|
52
|
+
def offerHashed(self, hashedValue):
|
|
53
|
+
j = (hashedValue % 0x100000000) >> (32 - self.log2m)
|
|
54
|
+
r = numberOfLeadingZeros(
|
|
55
|
+
(hashedValue << self.log2m) | (1 << (self.log2m - 1)) + 1) + 1
|
|
56
|
+
return self.registerSet.updateIfGreater(j, r)
|
|
57
|
+
|
|
58
|
+
def offer(self, o):
|
|
59
|
+
x = MurMurHash.hash(o)
|
|
60
|
+
return self.offerHashed(x)
|
|
61
|
+
|
|
62
|
+
def cardinality(self):
|
|
63
|
+
registerSum = 0
|
|
64
|
+
count = self.registerSet.count
|
|
65
|
+
zeros = 0.0
|
|
66
|
+
for j, _ in enumerate(count):
|
|
67
|
+
val = self.registerSet.get(j)
|
|
68
|
+
registerSum += 1.0 / (1 << val)
|
|
69
|
+
if int(val) == 0:
|
|
70
|
+
zeros += 1
|
|
71
|
+
|
|
72
|
+
estimate = self.alphaMM * (1 / registerSum)
|
|
73
|
+
if estimate <= (5.0 / 2.0) * count:
|
|
74
|
+
return math.round(linearCounting(count, zeros))
|
|
75
|
+
else:
|
|
76
|
+
return math.round(estimate)
|
|
77
|
+
|
|
78
|
+
def getBytes(self):
|
|
79
|
+
dout = DataOutputX()
|
|
80
|
+
dout.writeInt(self.log2m)
|
|
81
|
+
dout.writeInt(self.registerSet.size)
|
|
82
|
+
for m in self.registerSet.readOnlyBits():
|
|
83
|
+
dout.writeInt(m)
|
|
84
|
+
return dout.toByteArray()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class MurMurHash(object):
|
|
2
|
+
@classmethod
|
|
3
|
+
def hash(cls, data):
|
|
4
|
+
m = 0x5bd1e995
|
|
5
|
+
r = 24
|
|
6
|
+
h = 0
|
|
7
|
+
k = (data * m) & 0xffffffff
|
|
8
|
+
k ^= (k % 0x100000000) >> r
|
|
9
|
+
h ^= (k * m) & 0xffffffff
|
|
10
|
+
|
|
11
|
+
k = ((data >> 32) * m) & 0xffffffff
|
|
12
|
+
k ^= (k % 0x100000000) >> r
|
|
13
|
+
h *= m
|
|
14
|
+
h ^= k * m
|
|
15
|
+
|
|
16
|
+
h ^= (h % 0x100000000) >> 13
|
|
17
|
+
h *= m
|
|
18
|
+
h ^= (h % 0x100000000) >> 15
|
|
19
|
+
|
|
20
|
+
return h
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
LOG2_BITS_PER_WORD = 6
|
|
2
|
+
REGISTER_SIZE = 5
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def getBits(count):
|
|
6
|
+
return int(count / LOG2_BITS_PER_WORD)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def getSizeForCount(count):
|
|
10
|
+
bits = getBits(count)
|
|
11
|
+
if not bits:
|
|
12
|
+
return 1
|
|
13
|
+
elif not (bits % 32):
|
|
14
|
+
return bits
|
|
15
|
+
else:
|
|
16
|
+
return bits + 1
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class RegisterSet(object):
|
|
20
|
+
def __init__(self, count):
|
|
21
|
+
self.count = count
|
|
22
|
+
self.M = [0 for _ in range(getSizeForCount(self.count))]
|
|
23
|
+
self.size = len(self.M)
|
|
24
|
+
|
|
25
|
+
def set(self, position, value):
|
|
26
|
+
bucketPos = int(position / LOG2_BITS_PER_WORD)
|
|
27
|
+
shift = REGISTER_SIZE * (position - (bucketPos * LOG2_BITS_PER_WORD))
|
|
28
|
+
self.M[bucketPos] = (
|
|
29
|
+
self.M[bucketPos] & ~(0x1f << shift) | (value << shift))
|
|
30
|
+
|
|
31
|
+
def get(self, position):
|
|
32
|
+
bucketPos = int(position / LOG2_BITS_PER_WORD)
|
|
33
|
+
shift = REGISTER_SIZE * (position - (bucketPos * LOG2_BITS_PER_WORD))
|
|
34
|
+
return ((self.M[bucketPos] & (0x1f << shift)) % 0x100000000) >> shift
|
|
35
|
+
|
|
36
|
+
def updateIfGreater(self, position, value):
|
|
37
|
+
bucket = int(position / LOG2_BITS_PER_WORD)
|
|
38
|
+
shift = REGISTER_SIZE * (position - (bucket * LOG2_BITS_PER_WORD))
|
|
39
|
+
mask = 0x1f << shift
|
|
40
|
+
|
|
41
|
+
curVal = self.M[bucket] & mask
|
|
42
|
+
newVal = value << shift
|
|
43
|
+
if curVal < newVal:
|
|
44
|
+
self.M[bucket] = (self.M[bucket] & ~mask) | newVal
|
|
45
|
+
return True
|
|
46
|
+
else:
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
def merge(self, that):
|
|
50
|
+
for bucket, m in enumerate(self.M):
|
|
51
|
+
word = 0
|
|
52
|
+
for j in range(LOG2_BITS_PER_WORD):
|
|
53
|
+
mask = 0x1f << (REGISTER_SIZE * j)
|
|
54
|
+
thisVal = (self.M[bucket] & mask)
|
|
55
|
+
thatVal = (that.M[bucket] & mask)
|
|
56
|
+
word |= thatVal if thisVal < thatVal else thisVal
|
|
57
|
+
self.M[bucket] = word
|
|
58
|
+
|
|
59
|
+
def readOnlyBits(self):
|
|
60
|
+
return self.M
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class CompareUtil(object):
|
|
2
|
+
|
|
3
|
+
@staticmethod
|
|
4
|
+
def compareTo(l, r):
|
|
5
|
+
if not l and not r:
|
|
6
|
+
return 0
|
|
7
|
+
elif not l:
|
|
8
|
+
return -1
|
|
9
|
+
elif not r:
|
|
10
|
+
return 1
|
|
11
|
+
|
|
12
|
+
l_ln = len(l)
|
|
13
|
+
r_ln = len(r)
|
|
14
|
+
for i in range(l_ln):
|
|
15
|
+
if l[i] > r[i]:
|
|
16
|
+
return 1
|
|
17
|
+
if l[i] < r[i]:
|
|
18
|
+
return -1
|
|
19
|
+
return l_ln - r_ln
|
whatap/util/date_util.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DateUtil(object):
|
|
7
|
+
delta = 0
|
|
8
|
+
|
|
9
|
+
MILLIS_PER_SECOND = 1000
|
|
10
|
+
MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND
|
|
11
|
+
MILLIS_PER_FIVE_MINUTE = 5 * 60 * MILLIS_PER_SECOND
|
|
12
|
+
MILLIS_PER_TEN_MINUTE = 10 * MILLIS_PER_MINUTE
|
|
13
|
+
MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE
|
|
14
|
+
MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
def setServerTime(cls, time, syncfactor):
|
|
18
|
+
now = cls.now()
|
|
19
|
+
delta = time - now
|
|
20
|
+
if delta:
|
|
21
|
+
delta *= syncfactor
|
|
22
|
+
cls.delta = delta
|
|
23
|
+
return cls.delta
|
|
24
|
+
|
|
25
|
+
@classmethod
|
|
26
|
+
def currentTime(cls):
|
|
27
|
+
return int(round(time.time() * 1000)) + cls.delta
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def getServerDelta(cls):
|
|
31
|
+
return cls.delta
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def now(cls):
|
|
35
|
+
return cls.currentTime()
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
def nowSystem(cls):
|
|
39
|
+
return int(round(time.time() * 1000))
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
def getFiveMinUnit(cls):
|
|
43
|
+
return int(int(
|
|
44
|
+
cls.currentTime() / cls.MILLIS_PER_FIVE_MINUTE) * cls.MILLIS_PER_FIVE_MINUTE)
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def datetime(cls):
|
|
48
|
+
return datetime.now()
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def yyyymmdd(cls, time=None):
|
|
52
|
+
if not time:
|
|
53
|
+
time = cls.currentTime()
|
|
54
|
+
return datetime \
|
|
55
|
+
.fromtimestamp(time / 1000).strftime('%Y%m%d')
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import threading, traceback, time, sys
|
|
2
|
+
from datetime import datetime, timedelta
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def dump_stack(thread_id,output_path, timeout):
|
|
6
|
+
with open(output_path,'a+') as f:
|
|
7
|
+
started = datetime.now()
|
|
8
|
+
while datetime.now() - started < timedelta(seconds=timeout):
|
|
9
|
+
frame = sys._current_frames().get(thread_id)
|
|
10
|
+
if not frame:
|
|
11
|
+
return
|
|
12
|
+
f.write(str(datetime.now()))
|
|
13
|
+
f.write('\n')
|
|
14
|
+
for stack in traceback.extract_stack(frame):
|
|
15
|
+
line = stack[0]
|
|
16
|
+
line_num = stack[1]
|
|
17
|
+
method_name = stack[2]
|
|
18
|
+
|
|
19
|
+
stack = '{} ({}:{})\n'.format(method_name, line, line_num)
|
|
20
|
+
f.write(stack)
|
|
21
|
+
f.write('\n')
|
|
22
|
+
time.sleep(0.5)
|
|
23
|
+
|
|
24
|
+
def dumpThreadStack(timeout, output_path):
|
|
25
|
+
thread_id = threading.get_ident()
|
|
26
|
+
|
|
27
|
+
thr = threading.Thread(target=dump_stack, args=(thread_id,output_path, timeout), kwargs={})
|
|
28
|
+
thr.setDaemon(True)
|
|
29
|
+
thr.start()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def printStack():
|
|
33
|
+
thread_id = threading.get_ident()
|
|
34
|
+
|
|
35
|
+
frame = sys._current_frames().get(thread_id)
|
|
36
|
+
if not frame:
|
|
37
|
+
return
|
|
38
|
+
import io
|
|
39
|
+
f = io.StringIO()
|
|
40
|
+
f.write(str(datetime.now()))
|
|
41
|
+
f.write('\n')
|
|
42
|
+
for stack in traceback.extract_stack(frame):
|
|
43
|
+
line = stack[0]
|
|
44
|
+
line_num = stack[1]
|
|
45
|
+
method_name = stack[2]
|
|
46
|
+
|
|
47
|
+
stack = '{} ({}:{})\n'.format(method_name, line, line_num)
|
|
48
|
+
f.write(stack)
|
|
49
|
+
f.write('\n')
|
|
50
|
+
print(f.getvalue())
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def printAllStack():
|
|
54
|
+
for t in threading.enumerate():
|
|
55
|
+
thread_id = t.ident
|
|
56
|
+
|
|
57
|
+
frame = sys._current_frames().get(thread_id)
|
|
58
|
+
if not frame:
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
import io
|
|
62
|
+
f = io.StringIO()
|
|
63
|
+
f.write(str(datetime.now()))
|
|
64
|
+
f.write('\n')
|
|
65
|
+
for stack in traceback.extract_stack(frame):
|
|
66
|
+
line = stack[0]
|
|
67
|
+
line_num = stack[1]
|
|
68
|
+
method_name = stack[2]
|
|
69
|
+
|
|
70
|
+
stack = '{} ({}:{})\n'.format(method_name, line, line_num)
|
|
71
|
+
f.write(stack)
|
|
72
|
+
f.write('\n')
|
|
73
|
+
print(f.getvalue())
|