whatap-python 0.1.120__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.
Files changed (129) hide show
  1. whatap_python-0.3.35/PKG-INFO +143 -0
  2. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/__init__.py +141 -42
  3. whatap_python-0.3.35/whatap/agent/darwin/amd64/whatap_python +0 -0
  4. whatap_python-0.3.35/whatap/agent/darwin/arm64/whatap_python +0 -0
  5. whatap_python-0.3.35/whatap/agent/linux/amd64/whatap_python +0 -0
  6. {whatap-python-0.1.120/whatap/agent/darwin/amd64 → whatap_python-0.3.35/whatap/agent/linux/arm64}/whatap_python +0 -0
  7. whatap_python-0.3.35/whatap/bootstrap/sitecustomize.py +19 -0
  8. whatap_python-0.3.35/whatap/build.py +4 -0
  9. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/conf/configuration.py +9 -0
  10. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/conf/configure.py +19 -2
  11. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/io/data_outputx.py +4 -0
  12. whatap_python-0.3.35/whatap/net/async_sender.py +64 -0
  13. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/net/packet_enum.py +1 -0
  14. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/net/packet_type_enum.py +3 -0
  15. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/net/param_def.py +1 -0
  16. whatap_python-0.3.35/whatap/net/stackhelper.py +86 -0
  17. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/net/udp_session.py +90 -31
  18. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/net/udp_thread.py +18 -2
  19. whatap_python-0.3.35/whatap/pack/logSinkPack.py +77 -0
  20. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/pack/pack_enum.py +2 -0
  21. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/scripts/__init__.py +9 -2
  22. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/amqp_kombu.py +2 -2
  23. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/amqp_pika.py +2 -2
  24. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_django.py +67 -9
  25. whatap_python-0.3.35/whatap/trace/mod/application_django_py3.py +249 -0
  26. whatap_python-0.3.35/whatap/trace/mod/application_fastapi.py +420 -0
  27. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_flask.py +3 -3
  28. whatap_python-0.3.35/whatap/trace/mod/application_frappe.py +222 -0
  29. whatap_python-0.3.35/whatap/trace/mod/application_graphql.py +141 -0
  30. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_nameko.py +1 -1
  31. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_wsgi.py +146 -91
  32. whatap_python-0.3.35/whatap/trace/mod/database_mongo.py +167 -0
  33. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/database_mysql.py +5 -4
  34. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/database_redis.py +5 -5
  35. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/database_toolkit.py +98 -9
  36. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/email_smtp.py +3 -3
  37. whatap_python-0.3.35/whatap/trace/mod/logging.py +117 -0
  38. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/plugin.py +2 -2
  39. whatap_python-0.3.35/whatap/trace/simple_trace_context.py +9 -0
  40. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/trace_context.py +6 -2
  41. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/trace_context_manager.py +85 -22
  42. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/trace_import.py +17 -9
  43. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/trace_module_definition.py +25 -0
  44. whatap_python-0.3.35/whatap/util/debug_util.py +73 -0
  45. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/ip_util.py +0 -1
  46. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/linked_map.py +4 -25
  47. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/throttle_util.py +3 -6
  48. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/userid_util.py +6 -3
  49. whatap_python-0.3.35/whatap_python.egg-info/PKG-INFO +143 -0
  50. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap_python.egg-info/SOURCES.txt +10 -0
  51. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap_python.egg-info/entry_points.txt +0 -1
  52. whatap-python-0.1.120/PKG-INFO +0 -144
  53. whatap-python-0.1.120/whatap/agent/darwin/arm64/whatap_python +0 -0
  54. whatap-python-0.1.120/whatap/agent/linux/amd64/whatap_python +0 -0
  55. whatap-python-0.1.120/whatap/agent/linux/arm64/whatap_python +0 -0
  56. whatap-python-0.1.120/whatap/bootstrap/sitecustomize.py +0 -2
  57. whatap-python-0.1.120/whatap/build.py +0 -4
  58. whatap-python-0.1.120/whatap/util/debug_util.py +0 -29
  59. whatap-python-0.1.120/whatap_python.egg-info/PKG-INFO +0 -144
  60. {whatap-python-0.1.120 → whatap_python-0.3.35}/README.md +0 -0
  61. {whatap-python-0.1.120 → whatap_python-0.3.35}/setup.cfg +0 -0
  62. {whatap-python-0.1.120 → whatap_python-0.3.35}/setup.py +0 -0
  63. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/LICENSE +0 -0
  64. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/README.rst +0 -0
  65. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/__main__.py +0 -0
  66. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/bootstrap/__init__.py +0 -0
  67. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/conf/__init__.py +0 -0
  68. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/conf/license.py +0 -0
  69. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/control/__init__.py +0 -0
  70. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/io/__init__.py +0 -0
  71. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/io/data_inputx.py +0 -0
  72. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/net/__init__.py +0 -0
  73. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/pack/__init__.py +0 -0
  74. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/pack/pack.py +0 -0
  75. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/__init__.py +0 -0
  76. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/__init__.py +0 -0
  77. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_bottle.py +0 -0
  78. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_celery.py +0 -0
  79. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_cherrypy.py +0 -0
  80. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/application_tornado.py +0 -0
  81. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/database_postgresql.py +0 -0
  82. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/httpc_django.py +0 -0
  83. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/httpc_httplib.py +0 -0
  84. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/httpc_requests.py +0 -0
  85. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/trace/mod/httpc_urllib3.py +0 -0
  86. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/__init__.py +0 -0
  87. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/bit_util.py +0 -0
  88. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/cardinality/__init__.py +0 -0
  89. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/cardinality/hyperloglog.py +0 -0
  90. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/cardinality/murmurhash.py +0 -0
  91. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/cardinality/registerset.py +0 -0
  92. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/compare_util.py +0 -0
  93. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/date_util.py +0 -0
  94. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/escape_literal_sql.py +0 -0
  95. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/hash_util.py +0 -0
  96. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/hexa32.py +0 -0
  97. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/int_set.py +0 -0
  98. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/keygen.py +0 -0
  99. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/linked_list.py +0 -0
  100. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/metering_util.py +0 -0
  101. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/request_double_queue.py +0 -0
  102. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/request_queue.py +0 -0
  103. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/util/string_util.py +0 -0
  104. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/__init__.py +0 -0
  105. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/blob_value.py +0 -0
  106. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/boolean_value.py +0 -0
  107. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/decimal_value.py +0 -0
  108. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/double_summary.py +0 -0
  109. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/double_value.py +0 -0
  110. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/float_array.py +0 -0
  111. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/float_value.py +0 -0
  112. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/int_array.py +0 -0
  113. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/ip4_value.py +0 -0
  114. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/list_value.py +0 -0
  115. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/long_array.py +0 -0
  116. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/long_summary.py +0 -0
  117. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/map_value.py +0 -0
  118. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/null_value.py +0 -0
  119. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/number_value.py +0 -0
  120. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/summary_value.py +0 -0
  121. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/text_array.py +0 -0
  122. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/text_hash_value.py +0 -0
  123. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/text_value.py +0 -0
  124. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/value.py +0 -0
  125. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/value/value_enum.py +0 -0
  126. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap/whatap.conf +0 -0
  127. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap_python.egg-info/dependency_links.txt +0 -0
  128. {whatap-python-0.1.120 → whatap_python-0.3.35}/whatap_python.egg-info/not-zip-safe +0 -0
  129. {whatap-python-0.1.120 → 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.
@@ -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
- print('WHATAP: LOG FILE WRITE ERROR.')
66
- print(
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
- print('WHATAP: LOGGING ERROR: {}'.format(e))
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
- print(str)
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
- print('WHATAP: WHATAP HOME ERROR. (path: {})'.format(os.path.join(os.environ.get(home))))
129
- print(
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
- print('WHATAP: ${} is empty'.format(target))
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
- print('WHATAP: WHATAP_HOME is empty')
154
- print(
162
+ whatap_print('WHATAP: WHATAP_HOME is empty')
163
+ whatap_print(
155
164
  'WHATAP: WHATAP_HOME set default CURRENT_WORKING_DIRECTORY value')
156
- print('CURRENT_WORKING_DIRECTORY is {}\n'.format(whatap_home))
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
- print('WHATAP: PERMISSION ERROR: {}'.format(e))
176
- print(
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
- print('WHATAP: OPTION ERROR: {}'.format(e))
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,10 +293,10 @@ def agent():
281
293
  whatap_home = os.getcwd()
282
294
  os.environ[home] = whatap_home
283
295
 
284
- print('WHATAP: WHATAP_HOME is empty')
285
- print(
296
+ whatap_print('WHATAP: WHATAP_HOME is empty')
297
+ whatap_print(
286
298
  'WHATAP: WHATAP_HOME set default CURRENT_WORKING_DIRECTORY value')
287
- print('CURRENT_WORKING_DIRECTORY is {}\n'.format(whatap_home))
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
@@ -300,13 +312,15 @@ ARCH = {
300
312
  'x86_32': '386',
301
313
  'ARM': 'arm',
302
314
  'AArch64': 'arm64',
315
+ 'arm64': 'arm64',
316
+ 'aarch64': 'arm64'
303
317
  }
304
318
 
305
319
  AGENT_NAME = 'whatap_python'
306
320
 
307
321
 
308
322
 
309
- def go(batch=False):
323
+ def go(batch=False, opts={}):
310
324
  newenv=os.environ.copy()
311
325
  newenv['WHATAP_VERSION'] = build.version
312
326
  newenv['whatap.start'] = str(DateUtil.now())
@@ -317,6 +331,7 @@ def go(batch=False):
317
331
  newenv['sys.version_info'] = str(sys.version_info)
318
332
  newenv['sys.executable'] = sys.executable
319
333
  newenv['sys.path'] = str(sys.path)
334
+ newenv.update(opts)
320
335
 
321
336
  if not batch:
322
337
  home = 'WHATAP_HOME'
@@ -331,11 +346,12 @@ def go(batch=False):
331
346
  with open(cmdlinepath) as f:
332
347
  content = f.read()
333
348
  if content:
334
- return content.encode('utf8')
349
+ return content.strip()
335
350
  return ''
336
351
  pid = read_file(home, file_name)
337
- if pid and 'whatap_python' in get_pname(pid):
338
- return
352
+ if pid and get_pname(pid).find('whatap_python') >= 0:
353
+ os.kill(int(pid), signal.SIGKILL)
354
+
339
355
  try:
340
356
  home_path= os.environ.get(home)
341
357
  if os.path.exists(os.path.join(home_path, AGENT_NAME)):
@@ -344,28 +360,32 @@ def go(batch=False):
344
360
  source_cwd = os.path.join(os.path.join(os.path.dirname(__file__), 'agent'), platform.system().lower(),
345
361
  ARCH[platform.machine()])
346
362
 
347
-
348
363
  os.symlink(os.path.join(source_cwd, AGENT_NAME),
349
364
  os.path.join(home_path, AGENT_NAME))
350
365
 
366
+ sockfile_path = os.path.join(home_path, 'run')
367
+ if not os.path.exists(sockfile_path):
368
+ os.mkdir(sockfile_path)
351
369
  newenv['whatap.enabled'] = 'True'
352
- def preexec_function():
353
- signal.signal(signal.SIGINT, signal.SIG_IGN)
354
- process = subprocess.Popen('./{0}'.format(AGENT_NAME),
355
- cwd=home_path,env=newenv, preexec_fn=preexec_function)
356
- # Write PID file
357
- write_file(home, file_name, str(process.pid))
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"))
358
376
  except Exception as e:
359
- print('WHATAP: AGENT ERROR: {}'.format(e))
377
+ import traceback
378
+ traceback.print_exc()
379
+ whatap_print('WHATAP: AGENT ERROR: {}'.format(e))
360
380
  else:
361
- print('WHATAP: AGENT UP! (process name: {})\n'.format(AGENT_NAME))
381
+ whatap_print('WHATAP: AGENT UP! (process name: {})\n'.format(AGENT_NAME))
362
382
 
363
383
  import signal
364
384
 
365
385
  from whatap.trace.mod.application_wsgi import interceptor, start_interceptor, \
366
- end_interceptor, trace_handler
367
-
368
- 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
369
389
 
370
390
  def register_app(fn):
371
391
  @trace_handler(fn, True)
@@ -392,14 +412,18 @@ def method_profiling(fn):
392
412
  try:
393
413
  ctx = TraceContext()
394
414
  ctx.service_name=fn.__name__
395
- ctx = start_interceptor(ctx)
415
+ start_interceptor(ctx)
396
416
  callback = fn(*args, **kwargs)
397
- end_interceptor(thread_id= ctx.thread_id)
398
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)
399
421
  logging.debug('WHATAP(@method_profiling): ' + str(e),
400
422
  extra={'id': 'WA776'}, exc_info=True)
401
423
  finally:
402
- return callback if callback else fn(*args, **kwargs)
424
+ ctx = TraceContextManager.getLocalContext()
425
+ end_interceptor(ctx=ctx)
426
+ return callback
403
427
 
404
428
  if not os.environ.get('whatap.enabled'):
405
429
  agent()
@@ -412,7 +436,7 @@ def batch_agent():
412
436
  batch_home = os.environ.get(home)
413
437
  if not batch_home:
414
438
  if not read_file(home, home.lower()):
415
- print('WHATAP: WHATAP_HOME_BATCH is empty')
439
+ whatap_print('WHATAP: WHATAP_HOME_BATCH is empty')
416
440
  return
417
441
 
418
442
  if write_file(home, home.lower(), batch_home):
@@ -431,7 +455,7 @@ def batch_profiling(fn):
431
455
  home = 'WHATAP_HOME_BATCH'
432
456
  batch_home = read_file(home, home.lower())
433
457
  if not batch_home:
434
- print(
458
+ whatap_print(
435
459
  'WHATAP(@batch_profiling): try, whatap-start-batch')
436
460
  return fn(*args, **kwargs)
437
461
  else:
@@ -455,3 +479,78 @@ def batch_profiling(fn):
455
479
  return callback if callback else fn(*args, **kwargs)
456
480
 
457
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
@@ -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
+
@@ -0,0 +1,4 @@
1
+ app = 'Python'
2
+ name = 'whatap-python'
3
+ version = '0.3.35'
4
+ release_date = '20240625'
@@ -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
  }
@@ -14,13 +14,23 @@ class Configure(object):
14
14
  last_config_modified = 0
15
15
  observers = []
16
16
  POD_NAME = os.environ.get("POD_NAME") if os.environ.get('POD_NAME') else os.environ.get("PODNAME") if os.environ.get("PODNAME") else ''
17
+ license = None
18
+ max_send_queue_size = 1000
17
19
 
18
20
  @classmethod
19
21
  def init(cls, display=True):
20
-
22
+ if cls.last_loaded == 0:
23
+ cls.loadFromEnv()
21
24
  cls.last_loaded = time.time()
22
25
  return cls.load(display)
23
26
 
27
+ @classmethod
28
+ def loadFromEnv(cls):
29
+ for key, value in Configuration.items():
30
+ setattr(cls, key, value)
31
+ if not hasattr(cls, "license") and hasattr(cls, "accesskey"):
32
+ setattr(cls, "license", getattr(cls, "accesskey"))
33
+
24
34
  @classmethod
25
35
  def load(cls, display=True):
26
36
  home = 'WHATAP_HOME'
@@ -29,8 +39,9 @@ class Configure(object):
29
39
  last_modified = os.path.getmtime(whatap_config)
30
40
  if cls.last_config_modified >= last_modified:
31
41
  return True
32
- for key, value in Configuration.items():
42
+ for key, value in os.environ.items():
33
43
  setattr(cls, key, value)
44
+
34
45
  with open(whatap_config, 'r') as f:
35
46
  for line in f:
36
47
  cls.last_config_modified = last_modified
@@ -41,11 +52,15 @@ class Configure(object):
41
52
  key, value = line.split('=')
42
53
  key = key.strip()
43
54
  value = value.strip()
55
+ if key and key.endswith("_set"):
56
+ value = value.split(",")
44
57
  cls.setProperty(key, value)
45
58
 
46
59
  except Exception as e:
47
60
  print('WHATAP: ', e)
48
61
  continue
62
+ if not getattr(cls, "license") and getattr(cls, "accesskey"):
63
+ setattr(cls, "license", getattr(cls, "accesskey"))
49
64
  for callback in cls.observers:
50
65
  callback()
51
66
  except Exception as e:
@@ -63,6 +78,8 @@ class Configure(object):
63
78
  def getProperty(cls, key, value=None):
64
79
  if hasattr(cls, key):
65
80
  return getattr(cls, key)
81
+ elif key in os.environ:
82
+ return os.environ[key]
66
83
  else:
67
84
  return value
68
85
 
@@ -256,3 +256,7 @@ class DataOutputX(object):
256
256
  buffer_arr = bytearray(self.buffer.getvalue())
257
257
  buffer_arr[pos:pos + 4] = b.getvalue()
258
258
  self.buffer = io.BytesIO(buffer_arr)
259
+
260
+ def size(self):
261
+ return self.buffer.getbuffer().nbytes
262
+
@@ -0,0 +1,64 @@
1
+ import queue, time, threading
2
+ from . import udp_session
3
+ from whatap.conf.configure import Configure as conf
4
+ from whatap.trace.simple_trace_context import SimpleTraceContext
5
+
6
+ q = queue.Queue(conf.max_send_queue_size)
7
+
8
+ from enum import Enum
9
+ class SendType(Enum):
10
+ DATAS = 1
11
+ RELAY = 2
12
+
13
+ def send_packet( packet_type, ctx, datas=[]):
14
+ ctx = SimpleTraceContext(ctx.id, ctx.start_time, ctx.elapsed, ctx.thread_id)
15
+ _initThread()
16
+ global q
17
+ if q.full():
18
+ return
19
+ q.put((SendType.DATAS, (packet_type, ctx, datas)))
20
+
21
+ def send_relaypack( packbytes):
22
+ _initThread()
23
+ global q
24
+ if q.full():
25
+ return
26
+ q.put((SendType.RELAY, packbytes))
27
+
28
+ def startWhatapThread():
29
+ def __sendPackets():
30
+ global q
31
+ while True:
32
+ packet_env = q.get()
33
+ if not packet_env:
34
+ time.sleep(0.1)
35
+ continue
36
+ sendType,params = packet_env
37
+ if sendType == SendType.DATAS:
38
+ packet_type, ctx, datas = params
39
+ udp_session.UdpSession.send_packet(packet_type, ctx, datas)
40
+ elif sendType == SendType.RELAY:
41
+ packbytes = params
42
+ udp_session.UdpSession.send_relaypack(packbytes)
43
+ t = threading.Thread(target=__sendPackets)
44
+ t.setDaemon(True)
45
+ t.start()
46
+
47
+ _lock = threading.Lock()
48
+ _initialized = False
49
+
50
+ def _initThread():
51
+ global _lock, _initialized
52
+ if _initialized:
53
+ return
54
+ try:
55
+ if _initialized:
56
+ return
57
+ _lock.acquire()
58
+ if _initialized:
59
+ return
60
+ _initialized=True
61
+ startWhatapThread()
62
+ finally:
63
+ _lock.release()
64
+