whatap-python 0.1.118__tar.gz → 0.3.35__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.
- whatap_python-0.3.35/PKG-INFO +143 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/__init__.py +169 -98
- whatap_python-0.3.35/whatap/agent/darwin/amd64/whatap_python +0 -0
- whatap_python-0.3.35/whatap/agent/darwin/arm64/whatap_python +0 -0
- whatap_python-0.3.35/whatap/agent/linux/amd64/whatap_python +0 -0
- {whatap-python-0.1.118/whatap/agent/darwin/amd64 → whatap_python-0.3.35/whatap/agent/linux/arm64}/whatap_python +0 -0
- whatap_python-0.3.35/whatap/bootstrap/sitecustomize.py +19 -0
- whatap_python-0.3.35/whatap/build.py +4 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/conf/configuration.py +9 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/conf/configure.py +19 -2
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/io/data_outputx.py +4 -0
- whatap_python-0.3.35/whatap/net/async_sender.py +64 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/net/packet_enum.py +1 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/net/packet_type_enum.py +3 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/net/param_def.py +1 -0
- whatap_python-0.3.35/whatap/net/stackhelper.py +86 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/net/udp_session.py +115 -44
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/net/udp_thread.py +18 -2
- whatap_python-0.3.35/whatap/pack/logSinkPack.py +77 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/pack/pack_enum.py +2 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/scripts/__init__.py +15 -2
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/amqp_kombu.py +2 -2
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/amqp_pika.py +2 -2
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_django.py +67 -9
- whatap_python-0.3.35/whatap/trace/mod/application_django_py3.py +249 -0
- whatap_python-0.3.35/whatap/trace/mod/application_fastapi.py +420 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_flask.py +3 -3
- whatap_python-0.3.35/whatap/trace/mod/application_frappe.py +222 -0
- whatap_python-0.3.35/whatap/trace/mod/application_graphql.py +141 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_nameko.py +1 -1
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_wsgi.py +146 -91
- whatap_python-0.3.35/whatap/trace/mod/database_mongo.py +167 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/database_mysql.py +5 -4
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/database_redis.py +5 -5
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/database_toolkit.py +98 -9
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/email_smtp.py +3 -3
- whatap_python-0.3.35/whatap/trace/mod/logging.py +117 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/plugin.py +2 -2
- whatap_python-0.3.35/whatap/trace/simple_trace_context.py +9 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/trace_context.py +6 -2
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/trace_context_manager.py +86 -23
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/trace_import.py +17 -9
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/trace_module_definition.py +25 -0
- whatap_python-0.3.35/whatap/util/debug_util.py +73 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/ip_util.py +0 -1
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/linked_map.py +4 -25
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/throttle_util.py +3 -6
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/userid_util.py +6 -3
- whatap_python-0.3.35/whatap_python.egg-info/PKG-INFO +143 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap_python.egg-info/SOURCES.txt +11 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap_python.egg-info/entry_points.txt +0 -1
- whatap-python-0.1.118/PKG-INFO +0 -144
- whatap-python-0.1.118/whatap/agent/darwin/arm64/whatap_python +0 -0
- whatap-python-0.1.118/whatap/agent/linux/amd64/whatap_python +0 -0
- whatap-python-0.1.118/whatap/agent/linux/arm64/whatap_python +0 -0
- whatap-python-0.1.118/whatap/bootstrap/sitecustomize.py +0 -2
- whatap-python-0.1.118/whatap/build.py +0 -4
- whatap-python-0.1.118/whatap_python.egg-info/PKG-INFO +0 -144
- {whatap-python-0.1.118 → whatap_python-0.3.35}/README.md +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/setup.cfg +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/setup.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/LICENSE +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/README.rst +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/__main__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/bootstrap/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/conf/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/conf/license.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/control/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/io/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/io/data_inputx.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/net/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/pack/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/pack/pack.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_bottle.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_celery.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_cherrypy.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/application_tornado.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/database_postgresql.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/httpc_django.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/httpc_httplib.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/httpc_requests.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/trace/mod/httpc_urllib3.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/bit_util.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/cardinality/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/cardinality/hyperloglog.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/cardinality/murmurhash.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/cardinality/registerset.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/compare_util.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/date_util.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/escape_literal_sql.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/hash_util.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/hexa32.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/int_set.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/keygen.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/linked_list.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/metering_util.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/request_double_queue.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/request_queue.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/util/string_util.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/__init__.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/blob_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/boolean_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/decimal_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/double_summary.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/double_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/float_array.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/float_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/int_array.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/ip4_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/list_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/long_array.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/long_summary.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/map_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/null_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/number_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/summary_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/text_array.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/text_hash_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/text_value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/value.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/value/value_enum.py +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap/whatap.conf +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap_python.egg-info/dependency_links.txt +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap_python.egg-info/not-zip-safe +0 -0
- {whatap-python-0.1.118 → whatap_python-0.3.35}/whatap_python.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: whatap-python
|
|
3
|
+
Version: 0.3.35
|
|
4
|
+
Summary: Monitoring and Profiling Service
|
|
5
|
+
Home-page: https://www.whatap.io
|
|
6
|
+
Author: whatap
|
|
7
|
+
Author-email: admin@whatap.io
|
|
8
|
+
License: Whatap License
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
.. image:: https://www.whatap.io/img/common/whatap_logo_re.svg
|
|
12
|
+
|
|
13
|
+
.. _WhaTap: https://www.whatap.io/
|
|
14
|
+
|
|
15
|
+
WhaTap_ for python
|
|
16
|
+
==================
|
|
17
|
+
|
|
18
|
+
- Whatap allows for application performance monitoring.
|
|
19
|
+
- Support: WSGI server application & Batch job & Specific method profiling.
|
|
20
|
+
- Python version : 2.7 + & 3.3+
|
|
21
|
+
|
|
22
|
+
Installation
|
|
23
|
+
------------
|
|
24
|
+
|
|
25
|
+
.. code:: bash
|
|
26
|
+
|
|
27
|
+
$ pip install whatap-python
|
|
28
|
+
|
|
29
|
+
Application Monitoring
|
|
30
|
+
----------------------
|
|
31
|
+
|
|
32
|
+
Supported web frameworks such as Django, Flask, Bottle, Cherrypy, Tornado and WSGI Server Application.
|
|
33
|
+
|
|
34
|
+
Configuration
|
|
35
|
+
~~~~~~~~~~~~~
|
|
36
|
+
|
|
37
|
+
.. code:: bash
|
|
38
|
+
|
|
39
|
+
$ export WHATAP_HOME=[PATH]
|
|
40
|
+
$ whatap-setting-config --host [HOST_ADDR]
|
|
41
|
+
--license [LICENSE_KEY]
|
|
42
|
+
--app_name [APPLICATION_NAME]
|
|
43
|
+
--app_process_name [APP_PROCESS_NAME]
|
|
44
|
+
|
|
45
|
+
Usage
|
|
46
|
+
~~~~~
|
|
47
|
+
|
|
48
|
+
.. code:: bash
|
|
49
|
+
|
|
50
|
+
$ whatap-start-agent [YOUR_APPLICATION_START_COMMAND]
|
|
51
|
+
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
Unsupported web frameworks WSGI
|
|
55
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
56
|
+
|
|
57
|
+
If you want WSGI Application monitoring, include the @register_app decorator.
|
|
58
|
+
|
|
59
|
+
.. code:: python
|
|
60
|
+
|
|
61
|
+
import whatap
|
|
62
|
+
|
|
63
|
+
@whatap.register_app
|
|
64
|
+
def simple_app(environ, start_response):
|
|
65
|
+
"""Simplest possible application object"""
|
|
66
|
+
status = '200 OK'
|
|
67
|
+
response_headers = [('Content-type', 'text/plain')]
|
|
68
|
+
start_response(status, response_headers)
|
|
69
|
+
return ['Hello world!\n']
|
|
70
|
+
|
|
71
|
+
Method Profiling
|
|
72
|
+
~~~~~~~~~~~~~~~~
|
|
73
|
+
|
|
74
|
+
If you want method profiling, include the @method_profiling decorator.
|
|
75
|
+
|
|
76
|
+
.. code:: python
|
|
77
|
+
|
|
78
|
+
from whatap import method_profiling
|
|
79
|
+
|
|
80
|
+
@method_profiling
|
|
81
|
+
def db_connection():
|
|
82
|
+
db.connect('mysql:// ..')
|
|
83
|
+
|
|
84
|
+
@method_profiling
|
|
85
|
+
def query():
|
|
86
|
+
db.select('select * from ..')
|
|
87
|
+
|
|
88
|
+
....
|
|
89
|
+
|
|
90
|
+
Batch Monitoring
|
|
91
|
+
----------------
|
|
92
|
+
|
|
93
|
+
for Batch job.
|
|
94
|
+
|
|
95
|
+
Configuration
|
|
96
|
+
~~~~~~~~~~~~~
|
|
97
|
+
|
|
98
|
+
Set Environment valiable configuration.
|
|
99
|
+
|
|
100
|
+
.. code:: bash
|
|
101
|
+
|
|
102
|
+
$ export WHATAP_BATCH_HOME=[PATH]
|
|
103
|
+
$ cat >> $WHATAP_BATCH_HOME/whatap.conf << EOF
|
|
104
|
+
license=[LICENSE_KEY]
|
|
105
|
+
whatap.server.host=[HOST_ADDR]
|
|
106
|
+
|
|
107
|
+
app_name=batch
|
|
108
|
+
app_process_name=batch
|
|
109
|
+
EOF
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
Usage
|
|
113
|
+
~~~~~
|
|
114
|
+
|
|
115
|
+
Start bach agent.
|
|
116
|
+
|
|
117
|
+
.. code:: bash
|
|
118
|
+
|
|
119
|
+
$ whatap-start-batch
|
|
120
|
+
|
|
121
|
+
Example code
|
|
122
|
+
~~~~~~~~~~~~
|
|
123
|
+
|
|
124
|
+
.. code:: python
|
|
125
|
+
|
|
126
|
+
from whatap import method_profiling
|
|
127
|
+
|
|
128
|
+
class Command(BaseCommand):
|
|
129
|
+
|
|
130
|
+
@batch_profiling
|
|
131
|
+
def handle(self, *args, **options):
|
|
132
|
+
// batch code..
|
|
133
|
+
....
|
|
134
|
+
|
|
135
|
+
Restart
|
|
136
|
+
-------
|
|
137
|
+
|
|
138
|
+
Your Application restart.
|
|
139
|
+
|
|
140
|
+
Copyright
|
|
141
|
+
---------
|
|
142
|
+
|
|
143
|
+
Copyright (c) 2017 Whatap, Inc. All rights reserved.
|
|
@@ -2,7 +2,7 @@ import logging as logging_module
|
|
|
2
2
|
import os
|
|
3
3
|
import platform
|
|
4
4
|
import sys
|
|
5
|
-
import subprocess
|
|
5
|
+
import subprocess, signal
|
|
6
6
|
import time
|
|
7
7
|
from whatap import build
|
|
8
8
|
from whatap.util.date_util import DateUtil
|
|
@@ -39,12 +39,21 @@ class ContextFilter(logging_module.Filter):
|
|
|
39
39
|
record.id = ''
|
|
40
40
|
return True
|
|
41
41
|
|
|
42
|
+
|
|
42
43
|
|
|
43
44
|
from whatap.conf.configure import Configure as conf
|
|
44
|
-
|
|
45
45
|
CONFIG_FILE_NAME = 'whatap.conf'
|
|
46
46
|
LOG_FILE_NAME = 'whatap-hook.log'
|
|
47
47
|
|
|
48
|
+
isFrappeCommands = "get-frappe-commands" in sys.argv if hasattr(sys, "argv") else False
|
|
49
|
+
|
|
50
|
+
def whatap_print(*args):
|
|
51
|
+
if isFrappeCommands:
|
|
52
|
+
logging.info(*args)
|
|
53
|
+
else:
|
|
54
|
+
if len(args) > 0:
|
|
55
|
+
message = " ".join(args)
|
|
56
|
+
print(message)
|
|
48
57
|
|
|
49
58
|
class Logger(object):
|
|
50
59
|
def __init__(self):
|
|
@@ -62,8 +71,8 @@ class Logger(object):
|
|
|
62
71
|
os.mkdir(os.environ['WHATAP_LOGS'])
|
|
63
72
|
|
|
64
73
|
except Exception as e:
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
whatap_print('WHATAP: LOG FILE WRITE ERROR.')
|
|
75
|
+
whatap_print(
|
|
67
76
|
'WHATAP: Try to execute command. \n {}'.format(
|
|
68
77
|
'sudo mkdir -m 777 -p $WHATAP_HOME/logs`'))
|
|
69
78
|
|
|
@@ -86,7 +95,7 @@ class Logger(object):
|
|
|
86
95
|
|
|
87
96
|
self.logger.setLevel(logging_module.DEBUG)
|
|
88
97
|
except Exception as e:
|
|
89
|
-
|
|
98
|
+
whatap_print('WHATAP: LOGGING ERROR: {}'.format(e))
|
|
90
99
|
else:
|
|
91
100
|
self.print_whatap()
|
|
92
101
|
|
|
@@ -105,7 +114,7 @@ class Logger(object):
|
|
|
105
114
|
os.environ['WHATAP_CONFIG']))
|
|
106
115
|
str += '{0}: {1}\n\n'.format('Logs', os.environ['WHATAP_LOGS'])
|
|
107
116
|
|
|
108
|
-
|
|
117
|
+
whatap_print(str)
|
|
109
118
|
logging.debug(str)
|
|
110
119
|
|
|
111
120
|
|
|
@@ -113,7 +122,7 @@ def read_file(home, file_name):
|
|
|
113
122
|
data = ''
|
|
114
123
|
try:
|
|
115
124
|
f = open(os.path.join(os.environ.get(home), file_name), 'r+')
|
|
116
|
-
data = f.readline()
|
|
125
|
+
data = str(f.readline()).strip()
|
|
117
126
|
f.close()
|
|
118
127
|
finally:
|
|
119
128
|
return data
|
|
@@ -125,8 +134,8 @@ def write_file(home, file_name, value):
|
|
|
125
134
|
f.write(value)
|
|
126
135
|
f.close()
|
|
127
136
|
except Exception as e:
|
|
128
|
-
|
|
129
|
-
|
|
137
|
+
whatap_print('WHATAP: WHATAP HOME ERROR. (path: {})'.format(os.path.join(os.environ.get(home))))
|
|
138
|
+
whatap_print(
|
|
130
139
|
'WHATAP: Try to execute command. \n {}'.format(
|
|
131
140
|
'`sudo chmod -R 777 $WHATAP_HOME`'))
|
|
132
141
|
return False
|
|
@@ -137,7 +146,7 @@ def write_file(home, file_name, value):
|
|
|
137
146
|
def check_whatap_home(target='WHATAP_HOME'):
|
|
138
147
|
whatap_home = os.environ.get(target)
|
|
139
148
|
if not whatap_home:
|
|
140
|
-
|
|
149
|
+
whatap_print('WHATAP: ${} is empty'.format(target))
|
|
141
150
|
|
|
142
151
|
return whatap_home
|
|
143
152
|
|
|
@@ -150,10 +159,10 @@ def init_config(home):
|
|
|
150
159
|
whatap_home = os.getcwd()
|
|
151
160
|
os.environ[home] = whatap_home
|
|
152
161
|
|
|
153
|
-
|
|
154
|
-
|
|
162
|
+
whatap_print('WHATAP: WHATAP_HOME is empty')
|
|
163
|
+
whatap_print(
|
|
155
164
|
'WHATAP: WHATAP_HOME set default CURRENT_WORKING_DIRECTORY value')
|
|
156
|
-
|
|
165
|
+
whatap_print('CURRENT_WORKING_DIRECTORY is {}\n'.format(whatap_home))
|
|
157
166
|
|
|
158
167
|
if not write_file(home, home.lower(), whatap_home):
|
|
159
168
|
return False
|
|
@@ -172,8 +181,8 @@ def init_config(home):
|
|
|
172
181
|
with open(config_file, 'w+') as new_f:
|
|
173
182
|
new_f.write(content)
|
|
174
183
|
except Exception as e:
|
|
175
|
-
|
|
176
|
-
|
|
184
|
+
whatap_print('WHATAP: PERMISSION ERROR: {}'.format(e))
|
|
185
|
+
whatap_print(
|
|
177
186
|
'WHATAP: Try to execute command. \n {}'.format(
|
|
178
187
|
'`sudo chmod -R 777 $WHATAP_HOME`'))
|
|
179
188
|
return False
|
|
@@ -184,7 +193,6 @@ def init_config(home):
|
|
|
184
193
|
def update_config(home, opt_key, opt_value):
|
|
185
194
|
config_file = os.path.join(os.environ[home],
|
|
186
195
|
CONFIG_FILE_NAME)
|
|
187
|
-
|
|
188
196
|
try:
|
|
189
197
|
with open(config_file, 'r+') as f:
|
|
190
198
|
is_update = False
|
|
@@ -198,11 +206,11 @@ def update_config(home, opt_key, opt_value):
|
|
|
198
206
|
|
|
199
207
|
content += line
|
|
200
208
|
if not is_update:
|
|
201
|
-
content += '{0}={1}\n'.format(opt_key, opt_value)
|
|
209
|
+
content += '\n{0}={1}\n'.format(opt_key, opt_value)
|
|
202
210
|
open(config_file, 'w+').write(content)
|
|
203
211
|
|
|
204
212
|
except Exception as e:
|
|
205
|
-
|
|
213
|
+
whatap_print('WHATAP: OPTION ERROR: {}'.format(e))
|
|
206
214
|
|
|
207
215
|
|
|
208
216
|
def config(home):
|
|
@@ -241,9 +249,13 @@ def hooks(home):
|
|
|
241
249
|
logging.debug(e, extra={'id': 'MODULE ERROR'})
|
|
242
250
|
finally:
|
|
243
251
|
try:
|
|
252
|
+
if conf.trace_logging_enabled:
|
|
253
|
+
logging_module = sys.modules.get("logging")
|
|
254
|
+
from whatap.trace.mod.logging import instrument_logging
|
|
255
|
+
instrument_logging(logging_module)
|
|
256
|
+
|
|
244
257
|
if conf.hook_method_patterns:
|
|
245
258
|
from whatap.trace.mod.plugin import instrument_plugin
|
|
246
|
-
|
|
247
259
|
patterns = conf.hook_method_patterns.split(',')
|
|
248
260
|
for pattern in patterns:
|
|
249
261
|
pattern=pattern.strip()
|
|
@@ -281,47 +293,18 @@ def agent():
|
|
|
281
293
|
whatap_home = os.getcwd()
|
|
282
294
|
os.environ[home] = whatap_home
|
|
283
295
|
|
|
284
|
-
|
|
285
|
-
|
|
296
|
+
whatap_print('WHATAP: WHATAP_HOME is empty')
|
|
297
|
+
whatap_print(
|
|
286
298
|
'WHATAP: WHATAP_HOME set default CURRENT_WORKING_DIRECTORY value')
|
|
287
|
-
|
|
299
|
+
whatap_print('CURRENT_WORKING_DIRECTORY is {}\n'.format(whatap_home))
|
|
288
300
|
|
|
289
301
|
if write_file(home, home.lower(), whatap_home):
|
|
290
302
|
os.environ['WHATAP_HOME'] = whatap_home
|
|
291
303
|
|
|
292
|
-
t = threading.Thread(target=go)
|
|
293
|
-
t.setDaemon(True)
|
|
294
|
-
t.start()
|
|
304
|
+
# t = threading.Thread(target=go)
|
|
305
|
+
# t.setDaemon(True)
|
|
306
|
+
# t.start()
|
|
295
307
|
config(home)
|
|
296
|
-
#startWhatapThread()
|
|
297
|
-
|
|
298
|
-
def startWhatapThread():
|
|
299
|
-
def __whatap_jobs():
|
|
300
|
-
from whatap.conf.configure import Configure as conf
|
|
301
|
-
from whatap.net.udp_session import UdpSession
|
|
302
|
-
UdpSession.read_timeout = conf.session_read_timeout
|
|
303
|
-
UdpSession.udp()
|
|
304
|
-
|
|
305
|
-
def __udp_recv():
|
|
306
|
-
UdpSession.get()
|
|
307
|
-
|
|
308
|
-
def __config_load():
|
|
309
|
-
now = time.time()
|
|
310
|
-
if now - conf.last_loaded > conf.init_load_interval / 1000:
|
|
311
|
-
conf.init(False)
|
|
312
|
-
|
|
313
|
-
while True:
|
|
314
|
-
for job in (__udp_recv, __config_load):
|
|
315
|
-
try:
|
|
316
|
-
job()
|
|
317
|
-
time.sleep(0)
|
|
318
|
-
except Exception as e:
|
|
319
|
-
logging.debug(e, extra={'id': 'WA914'}, exc_info=True)
|
|
320
|
-
time.sleep(0.05)
|
|
321
|
-
|
|
322
|
-
t = threading.Thread(target=__whatap_jobs)
|
|
323
|
-
t.setDaemon(True)
|
|
324
|
-
t.start()
|
|
325
308
|
|
|
326
309
|
ARCH = {
|
|
327
310
|
'x86_64': 'amd64',
|
|
@@ -329,27 +312,27 @@ ARCH = {
|
|
|
329
312
|
'x86_32': '386',
|
|
330
313
|
'ARM': 'arm',
|
|
331
314
|
'AArch64': 'arm64',
|
|
315
|
+
'arm64': 'arm64',
|
|
316
|
+
'aarch64': 'arm64'
|
|
332
317
|
}
|
|
333
318
|
|
|
334
319
|
AGENT_NAME = 'whatap_python'
|
|
335
320
|
|
|
336
321
|
|
|
337
|
-
def go(batch=False):
|
|
338
|
-
os.environ['WHATAP_VERSION'] = build.version
|
|
339
|
-
|
|
340
|
-
os.environ['whatap.start'] = str(DateUtil.now())
|
|
341
|
-
|
|
342
|
-
os.environ['python.uptime'] = str(DateUtil.datetime())
|
|
343
|
-
os.environ['python.version'] = sys.version
|
|
344
|
-
os.environ['python.tzname'] = time.tzname[0]
|
|
345
322
|
|
|
346
|
-
|
|
347
|
-
os.environ
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
323
|
+
def go(batch=False, opts={}):
|
|
324
|
+
newenv=os.environ.copy()
|
|
325
|
+
newenv['WHATAP_VERSION'] = build.version
|
|
326
|
+
newenv['whatap.start'] = str(DateUtil.now())
|
|
327
|
+
newenv['python.uptime'] = str(DateUtil.datetime())
|
|
328
|
+
newenv['python.version'] = sys.version
|
|
329
|
+
newenv['python.tzname'] = time.tzname[0]
|
|
330
|
+
newenv['os.release'] = platform.release()
|
|
331
|
+
newenv['sys.version_info'] = str(sys.version_info)
|
|
332
|
+
newenv['sys.executable'] = sys.executable
|
|
333
|
+
newenv['sys.path'] = str(sys.path)
|
|
334
|
+
newenv.update(opts)
|
|
335
|
+
|
|
353
336
|
if not batch:
|
|
354
337
|
home = 'WHATAP_HOME'
|
|
355
338
|
file_name = AGENT_NAME + '.pid'
|
|
@@ -357,43 +340,52 @@ def go(batch=False):
|
|
|
357
340
|
home = 'WHATAP_HOME_BATCH'
|
|
358
341
|
file_name = AGENT_NAME + '.pid.batch'
|
|
359
342
|
|
|
360
|
-
def get_pname(
|
|
361
|
-
|
|
362
|
-
|
|
343
|
+
def get_pname(pid):
|
|
344
|
+
cmdlinepath = os.path.join('/proc', str(pid), 'cmdline')
|
|
345
|
+
if os.path.exists(cmdlinepath):
|
|
346
|
+
with open(cmdlinepath) as f:
|
|
347
|
+
content = f.read()
|
|
348
|
+
if content:
|
|
349
|
+
return content.strip()
|
|
350
|
+
return ''
|
|
363
351
|
pid = read_file(home, file_name)
|
|
364
|
-
if pid and 'whatap_python'
|
|
365
|
-
|
|
352
|
+
if pid and get_pname(pid).find('whatap_python') >= 0:
|
|
353
|
+
os.kill(int(pid), signal.SIGKILL)
|
|
354
|
+
|
|
366
355
|
try:
|
|
367
|
-
|
|
368
|
-
if os.path.exists(os.path.join(
|
|
369
|
-
os.remove(os.path.join(
|
|
356
|
+
home_path= os.environ.get(home)
|
|
357
|
+
if os.path.exists(os.path.join(home_path, AGENT_NAME)):
|
|
358
|
+
os.remove(os.path.join(home_path, AGENT_NAME))
|
|
370
359
|
|
|
371
360
|
source_cwd = os.path.join(os.path.join(os.path.dirname(__file__), 'agent'), platform.system().lower(),
|
|
372
361
|
ARCH[platform.machine()])
|
|
373
362
|
|
|
374
|
-
|
|
375
363
|
os.symlink(os.path.join(source_cwd, AGENT_NAME),
|
|
376
|
-
os.path.join(
|
|
377
|
-
|
|
378
|
-
os.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
364
|
+
os.path.join(home_path, AGENT_NAME))
|
|
365
|
+
|
|
366
|
+
sockfile_path = os.path.join(home_path, 'run')
|
|
367
|
+
if not os.path.exists(sockfile_path):
|
|
368
|
+
os.mkdir(sockfile_path)
|
|
369
|
+
newenv['whatap.enabled'] = 'True'
|
|
370
|
+
newenv['WHATAP_PID_FILE'] = file_name
|
|
371
|
+
newenv['PYTHON_PARENT_APP_PID'] = str(os.getpid())
|
|
372
|
+
process = subprocess.Popen(['./{0}'.format(AGENT_NAME), '-t', '3', '-d', '1'],
|
|
373
|
+
cwd=home_path,env=newenv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
374
|
+
stdouts, errs = process.communicate()
|
|
375
|
+
whatap_print("executed golang module ", str(stdouts,"utf8"), str(errs, "utf8"))
|
|
385
376
|
except Exception as e:
|
|
386
|
-
|
|
377
|
+
import traceback
|
|
378
|
+
traceback.print_exc()
|
|
379
|
+
whatap_print('WHATAP: AGENT ERROR: {}'.format(e))
|
|
387
380
|
else:
|
|
388
|
-
|
|
389
|
-
|
|
381
|
+
whatap_print('WHATAP: AGENT UP! (process name: {})\n'.format(AGENT_NAME))
|
|
390
382
|
|
|
391
383
|
import signal
|
|
392
384
|
|
|
393
385
|
from whatap.trace.mod.application_wsgi import interceptor, start_interceptor, \
|
|
394
|
-
end_interceptor, trace_handler
|
|
395
|
-
|
|
396
|
-
from whatap.trace.trace_context import TraceContext
|
|
386
|
+
end_interceptor, trace_handler, interceptor_step_error
|
|
387
|
+
from whatap.trace.mod.application_fastapi import interceptor_error_log
|
|
388
|
+
from whatap.trace.trace_context import TraceContext, TraceContextManager
|
|
397
389
|
|
|
398
390
|
def register_app(fn):
|
|
399
391
|
@trace_handler(fn, True)
|
|
@@ -420,14 +412,18 @@ def method_profiling(fn):
|
|
|
420
412
|
try:
|
|
421
413
|
ctx = TraceContext()
|
|
422
414
|
ctx.service_name=fn.__name__
|
|
423
|
-
|
|
415
|
+
start_interceptor(ctx)
|
|
424
416
|
callback = fn(*args, **kwargs)
|
|
425
|
-
end_interceptor(thread_id= ctx.thread_id)
|
|
426
417
|
except Exception as e:
|
|
418
|
+
ctx = TraceContextManager.getLocalContext()
|
|
419
|
+
interceptor_step_error(e, ctx=ctx)
|
|
420
|
+
interceptor_error_log(ctx.id, e, fn, args, kwargs)
|
|
427
421
|
logging.debug('WHATAP(@method_profiling): ' + str(e),
|
|
428
422
|
extra={'id': 'WA776'}, exc_info=True)
|
|
429
423
|
finally:
|
|
430
|
-
|
|
424
|
+
ctx = TraceContextManager.getLocalContext()
|
|
425
|
+
end_interceptor(ctx=ctx)
|
|
426
|
+
return callback
|
|
431
427
|
|
|
432
428
|
if not os.environ.get('whatap.enabled'):
|
|
433
429
|
agent()
|
|
@@ -440,7 +436,7 @@ def batch_agent():
|
|
|
440
436
|
batch_home = os.environ.get(home)
|
|
441
437
|
if not batch_home:
|
|
442
438
|
if not read_file(home, home.lower()):
|
|
443
|
-
|
|
439
|
+
whatap_print('WHATAP: WHATAP_HOME_BATCH is empty')
|
|
444
440
|
return
|
|
445
441
|
|
|
446
442
|
if write_file(home, home.lower(), batch_home):
|
|
@@ -459,7 +455,7 @@ def batch_profiling(fn):
|
|
|
459
455
|
home = 'WHATAP_HOME_BATCH'
|
|
460
456
|
batch_home = read_file(home, home.lower())
|
|
461
457
|
if not batch_home:
|
|
462
|
-
|
|
458
|
+
whatap_print(
|
|
463
459
|
'WHATAP(@batch_profiling): try, whatap-start-batch')
|
|
464
460
|
return fn(*args, **kwargs)
|
|
465
461
|
else:
|
|
@@ -483,3 +479,78 @@ def batch_profiling(fn):
|
|
|
483
479
|
return callback if callback else fn(*args, **kwargs)
|
|
484
480
|
|
|
485
481
|
return trace
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
import fcntl, os, time
|
|
485
|
+
import errno
|
|
486
|
+
def openPortFile(filepath=os.environ.get('WHATAP_LOCK_FILE', '/tmp/whatap-python.lock')):
|
|
487
|
+
f = None
|
|
488
|
+
i=0
|
|
489
|
+
while f == None and i < 100:
|
|
490
|
+
try:
|
|
491
|
+
f = open(filepath, 'r+')
|
|
492
|
+
except IOError as e:
|
|
493
|
+
if e.errno == 2:
|
|
494
|
+
prefix = os.path.split(filepath)[0]
|
|
495
|
+
try:
|
|
496
|
+
if not os.path.exists(prefix):
|
|
497
|
+
os.makedirs(prefix)
|
|
498
|
+
f = open(filepath, 'w+')
|
|
499
|
+
except:
|
|
500
|
+
pass
|
|
501
|
+
i += 1
|
|
502
|
+
|
|
503
|
+
if f:
|
|
504
|
+
try:
|
|
505
|
+
fcntl.lockf(f, fcntl.LOCK_EX)
|
|
506
|
+
return f
|
|
507
|
+
except Exception as e:
|
|
508
|
+
whatap_print(e)
|
|
509
|
+
try:
|
|
510
|
+
f.close()
|
|
511
|
+
except:
|
|
512
|
+
pass
|
|
513
|
+
|
|
514
|
+
def get_port_number(port=6600, home=os.environ.get('WHATAP_HOME')):
|
|
515
|
+
if not home:
|
|
516
|
+
return None
|
|
517
|
+
|
|
518
|
+
for i in range(100):
|
|
519
|
+
f = openPortFile()
|
|
520
|
+
if not f:
|
|
521
|
+
if i > 50:
|
|
522
|
+
time.sleep(0.1)
|
|
523
|
+
continue
|
|
524
|
+
if f:
|
|
525
|
+
lastPortFound = None
|
|
526
|
+
for l in f.readlines():
|
|
527
|
+
l = l.strip()
|
|
528
|
+
try:
|
|
529
|
+
(portFound, portHome) = l.split()
|
|
530
|
+
portFound = int(portFound)
|
|
531
|
+
except:
|
|
532
|
+
continue
|
|
533
|
+
if home == portHome:
|
|
534
|
+
return portFound
|
|
535
|
+
if not lastPortFound or lastPortFound < portFound:
|
|
536
|
+
lastPortFound = int(portFound)
|
|
537
|
+
if not lastPortFound:
|
|
538
|
+
lastPortFound = port
|
|
539
|
+
else:
|
|
540
|
+
lastPortFound += 1
|
|
541
|
+
f.write(str(lastPortFound))
|
|
542
|
+
f.write('\t')
|
|
543
|
+
f.write(home)
|
|
544
|
+
f.write('\n')
|
|
545
|
+
fcntl.lockf(f, fcntl.LOCK_UN)
|
|
546
|
+
f.close()
|
|
547
|
+
return lastPortFound
|
|
548
|
+
|
|
549
|
+
return port
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def configPort():
|
|
553
|
+
port = get_port_number()
|
|
554
|
+
if port:
|
|
555
|
+
update_config('WHATAP_HOME', 'net_udp_port', str(port))
|
|
556
|
+
return port
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import sys, os
|
|
2
|
+
|
|
3
|
+
try:
|
|
4
|
+
from whatap import agent
|
|
5
|
+
agent()
|
|
6
|
+
except ModuleNotFoundError:
|
|
7
|
+
pythonpath = os.environ.get('PYTHONPATH')
|
|
8
|
+
if pythonpath.endswith("/bootstrap"):
|
|
9
|
+
pythonpath,_ = os.path.split(pythonpath)
|
|
10
|
+
pythonpath,_ = os.path.split(pythonpath)
|
|
11
|
+
|
|
12
|
+
sys.path.append(pythonpath)
|
|
13
|
+
try:
|
|
14
|
+
from whatap import agent
|
|
15
|
+
agent()
|
|
16
|
+
except ModuleNotFoundError:
|
|
17
|
+
#final fail
|
|
18
|
+
pass
|
|
19
|
+
|
|
@@ -5,7 +5,12 @@ Configuration = {
|
|
|
5
5
|
"trace_auto_normalize_enabled": True,
|
|
6
6
|
"trace_user_enabled": True,
|
|
7
7
|
"trace_user_using_ip": True,
|
|
8
|
+
"trace_logging_enabled": False,
|
|
9
|
+
"trace_loguru_enabled": False,
|
|
10
|
+
"trace_ignore_url_set": [],
|
|
11
|
+
"trace_ignore_url_prefix": None,
|
|
8
12
|
|
|
13
|
+
"debug": False,
|
|
9
14
|
"query_string_enabled": False,
|
|
10
15
|
"query_string_urls": "",
|
|
11
16
|
|
|
@@ -194,4 +199,8 @@ Configuration = {
|
|
|
194
199
|
"master_agent_port" : 6600,
|
|
195
200
|
"unix_socket_enabled":False,
|
|
196
201
|
"unix_socket":"whatap.sock",
|
|
202
|
+
"debug_stack_enabled": False,
|
|
203
|
+
"log_unhandled_exception": 'false',
|
|
204
|
+
"threadstack_faulthandler": False,
|
|
205
|
+
"max_send_queue_size": 1000,
|
|
197
206
|
}
|