cavisson-pythonagent 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. cavisson_pythonagent-0.0.1.dist-info/METADATA +32 -0
  2. cavisson_pythonagent-0.0.1.dist-info/RECORD +180 -0
  3. cavisson_pythonagent-0.0.1.dist-info/WHEEL +5 -0
  4. cavisson_pythonagent-0.0.1.dist-info/licenses/LICENSE +19 -0
  5. cavisson_pythonagent-0.0.1.dist-info/top_level.txt +1 -0
  6. pythonagent/__init__.py +22 -0
  7. pythonagent/agent/__init__.py +219 -0
  8. pythonagent/agent/internal/__init__.py +1 -0
  9. pythonagent/agent/internal/agent.py +1651 -0
  10. pythonagent/agent/internal/framesinfo.py +152 -0
  11. pythonagent/agent/internal/heap_dump.py +39 -0
  12. pythonagent/agent/internal/intercept_module.py +70 -0
  13. pythonagent/agent/internal/logs.py +122 -0
  14. pythonagent/agent/internal/metadata/__init__.py +0 -0
  15. pythonagent/agent/internal/metadata/agent_meta_data.py +276 -0
  16. pythonagent/agent/internal/proc_compat.py +75 -0
  17. pythonagent/agent/internal/profile.py +47 -0
  18. pythonagent/agent/internal/provider.py +83 -0
  19. pythonagent/agent/internal/thread_dump.py +85 -0
  20. pythonagent/agent/internal/udp.py +245 -0
  21. pythonagent/agent/internal/udp_message.py +800 -0
  22. pythonagent/agent/probes/Instrumentation/__init__.py +340 -0
  23. pythonagent/agent/probes/Instrumentation/find.py +243 -0
  24. pythonagent/agent/probes/Instrumentation/module_version_resolver.py +155 -0
  25. pythonagent/agent/probes/Instrumentation/new_parser.py +64 -0
  26. pythonagent/agent/probes/Instrumentation/parser.py +129 -0
  27. pythonagent/agent/probes/__init__.py +219 -0
  28. pythonagent/agent/probes/base.py +303 -0
  29. pythonagent/agent/probes/cache/__init__.py +51 -0
  30. pythonagent/agent/probes/cache/redis.py +119 -0
  31. pythonagent/agent/probes/cache/redis_asyncio.py +83 -0
  32. pythonagent/agent/probes/coroutines/__init__.py +1 -0
  33. pythonagent/agent/probes/coroutines/asyncio.py +63 -0
  34. pythonagent/agent/probes/elasticdb/__init__.py +7 -0
  35. pythonagent/agent/probes/elasticdb/aelastic.py +54 -0
  36. pythonagent/agent/probes/frameworks/__init__.py +27 -0
  37. pythonagent/agent/probes/frameworks/agentprofiler.py +105 -0
  38. pythonagent/agent/probes/frameworks/aiohttp_web.py +155 -0
  39. pythonagent/agent/probes/frameworks/aisess.py +151 -0
  40. pythonagent/agent/probes/frameworks/asgi.py +340 -0
  41. pythonagent/agent/probes/frameworks/bottle.py +27 -0
  42. pythonagent/agent/probes/frameworks/cherry.py +25 -0
  43. pythonagent/agent/probes/frameworks/django.py +128 -0
  44. pythonagent/agent/probes/frameworks/falcon.py +21 -0
  45. pythonagent/agent/probes/frameworks/fastapi.py +35 -0
  46. pythonagent/agent/probes/frameworks/flask.py +30 -0
  47. pythonagent/agent/probes/frameworks/pyramid.py +56 -0
  48. pythonagent/agent/probes/frameworks/test.py +108 -0
  49. pythonagent/agent/probes/frameworks/tornado_async_web.py +117 -0
  50. pythonagent/agent/probes/frameworks/tornado_web.py +133 -0
  51. pythonagent/agent/probes/frameworks/wsgi.py +353 -0
  52. pythonagent/agent/probes/grpc/__init__.py +76 -0
  53. pythonagent/agent/probes/grpc/client_interceptor.py +132 -0
  54. pythonagent/agent/probes/grpc/server_interceptor.py +129 -0
  55. pythonagent/agent/probes/havoc/__init__.py +0 -0
  56. pythonagent/agent/probes/havoc/custom_memory_stress.py +186 -0
  57. pythonagent/agent/probes/havoc/custom_thread_stress.py +187 -0
  58. pythonagent/agent/probes/havoc/havoc_constants.py +218 -0
  59. pythonagent/agent/probes/havoc/havoc_manager.py +981 -0
  60. pythonagent/agent/probes/http/__init__.py +49 -0
  61. pythonagent/agent/probes/http/aiohttp_client.py +59 -0
  62. pythonagent/agent/probes/http/boto.py +12 -0
  63. pythonagent/agent/probes/http/httplib.py +110 -0
  64. pythonagent/agent/probes/http/httpx_client.py +116 -0
  65. pythonagent/agent/probes/http/requests.py +15 -0
  66. pythonagent/agent/probes/http/tornado_httpclient.py +85 -0
  67. pythonagent/agent/probes/http/urllib3.py +16 -0
  68. pythonagent/agent/probes/langchain/__init__.py +21 -0
  69. pythonagent/agent/probes/langchain/base_tool.py +95 -0
  70. pythonagent/agent/probes/langchain/langchain_community.py +136 -0
  71. pythonagent/agent/probes/langchain/langchain_core.py +32 -0
  72. pythonagent/agent/probes/langchain/langchain_openai.py +110 -0
  73. pythonagent/agent/probes/logging/__init__.py +106 -0
  74. pythonagent/agent/probes/message_brokers/__init__.py +4 -0
  75. pythonagent/agent/probes/message_brokers/pika.py +126 -0
  76. pythonagent/agent/probes/mongodb/__init__.py +6 -0
  77. pythonagent/agent/probes/mongodb/pymongo.py +286 -0
  78. pythonagent/agent/probes/openai/__init__.py +3 -0
  79. pythonagent/agent/probes/openai/openai.py +797 -0
  80. pythonagent/agent/probes/span.py +101 -0
  81. pythonagent/agent/probes/sql/__init__.py +13 -0
  82. pythonagent/agent/probes/sql/botocores3.py +51 -0
  83. pythonagent/agent/probes/sql/dbapi.py +285 -0
  84. pythonagent/agent/probes/sql/dynamodb.py +90 -0
  85. pythonagent/agent/probes/sql/mysql_connector.py +24 -0
  86. pythonagent/agent/probes/sql/mysql_connector_cext.py +24 -0
  87. pythonagent/agent/probes/sql/mysqldb.py +43 -0
  88. pythonagent/agent/probes/sql/psycopg2.py +174 -0
  89. pythonagent/agent/probes/sql/pymysql.py +25 -0
  90. pythonagent/bootstrap/__init__.py +0 -0
  91. pythonagent/bootstrap/cav_gunicorn.py +26 -0
  92. pythonagent/bootstrap/cavagent_lambda_wrapper.py +291 -0
  93. pythonagent/bootstrap/run.py +47 -0
  94. pythonagent/bootstrap/sitecustomize.py +287 -0
  95. pythonagent/cavisson/netdiagnostics/CavAgent/instrumentationprofile.json +26 -0
  96. pythonagent/cavisson/netdiagnostics/CavAgent/interceptor_points.txt +29 -0
  97. pythonagent/cavisson/netdiagnostics/python/CavAgent/instrumentationprofile.json +42 -0
  98. pythonagent/cavisson/netdiagnostics/python/CavAgent/interceptor_points.txt +29 -0
  99. pythonagent/cavisson/netdiagnostics/python/config/ndsettings.conf +6 -0
  100. pythonagent/config.py +279 -0
  101. pythonagent/find.py +72 -0
  102. pythonagent/find_mod_cls_name.py +54 -0
  103. pythonagent/lang.py +131 -0
  104. pythonagent/lib.py +91 -0
  105. pythonagent/main/__init__.py +0 -0
  106. pythonagent/main/pytrace/__init__.py +79 -0
  107. pythonagent/main/pytrace/commands/__init__.py +0 -0
  108. pythonagent/main/pytrace/commands/auto_discovery.py +25 -0
  109. pythonagent/main/pytrace/commands/run.py +401 -0
  110. pythonagent/main/pytrace/pytrace.py +133 -0
  111. pythonagent/main/wsgi.py +6 -0
  112. pythonagent/main.py +27 -0
  113. pythonagent/run.py +46 -0
  114. pythonagent/sqins.py +8 -0
  115. pythonagent/test.py +73 -0
  116. pythonagent/utils.py +168 -0
  117. pythonagent/vendor/__init__.py +0 -0
  118. pythonagent/vendor/pympler/__init__.py +1 -0
  119. pythonagent/vendor/pympler/asizeof.py +2810 -0
  120. pythonagent/vendor/pympler/charts.py +62 -0
  121. pythonagent/vendor/pympler/classtracker.py +590 -0
  122. pythonagent/vendor/pympler/classtracker_stats.py +780 -0
  123. pythonagent/vendor/pympler/garbagegraph.py +80 -0
  124. pythonagent/vendor/pympler/mprofile.py +97 -0
  125. pythonagent/vendor/pympler/muppy.py +275 -0
  126. pythonagent/vendor/pympler/panels.py +115 -0
  127. pythonagent/vendor/pympler/process.py +238 -0
  128. pythonagent/vendor/pympler/py.typed +0 -0
  129. pythonagent/vendor/pympler/refbrowser.py +451 -0
  130. pythonagent/vendor/pympler/refgraph.py +350 -0
  131. pythonagent/vendor/pympler/summary.py +321 -0
  132. pythonagent/vendor/pympler/tracker.py +267 -0
  133. pythonagent/vendor/pympler/util/__init__.py +0 -0
  134. pythonagent/vendor/pympler/util/bottle.py +3809 -0
  135. pythonagent/vendor/pympler/util/compat.py +23 -0
  136. pythonagent/vendor/pympler/util/stringutils.py +77 -0
  137. pythonagent/vendor/pympler/web.py +346 -0
  138. pythonagent/vendor/werkzeug/__init__.py +20 -0
  139. pythonagent/vendor/werkzeug/_compat.py +228 -0
  140. pythonagent/vendor/werkzeug/_internal.py +473 -0
  141. pythonagent/vendor/werkzeug/_reloader.py +341 -0
  142. pythonagent/vendor/werkzeug/datastructures.py +3120 -0
  143. pythonagent/vendor/werkzeug/debug/__init__.py +498 -0
  144. pythonagent/vendor/werkzeug/debug/console.py +218 -0
  145. pythonagent/vendor/werkzeug/debug/repr.py +297 -0
  146. pythonagent/vendor/werkzeug/debug/tbtools.py +628 -0
  147. pythonagent/vendor/werkzeug/exceptions.py +829 -0
  148. pythonagent/vendor/werkzeug/filesystem.py +64 -0
  149. pythonagent/vendor/werkzeug/formparser.py +584 -0
  150. pythonagent/vendor/werkzeug/http.py +1307 -0
  151. pythonagent/vendor/werkzeug/local.py +420 -0
  152. pythonagent/vendor/werkzeug/middleware/__init__.py +25 -0
  153. pythonagent/vendor/werkzeug/middleware/dispatcher.py +66 -0
  154. pythonagent/vendor/werkzeug/middleware/http_proxy.py +219 -0
  155. pythonagent/vendor/werkzeug/middleware/lint.py +408 -0
  156. pythonagent/vendor/werkzeug/middleware/profiler.py +132 -0
  157. pythonagent/vendor/werkzeug/middleware/proxy_fix.py +169 -0
  158. pythonagent/vendor/werkzeug/middleware/shared_data.py +293 -0
  159. pythonagent/vendor/werkzeug/posixemulation.py +117 -0
  160. pythonagent/vendor/werkzeug/routing.py +2210 -0
  161. pythonagent/vendor/werkzeug/security.py +249 -0
  162. pythonagent/vendor/werkzeug/serving.py +1117 -0
  163. pythonagent/vendor/werkzeug/test.py +1123 -0
  164. pythonagent/vendor/werkzeug/testapp.py +241 -0
  165. pythonagent/vendor/werkzeug/urls.py +1138 -0
  166. pythonagent/vendor/werkzeug/useragents.py +202 -0
  167. pythonagent/vendor/werkzeug/utils.py +778 -0
  168. pythonagent/vendor/werkzeug/wrappers/__init__.py +36 -0
  169. pythonagent/vendor/werkzeug/wrappers/accept.py +50 -0
  170. pythonagent/vendor/werkzeug/wrappers/auth.py +33 -0
  171. pythonagent/vendor/werkzeug/wrappers/base_request.py +673 -0
  172. pythonagent/vendor/werkzeug/wrappers/base_response.py +700 -0
  173. pythonagent/vendor/werkzeug/wrappers/common_descriptors.py +341 -0
  174. pythonagent/vendor/werkzeug/wrappers/cors.py +100 -0
  175. pythonagent/vendor/werkzeug/wrappers/etag.py +304 -0
  176. pythonagent/vendor/werkzeug/wrappers/json.py +145 -0
  177. pythonagent/vendor/werkzeug/wrappers/request.py +49 -0
  178. pythonagent/vendor/werkzeug/wrappers/response.py +84 -0
  179. pythonagent/vendor/werkzeug/wrappers/user_agent.py +14 -0
  180. pythonagent/vendor/werkzeug/wsgi.py +1000 -0
@@ -0,0 +1,75 @@
1
+ import os
2
+ import sys
3
+ import platform
4
+
5
+
6
+ def get_process_name():
7
+ """Return current process name (basename of argv[0])."""
8
+ try:
9
+ # Linux fast path
10
+ with open('/proc/self/comm', 'r') as f:
11
+ return f.read().strip()
12
+ except (IOError, OSError):
13
+ pass
14
+ # Cross-platform fallback
15
+ if sys.argv:
16
+ return os.path.basename(sys.argv[0])
17
+ return os.path.basename(sys.executable)
18
+
19
+
20
+ def get_cmdline():
21
+ """Return command line as a list of strings."""
22
+ try:
23
+ with open('/proc/self/cmdline', 'rb') as f:
24
+ return f.read().decode('utf-8', errors='replace').split('\x00')
25
+ except (IOError, OSError):
26
+ pass
27
+ return list(sys.argv) # fallback: sys.argv covers script args
28
+
29
+
30
+ def get_rss_bytes():
31
+ """Return process RSS (resident set size) in bytes."""
32
+ try:
33
+ # Linux: /proc/self/status — VmRSS in kB
34
+ with open('/proc/self/status', 'r') as f:
35
+ for line in f:
36
+ if line.startswith('VmRSS:'):
37
+ return int(line.split()[1]) * 1024
38
+ except (IOError, OSError):
39
+ pass
40
+ try:
41
+ # macOS / BSD fallback via resource module
42
+ import resource
43
+ rss = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
44
+ if platform.system() == 'Linux':
45
+ rss *= 1024 # Linux reports ru_maxrss in kB
46
+ return rss
47
+ except (ImportError, AttributeError):
48
+ pass
49
+ return 0
50
+
51
+
52
+ def get_virtual_memory():
53
+ """Return (total, available, percent, used, free) in bytes."""
54
+ try:
55
+ mem = {}
56
+ with open('/proc/meminfo', 'r') as f:
57
+ for line in f:
58
+ parts = line.split()
59
+ if len(parts) >= 2:
60
+ mem[parts[0].rstrip(':')] = int(parts[1]) * 1024
61
+ total = mem.get('MemTotal', 0)
62
+ available = mem.get('MemAvailable', mem.get('MemFree', 0))
63
+ free = mem.get('MemFree', 0)
64
+ used = total - available
65
+ percent = (used / total * 100) if total else 0.0
66
+ return (total, available, percent, used, free)
67
+ except (IOError, OSError, ValueError):
68
+ pass
69
+ return (0, 0, 0.0, 0, 0)
70
+
71
+
72
+ def get_free_memory_mb():
73
+ """Return free physical memory in MB."""
74
+ return get_virtual_memory()[4] >> 20
75
+
@@ -0,0 +1,47 @@
1
+ import time
2
+ from pythonagent.agent.internal.proc_compat import get_rss_bytes
3
+
4
+
5
+ #def elapsed_since(start):
6
+ # return time.strftime("%H:%M:%S", time.gmtime(time.time() - start))
7
+
8
+ def elapsed_since(start):
9
+ #return time.strftime("%H:%M:%S", time.gmtime(time.time() - start))
10
+ elapsed = time.time() - start
11
+ if elapsed < 1:
12
+ return str(round(elapsed*1000,2)) + " ms"
13
+ if elapsed < 60:
14
+ return str(round(elapsed, 2)) + " s"
15
+ if elapsed < 3600:
16
+ return str(round(elapsed/60, 2)) + " min"
17
+ else:
18
+ return str(round(elapsed / 3600, 2)) + " hrs"
19
+
20
+ def format_bytes(bytes):
21
+ if abs(bytes) < 1000:
22
+ return str(bytes)+" B"
23
+ elif abs(bytes) < 1e6:
24
+ return str(round(bytes/1e3,2)) + " kB"
25
+ elif abs(bytes) < 1e9:
26
+ return str(round(bytes / 1e6, 2)) + " MB"
27
+ else:
28
+ return str(round(bytes / 1e9, 2)) + " GB"
29
+
30
+ def get_process_memory():
31
+ return get_rss_bytes()
32
+
33
+
34
+ def profile(func):
35
+ def wrapper(*args, **kwargs):
36
+ mem_before = get_process_memory()
37
+ start = time.time()
38
+ result = func(*args, **kwargs)
39
+ elapsed_time = elapsed_since(start)
40
+ mem_after = get_process_memory()
41
+ print("{0}: memory before: {1}, after: {2}, consumed: {3}; exec time: {4}".format(
42
+ func.__name__,
43
+ format_bytes(mem_before), format_bytes(mem_after), format_bytes(mem_after - mem_before),
44
+ elapsed_time))
45
+ return result
46
+ return wrapper
47
+
@@ -0,0 +1,83 @@
1
+ import contextvars
2
+
3
+
4
+ _CAV_CONTEXTVAR = contextvars.ContextVar("cavisson_contextvar", default=None)
5
+ _CURRENTBT_CONTEXTVAR = contextvars.ContextVar("currentbt_contextvar", default=None)
6
+ _STATUSCODE_CONTEXTVAR = contextvars.ContextVar("statuscode_contextvar", default=None)
7
+
8
+
9
+ class ContextProvider(object):
10
+
11
+ def __init__(self):
12
+ self.token = None
13
+
14
+ def _has_active_context(self):
15
+ ctx = _CAV_CONTEXTVAR.get()
16
+ return ctx is not None
17
+
18
+ def activate(self, ctx):
19
+ self.token = _CAV_CONTEXTVAR.set(ctx)
20
+
21
+ def active(self):
22
+ item = _CAV_CONTEXTVAR.get()
23
+ return item
24
+
25
+ def reset(self):
26
+ pass
27
+ #if self.token:
28
+ #_CAV_CONTEXTVAR.reset(self.token)
29
+
30
+
31
+
32
+ class CurrentBTProvider(object):
33
+
34
+ def __init__(self):
35
+ self.token = None
36
+
37
+ def _has_active_context(self):
38
+ ctx = _CURRENTBT_CONTEXTVAR.get()
39
+ return ctx is not None
40
+
41
+ def activate(self, ctx):
42
+ self.token = _CURRENTBT_CONTEXTVAR.set(ctx)
43
+
44
+ def active(self):
45
+ item = _CURRENTBT_CONTEXTVAR.get()
46
+ return item
47
+
48
+ def reset(self):
49
+ pass
50
+ #if self.token:
51
+ #_CURRENTBT_CONTEXTVAR.reset(self.token)
52
+
53
+
54
+
55
+ class StatusCodeProvider(object):
56
+
57
+ def __init__(self):
58
+ self.token = None
59
+
60
+ def _has_active_context(self):
61
+ ctx = _STATUSCODE_CONTEXTVAR.get()
62
+ return ctx is not None
63
+
64
+ def activate(self, ctx):
65
+ self.token = _STATUSCODE_CONTEXTVAR.set(ctx)
66
+
67
+ def active(self):
68
+ item = _STATUSCODE_CONTEXTVAR.get()
69
+ return item
70
+
71
+ def reset(self):
72
+ pass
73
+ #if self.token:
74
+ #_STATUSCODE_CONTEXTVAR.reset(self.token)
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
@@ -0,0 +1,85 @@
1
+ import json
2
+ import os
3
+ from datetime import datetime
4
+ import platform
5
+ import time
6
+ import threading
7
+ import traceback
8
+ import sys
9
+ import multiprocessing
10
+
11
+
12
+ def dumpstacks(nd_build):
13
+ my_system = platform.uname()
14
+ osName = my_system.system
15
+ osVersion = my_system.version
16
+ arch = my_system.machine
17
+ cpu_count = multiprocessing.cpu_count()
18
+ l = os.getloadavg()
19
+ res = sum(list(l))
20
+ sys_load_avg = round(res, 2) / 3
21
+ header = ("Full thread dump BCI Agent :- [ Dump Taken at : " + datetime.now().strftime(
22
+ "%d/%m/%Y %H:%M:%S") + " , Where BCIAgent build = " + nd_build + "]")
23
+ deadlocked_threads = ""
24
+ nid = "0x0"
25
+ prio = "5"
26
+ vendor = ""
27
+ version = ""
28
+ system_name = os.getenv('HOSTNAME')
29
+ # //****append the thread details into list(code)*****//
30
+ code = []
31
+ o = []
32
+ al = []
33
+
34
+ thread_dict = {}
35
+ for thread in threading.enumerate():
36
+ thread_dict[thread.ident] = thread
37
+
38
+ for threadId, stack in sys._current_frames().items():
39
+ thread_name = None
40
+ thread_status = None
41
+ thread_object = thread_dict.get(threadId, None)
42
+
43
+ if thread_object:
44
+ thread_name = thread_object.name
45
+ if thread_object.isDaemon():
46
+ thread_status = 'Daemon'
47
+ else:
48
+ thread_status = 'Non-Daemon'
49
+
50
+ if not thread_name:
51
+ thread_name = "unknown"
52
+
53
+ if not thread_status:
54
+ thread_status = "unknown"
55
+
56
+ thread_string = ("\n\n'{}'".format(thread_name)
57
+ + " prio={}".format(prio)
58
+ + " tid={}".format(threadId)
59
+ + " nid={}".format(nid)
60
+ + " " + thread_status + " \n"
61
+ + "java.lang.Thread.State: {} ".format(thread_status))
62
+
63
+ code.extend([thread_string])
64
+
65
+ for filename, lineno, name, line in traceback.extract_stack(stack):
66
+ code.append('File: "%s", line %d, in %s, at %s' % (filename, lineno, name, datetime.now()))
67
+ if line:
68
+ code.append(" %s" % (line.strip()))
69
+
70
+ thread_dump_header = {
71
+ "": header,
72
+ "vmName": osName,
73
+ "version": version,
74
+ "vendor": vendor,
75
+ "osName": osName,
76
+ "osVersion": osVersion,
77
+ "arch": arch,
78
+ "noOfProcessors": cpu_count,
79
+ "SysLoadAvg": sys_load_avg,
80
+ "deadlocked threads": deadlocked_threads
81
+ }
82
+ joined_code = "\n".join((code))
83
+ return f"{thread_dump_header}" + '\n' + f"{joined_code}\n"
84
+
85
+
@@ -0,0 +1,245 @@
1
+ import uuid
2
+ import os
3
+ import socket
4
+
5
+ import sys
6
+ import threading
7
+ import json
8
+ from .udp_message import create_start_transaction_message, create_end_transaction_message
9
+ from .udp_message import create_method_entry_message, create_method_exit_message
10
+ from .udp_message import create_transaction_encode_http_message
11
+ from .udp_message import create_exception_encode_message
12
+ from .udp_message import create_havoc_message
13
+ from .udp_message import create_init_message, create_agent_initialize_message
14
+ from .udp_message import create_heartbeat_message
15
+ import time
16
+ import logging
17
+
18
+ udp_connection = None
19
+
20
+ logger = logging.getLogger('pythonagent.agent')
21
+
22
+
23
+ class UDPConnection(object):
24
+ def __init__(self, agent_obj):
25
+
26
+ if 'CAV_APP_AGENT_PROXYIP' in os.environ:
27
+ self.cav_proxy_ip = os.environ['CAV_APP_AGENT_PROXYIP']
28
+ else:
29
+ self.cav_proxy_ip = "127.0.0.1"
30
+
31
+ if 'CAV_APP_AGENT_PROXYPORT' in os.environ:
32
+ self.cav_proxy_port = int(os.environ['CAV_APP_AGENT_PROXYPORT'])
33
+
34
+ else:
35
+ self.cav_proxy_port = 10000
36
+
37
+ self.server_address_port = (self.cav_proxy_ip, self.cav_proxy_port)
38
+
39
+ # Create a UDP socket at client side
40
+ try:
41
+
42
+ self.UDPClientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
43
+ logger.debug("Server Port {}".format(self.server_address_port))
44
+
45
+ havoc_thread = threading.Thread(target=incoming_message_processor, name="havoc_thread",
46
+ args=(self.UDPClientSocket, agent_obj), daemon=True)
47
+ havoc_thread.start()
48
+
49
+ heartbeat_thread = threading.Thread(target=heartbeat_sender, name="heartbeat_thread",
50
+ args=(self.UDPClientSocket, self.server_address_port, agent_obj),
51
+ daemon=True)
52
+ heartbeat_thread.start()
53
+
54
+
55
+ except:
56
+ logger.warning("Unable to create UDP Connection")
57
+
58
+ def send(self, message, tx_type="non_start_fp"):
59
+
60
+ # Send to server using created UDP socket
61
+ try:
62
+ self.UDPClientSocket.sendto(message, self.server_address_port)
63
+
64
+ except:
65
+ logger.warning("Unable to send UDP packet")
66
+
67
+
68
+ def heartbeat_sender(udp_socket, address_port, ag_obj):
69
+ logger.info("heartbeat sender started")
70
+ context = ag_obj.get_transaction_context()
71
+ if not context:
72
+ from pythonagent.agent.internal.agent import TransactionContext
73
+ context = TransactionContext() # Create dummy context to avoid failure
74
+ message = create_heartbeat_message(context, ag_obj)
75
+ logger.info("heartbeat message {}".format(message))
76
+ while True:
77
+ try:
78
+ logger.debug("heartbeat about to send")
79
+ udp_socket.sendto(message, address_port)
80
+ logger.info("heartbeat sent")
81
+ time.sleep(10)
82
+ logger.debug("heartbeat sleep completed")
83
+ except Exception as e:
84
+ logger.error("heartbeat exception", e)
85
+
86
+
87
+ def incoming_message_processor(udp_socket, agent_obj):
88
+ logger.debug("New thread started")
89
+
90
+ from pythonagent.agent.probes.havoc.havoc_manager import NDNetHavocMonitor # Don't shift to top, it will cause circular import
91
+ from pythonagent.utils import process_raw_havoc_message, process_udp_agent_init_response
92
+ havoc_monitor = NDNetHavocMonitor.get_instance()
93
+ # logger.debug("udp.py havoc id {}".format(id(havoc_monitor)))
94
+ udp_socket.settimeout(2.0)
95
+ buffer_size = 4096
96
+ counter = 0
97
+
98
+ while True:
99
+
100
+ try: # timeout (non-blocking behaviour) added because in warm-start, listener is not working sometimes
101
+ counter += 1
102
+ logger.debug("counter: {}".format(counter))
103
+ logger.debug("Going to call recv from api for {} time".format(counter))
104
+ logger.debug("Going to call recv from api")
105
+ data, address = udp_socket.recvfrom(buffer_size)
106
+ logger.debug("incoming received message = {} from address {}".format(data, address))
107
+ logger.debug("after gettting message")
108
+
109
+ output = str(data)
110
+
111
+ if output[2:5] == "[\\n": # Output starts with b'[\n
112
+ process_udp_agent_init_response(output, agent_obj)
113
+ continue
114
+
115
+ if output == "b'Heart Beat Received'":
116
+ logger.debug("ignoring heartbeat acknowledgement")
117
+ continue
118
+ try:
119
+ body, header_dict = process_raw_havoc_message(output, agent_obj.cav_env)
120
+ havoc_monitor.parse_nethavoc_config(body, header_dict)
121
+
122
+ except Exception as e:
123
+ logger.warning("Unable to parse config: {}", e)
124
+
125
+ except socket.timeout:
126
+ logger.debug("recv timed out") # This is not an exception, but a mechanism to implement timeout
127
+
128
+
129
+ def generate_bt():
130
+ id = uuid.uuid4()
131
+ id_int = id.int
132
+ return id_int
133
+
134
+
135
+ def sdk_init(agent_obj):
136
+ agent_obj.udp_connection = UDPConnection(agent_obj)
137
+ logger.debug("called sdk init")
138
+ context = agent_obj.get_transaction_context()
139
+ if not context:
140
+ from pythonagent.agent.internal.agent import TransactionContext
141
+ context = TransactionContext() # Create dummy context to avoid failure
142
+ logger.debug("transaction context dictionary inside sdk init in udp.py {}".format(context.function_name))
143
+ message = create_init_message(context, agent_obj)
144
+ logger.debug("first message to be sent to proxy {}".format(message))
145
+ agent_obj.udp_connection.send(message)
146
+ logger.debug("init sent")
147
+
148
+ message = create_agent_initialize_message(context, agent_obj)
149
+ logger.debug("sending agent initialize message {}".format(message))
150
+ agent_obj.udp_connection.send(message)
151
+ logger.debug("sent agent initialize message")
152
+ return udp_connection
153
+
154
+
155
+ def sdk_free(agent_obj):
156
+ pass
157
+
158
+
159
+ def method_entry(agent_obj, bt, method, query_string, url_parameter, query_parameter="NA"):
160
+ context = agent_obj.get_transaction_context()
161
+ message = create_method_entry_message(context, bt, method, query_string, url_parameter, query_parameter, agent_obj)
162
+
163
+ logger.info("method_entry {}".format(message))
164
+ agent_obj.udp_connection.send(message)
165
+
166
+
167
+ def method_exit(agent_obj, bt, method, backend_header, status, duration):
168
+ context = agent_obj.get_transaction_context()
169
+ # message = create_method_exit_message(context, bt, method)
170
+ message = create_method_exit_message(context, bt, method, backend_header, status, duration, agent_obj)
171
+ logger.info("method_exit: status {}, duration {}, message {}".format(status, duration, message))
172
+ agent_obj.udp_connection.send(message)
173
+
174
+
175
+ def start_business_transaction(agent_obj, bt_name, correlation_header):
176
+ if os.environ['nd_init_done'] == '0':
177
+ agent_obj.sdk_init()
178
+
179
+ context = agent_obj.get_transaction_context()
180
+ # message = udp_message.create_start_transaction_message(context, bt_name, correlation_header)
181
+ message = create_start_transaction_message(context, bt_name, correlation_header, agent_obj)
182
+ logger.info("start_business_transaction {}".format(message))
183
+ agent_obj.udp_connection.send(message, "start_fp")
184
+
185
+ bt = generate_bt()
186
+
187
+ agent_obj.active_bts.add(bt)
188
+ agent_obj.set_current_bt(bt)
189
+
190
+ return bt
191
+
192
+
193
+ def end_business_transaction(agent_obj, bt):
194
+ status_code = agent_obj.get_current_status_code()
195
+ context = agent_obj.get_transaction_context()
196
+ message = create_end_transaction_message(context, bt, status_code, agent_obj)
197
+
198
+ agent_obj.logger.info("status_code {}, message {}".format(status_code, message))
199
+
200
+ agent_obj.udp_connection.send(message)
201
+ rc = 0 # DUMMY VALUE FOR SUCCESS
202
+ agent_obj.reset_transaction_context()
203
+
204
+ return rc
205
+
206
+
207
+ def store_business_transaction(agent_obj, bt, unique_bt_id):
208
+ pass
209
+
210
+
211
+ def db_call_begin(bt, db_host, db_query, db_query_params=None):
212
+ pass
213
+
214
+
215
+ def db_call_end(bt, ip_handle):
216
+ pass
217
+
218
+
219
+ def http_call_begin(agent_obj, bt, http_host, url):
220
+ handle = 0 # DUMMY NON ZERO VALUE
221
+ return handle
222
+
223
+
224
+ def http_call_end(agent_obj, bt, ip_handle):
225
+ pass
226
+
227
+ def http_req_resp_wrapper(agent_obj, bt, rbuffer, rtype, statuscode):
228
+ context = agent_obj.get_transaction_context()
229
+ message = create_transaction_encode_http_message(context, bt, rbuffer, rtype, statuscode, agent_obj)
230
+ logger.info("transaction_encode_http message {}".format(message))
231
+ agent_obj.udp_connection.send(message)
232
+
233
+ def exception_dump(agent_obj, bt, mpp, starttime, excptnclsname, excptnmsg, throwingclsname,
234
+ throwingmtdname, excptncause, excptnlineno, stacktrace):
235
+ context = agent_obj.get_transaction_context()
236
+ message = create_exception_encode_message(context, excptnlineno, excptnclsname, throwingclsname, throwingmtdname,
237
+ excptnmsg, excptncause, stacktrace, starttime, agent_obj)
238
+ logger.info("exception_encode message {}".format(message))
239
+ agent_obj.udp_connection.send(message)
240
+
241
+ def havoc_message(agent_obj, havoc_header):
242
+ context = agent_obj.get_transaction_context()
243
+ message = create_havoc_message(context, havoc_header, agent_obj)
244
+ logger.debug("havoc_message: {}".format(message))
245
+ agent_obj.udp_connection.send(message)