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,174 @@
1
+
2
+
3
+ """Intercept the psycopg2 package.
4
+
5
+ The interceptors in here are more complex than for other packages because the
6
+ classes are defined in C extension code. We have to wrap the connection and
7
+ cursor classes with our own, which allows us to attach to the relevant methods.
8
+
9
+ """
10
+
11
+ # pylint: disable=no-self-argument
12
+
13
+ from __future__ import unicode_literals
14
+ import re
15
+
16
+ from pythonagent.lang import parse_qs, str, urlparse
17
+ from ..base import BaseInterceptor
18
+ from .dbapi import DbAPIConnectionInterceptor, DbAPICursorInterceptor
19
+
20
+ # For format of PostgreSQL connection strings, see:
21
+ # http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
22
+
23
+ KV_RE = re.compile(r'\s*(?P<key>[a-zA-Z_]+)\s*=\s*(?P<remainder>.+)')
24
+
25
+
26
+ def parse_postgresql_url_dsn(dsn):
27
+ url = urlparse(dsn, allow_fragments=False)
28
+
29
+ if '?' in url.path:
30
+ parts = url.path.split('?', 1)
31
+ path, params = parts[0], parse_qs(parts[1])
32
+ else:
33
+ path = url.path
34
+ params = parse_qs(url.query) if url.query else {}
35
+
36
+ if 'host' in params:
37
+ host = params['host'][0]
38
+ else:
39
+ host = url.hostname or 'localhost'
40
+
41
+ if 'port' in params:
42
+ port = params['port'][0]
43
+ elif url.port:
44
+ port = str(url.port)
45
+ else:
46
+ port = '5432'
47
+
48
+ path = path.strip('/')
49
+
50
+ if 'dbname' in params:
51
+ dbname = params['dbname'][0]
52
+ elif path:
53
+ dbname = path
54
+ elif 'user' in params:
55
+ dbname = params['user'][0]
56
+ else:
57
+ dbname = url.username or 'postgres'
58
+
59
+ return host, port, dbname
60
+
61
+
62
+ def parse_quoted_value(remainder):
63
+ length = len(remainder)
64
+ idx = 1
65
+
66
+ start_idx = idx
67
+ val = []
68
+
69
+ while idx < length and remainder[idx] != "'":
70
+ if remainder[idx:idx + 2] in ("\\\\", "\\'"):
71
+ # Valid escape sequence: collect the current run with the
72
+ # escaped character, move past the escape sequence, and start a
73
+ # new run.
74
+ val.append(remainder[start_idx:idx] + remainder[idx + 1])
75
+ idx += 2
76
+ start_idx = idx
77
+ else:
78
+ idx += 1
79
+
80
+ val.append(remainder[start_idx:idx])
81
+ return ''.join(val), remainder[idx + 1:]
82
+
83
+
84
+ def parse_postgresql_kv_dsn(dsn):
85
+ if "'" not in dsn: # Fast path when there are no quoted strings.
86
+ dsn = re.sub(r'(\s*=\s+|\s+=\s*)', '=', dsn).split()
87
+ parts = dict(pair.split('=', 1) for pair in dsn)
88
+ else:
89
+ parts = {}
90
+ m = KV_RE.match(dsn)
91
+
92
+ while m:
93
+ key, remainder = m.group('key'), m.group('remainder')
94
+
95
+ if remainder[0] == "'":
96
+ value, remainder = parse_quoted_value(remainder)
97
+ else:
98
+ split = remainder.split(None, 1)
99
+ if len(split) == 1:
100
+ value, remainder = split[0], ''
101
+ elif split:
102
+ value, remainder = split
103
+ else:
104
+ break
105
+
106
+ parts[key] = value
107
+ m = KV_RE.match(remainder)
108
+
109
+ return parse_postgresql_keyword_args(parts)
110
+
111
+
112
+ def parse_postgresql_keyword_args(parts):
113
+ host = parts.get('host', 'localhost')
114
+ port = parts.get('port', '5432')
115
+ dbname = parts.get('dbname', parts.get('user', 'postgres'))
116
+ user = parts.get('user', 'postgres')
117
+ return host, port, dbname, user
118
+
119
+
120
+ def parse_postgresql_dsn(dsn=None, *args, **kwargs):
121
+ if dsn:
122
+ if dsn.startswith('postgresql://'):
123
+ return parse_postgresql_url_dsn(dsn)
124
+ else:
125
+ return parse_postgresql_kv_dsn(dsn)
126
+ else:
127
+ return parse_postgresql_keyword_args(kwargs)
128
+
129
+
130
+ class Psycopg2ConnectionInterceptor(DbAPIConnectionInterceptor):
131
+ def get_backend_properties(self, conn, *args, **kwargs):
132
+ return parse_postgresql_dsn(*args, **kwargs) + ('POSTGRES',)
133
+
134
+
135
+ class Psycopg2CursorInterceptor(DbAPICursorInterceptor):
136
+ def get_connection(self, cursor):
137
+ return cursor.connection
138
+
139
+
140
+ class Psycopg2Interceptor(BaseInterceptor):
141
+ cursor_classes = {}
142
+
143
+ def _connect(self, connect, *args, **kwargs):
144
+ connection_factory = kwargs.pop('connection_factory', None) or self.cls.extensions.connection
145
+
146
+ class Connection(connection_factory):
147
+ def __init__(conn, *args, **kwargs):
148
+ super(Connection, conn).__init__(*args, **kwargs)
149
+
150
+ def cursor(conn, *args, **kwargs):
151
+ cursor_factory = kwargs.pop('cursor_factory', None) or conn.cursor_factory or self.cls.extensions.cursor
152
+ try:
153
+ # we store these wrapper classes to avoid 're-instrumenting' each time
154
+ cursor_class = self.cursor_classes[cursor_factory]
155
+ except KeyError:
156
+ class Cursor(cursor_factory):
157
+ def execute(curs, *args, **kwargs):
158
+ return super(Cursor, curs).execute(*args, **kwargs)
159
+
160
+ def executemany(curs, *args, **kwargs):
161
+ return super(Cursor, curs).executemany(*args, **kwargs)
162
+ self.cursor_classes[cursor_factory] = Cursor
163
+ cursor_class = Cursor
164
+ return super(Connection, conn).cursor(cursor_factory=cursor_class, *args, **kwargs)
165
+
166
+ Psycopg2ConnectionInterceptor(
167
+ self.agent, Connection, Psycopg2CursorInterceptor).attach('__init__')
168
+
169
+ return connect(connection_factory=Connection, *args, **kwargs)
170
+
171
+
172
+ def intercept_psycopg2_connection(agent, mod):
173
+ agent.logger.warning("Instrument module: psycopg2{}".format(", mod: {}".format(mod) if mod else ""))
174
+ Psycopg2Interceptor(agent, mod).attach('connect')
@@ -0,0 +1,25 @@
1
+
2
+ """Intercept the pymysql package.
3
+
4
+ """
5
+
6
+ from __future__ import unicode_literals
7
+
8
+ from .dbapi import DbAPIConnectionInterceptor, DbAPICursorInterceptor
9
+
10
+
11
+ class PymysqlConnectionInterceptor(DbAPIConnectionInterceptor):
12
+ def get_backend_properties(self, conn, *args, **kwargs):
13
+ conn.db_type = "MYSQL"
14
+ # self.agent.get_transaction_context().dbhost = conn.host
15
+ return conn.host, conn.port, conn.db, conn.user, conn.db_type
16
+
17
+
18
+ class PymysqlCursorInterceptor(DbAPICursorInterceptor):
19
+ def get_connection(self, cursor):
20
+ return cursor.connection
21
+
22
+
23
+ def intercept_pymysql_connections(agent, mod):
24
+ agent.logger.warning("Instrument module: pymysql.connections{}".format(", mod: {}".format(mod) if mod else ""))
25
+ PymysqlConnectionInterceptor(agent, mod.Connection, PymysqlCursorInterceptor).attach('connect')
File without changes
@@ -0,0 +1,26 @@
1
+ # Cavisson Python Agent — gunicorn integration config
2
+ #
3
+ # This file is a ready-to-use gunicorn config that bootstraps the Cavisson agent
4
+ # in each worker process without requiring changes to your own gunicorn.conf.
5
+ #
6
+ # Usage (add to gunicorn command):
7
+ # gunicorn -c $NDHOME/python/config/cav_gunicorn.py myapp:application
8
+ #
9
+ # If you already have a gunicorn config file, place cav_gunicorn.py FIRST:
10
+ # gunicorn -c $NDHOME/python/config/cav_gunicorn.py -c your_gunicorn.conf myapp:application
11
+ #
12
+ # Note: When multiple -c files define the same function (e.g. post_fork), the
13
+ # LAST config wins. Place your own config after cav_gunicorn.py so your post_fork
14
+ # takes precedence; ensure your post_fork also calls agent.bootstrap() if needed.
15
+ #
16
+ # This file is a fallback for environments where sitecustomize.py is not on
17
+ # PYTHONPATH. When sitecustomize.py is active, auto-patching via Worker.init_process
18
+ # handles gunicorn worker bootstrap automatically without this file.
19
+
20
+ def post_fork(server, worker):
21
+ try:
22
+ import pythonagent.agent as _agent
23
+ _agent.configure()
24
+ _agent.bootstrap()
25
+ except Exception:
26
+ pass
@@ -0,0 +1,291 @@
1
+ from __future__ import unicode_literals
2
+ import imp
3
+ import os
4
+ import warnings
5
+ import logging
6
+ import sys
7
+ from subprocess import call
8
+ import subprocess
9
+ import uuid
10
+ import datetime
11
+ import time
12
+
13
+ is_lambda = True
14
+
15
+ if is_lambda:
16
+ os.environ.setdefault("NDHOME", "/opt/python/pythonagent/cavisson/netdiagnostics")
17
+ sys.path.insert(1, '/opt')
18
+
19
+ os.environ.setdefault("CAVISSON_APP_NAME", os.getenv("AWS_LAMBDA_FUNCTION_NAME", ""))
20
+ os.environ.setdefault("CAVISSON_NO_CONFIG_FILE", "true")
21
+ os.environ.setdefault("CAVISSON_DISTRIBUTED_TRACING_ENABLED", "true")
22
+ os.environ.setdefault("CAVISSON_SERVERLESS_MODE_ENABLED", "true")
23
+ os.environ.setdefault("CAVISSON_TRUSTED_ACCOUNT_KEY", os.getenv("CAVISSON_ACCOUNT_ID", ""))
24
+
25
+ _agent = None
26
+ logger = None
27
+
28
+ try:
29
+ import pythonagent.agent as agent
30
+ agent.configure()
31
+ #_agent = agent.bootstrap()
32
+ _agent = agent.get_agent_instance()
33
+ #_agent.init_sent = True
34
+
35
+ except:
36
+ print("import error in Agent")
37
+ logger = logging.getLogger('pythonagent.agent')
38
+ logger.exception('Exception in agent startup.')
39
+ finally:
40
+ pass
41
+
42
+ if _agent is None:
43
+ raise ValueError("Failed to initialize agent")
44
+
45
+ from pythonagent.agent.internal.agent import TransactionContext
46
+
47
+ # from pythonagent.agent.probes.havoc.havoc_manager import NDNetHavocMonitor, NDHavocException
48
+
49
+
50
+ def get_handler():
51
+ print("inside get_handler function first", sys.executable)
52
+ modandpackage = os.path.abspath('.')
53
+ mod = sys.modules[__name__]
54
+ print("inside get_handler function mod", mod)
55
+ try:
56
+ sys.path.remove(os.path.dirname(__file__))
57
+ except ValueError: # directory not in sys.path
58
+ pass
59
+
60
+
61
+ if (
62
+ "CAVISSON_LAMBDA_HANDLER" not in os.environ
63
+ or not os.environ["CAVISSON_LAMBDA_HANDLER"]
64
+ ):
65
+ raise ValueError(
66
+ "No value specified in CAVISSON_LAMBDA_HANDLER environment variable"
67
+ )
68
+
69
+ try:
70
+ module_path, handler_name = os.environ["CAVISSON_LAMBDA_HANDLER"].rsplit(
71
+ ".", 1
72
+ )
73
+ print("inside get_handler function module_path, handler name: ", module_path, handler_name)
74
+
75
+ except ValueError:
76
+ raise ValueError(
77
+ "Improperly formated handler value: %s"
78
+ % os.environ["CAVISSON_LAMBDA_HANDLER"]
79
+ )
80
+
81
+ file_handle, pathname, desc = None, None, None
82
+
83
+ try:
84
+ for segment in module_path.split("."):
85
+ if pathname is not None:
86
+ pathname = [pathname]
87
+
88
+ file_handle, pathname, desc = imp.find_module(segment, pathname)
89
+
90
+ if file_handle is None:
91
+ module_type = desc[2]
92
+ if module_type == imp.C_BUILTIN:
93
+ raise ImportError(
94
+ "Cannot use built-in module %s as a handler module" % module_path
95
+ )
96
+
97
+ print("inside get_handler function module_path, file_handle, pathname, desc", module_path, file_handle, pathname, desc)
98
+
99
+ module = imp.load_module(module_path, file_handle, pathname, desc)
100
+ print("inside get_handler function module in cavagent_lambda_wrapper ", module)
101
+
102
+
103
+ except Exception as e:
104
+ print("Module not found")
105
+ raise ImportError("Failed to import module '%s': %s" % (module_path, e))
106
+ finally:
107
+ if file_handle is not None:
108
+ file_handle.close()
109
+
110
+ try:
111
+ handler = getattr(module, handler_name)
112
+ print("inside get_handler function handler", handler)
113
+ except AttributeError:
114
+ print("NO HANDLER FOUND")
115
+ raise AttributeError(
116
+ "No handler '%s' in module '%s'" % (handler_name, module_path)
117
+ )
118
+
119
+ return handler, handler_name, modandpackage
120
+
121
+
122
+ def local_customer_application(event, context):
123
+ from .run import db_callout, flask_wsgi, http_callout, first
124
+ print("inside local_customer_application function Lambda Handler Function")
125
+
126
+ first()
127
+ # second()
128
+ # http_callout()
129
+ # db_callout()
130
+ # flask_wsgi()
131
+
132
+ return "Nothing"
133
+
134
+
135
+ def local_lambda_handler():
136
+ #for i in range(100):
137
+ # print(1)
138
+ class TestObj:
139
+ def __init__(self):
140
+ self.__module__ = "test"
141
+
142
+ t = TestObj()
143
+ return t , "test", "test"
144
+
145
+ # Greedily load the handler during cold start, so we don't pay for it on first invoke
146
+
147
+
148
+ def wrapped_handler(event, context, is_lambda):
149
+ if is_lambda:
150
+ a, b, c = get_handler()
151
+ else:
152
+ a, b, c = local_lambda_handler()
153
+ return a, b, c
154
+
155
+
156
+ def handler(event, context):
157
+ context_obj = TransactionContext()
158
+ start_time = datetime.datetime.now()
159
+
160
+ if context.aws_request_id is not None:
161
+ context_obj.aws_request_id = context.aws_request_id
162
+ else:
163
+ context_obj.aws_request_id = "default_aws_request_id"
164
+
165
+ if context.function_name is not None:
166
+ context_obj.function_name = context.function_name
167
+ else:
168
+ context_obj.function_name = "default"
169
+ print("function name inside context object in cavwrapper handler", context_obj.function_name)
170
+
171
+
172
+ try:
173
+ # context_obj.function_name = event['requestContext']['path']
174
+ context_obj.url_path = event['requestContext']['path']
175
+
176
+ except:
177
+ if "path" in event:
178
+ context_obj.url_path = event["path"]
179
+ else:
180
+ context_obj.url_path = context.function_name
181
+
182
+ if context.log_stream_name is not None:
183
+ context_obj.api_request_id = context.log_stream_name
184
+ else:
185
+ new_id = uuid.uuid4()
186
+ id_int = new_id.int
187
+ context_obj.api_request_id = id_int
188
+
189
+ _agent.set_transaction_context(context_obj)
190
+
191
+ from pythonagent.agent.probes.havoc.havoc_manager import NDNetHavocMonitor, NDHavocException
192
+ havoc_monitor = NDNetHavocMonitor.get_instance()
193
+
194
+ bt = None
195
+
196
+ try:
197
+ bt = _agent.start_business_transaction(context_obj.url_path, "")
198
+ except Exception as e:
199
+ print("Error occurred in Start Business transaction Call {}".format(e))
200
+
201
+ # import time
202
+ # print("Start fp done, sleep 30")
203
+ # time.sleep(30)
204
+
205
+ try:
206
+ handle, handler_name, modandpackage = wrapped_handler(event, context, is_lambda)
207
+ except Exception as e:
208
+ print("Error occurred in Calling Wrapped Handler {}".format(e))
209
+
210
+
211
+ print("inside handler function handle, handler_name, modandpackage IN CAVAGENT_LAMBDA_WRAPPER", handle, handler_name, modandpackage)
212
+ #fqmmethodentry = str(modandpackage) + "." + str(handler_name)
213
+ fqmmethodentry = str(handle.__module__) + "." + str(handler_name)
214
+
215
+ _agent.method_entry(bt, fqmmethodentry)
216
+
217
+ if is_lambda:
218
+ try:
219
+ response = handle(event, context) # Client Lambda Function
220
+ print("inside handler function RESPONSE IN LAMBDA IN CAVAGENT_LAMBDA_WRAPPER", response)
221
+ except Exception as e:
222
+ print("Error while invoking handler {}".format(e))
223
+ _agent.method_exit(bt, fqmmethodentry, 503)
224
+ _agent.set_current_status_code(503)
225
+ rc = _agent.end_business_transaction(bt)
226
+ havoc_monitor.refresh_configs(_agent)
227
+ raise e
228
+ else:
229
+ response = local_customer_application(event, context)
230
+ print("inside handler function RESPONSE IN LAMBDA IN CAVAGENT_LAMBDA_WRAPPER", response)
231
+
232
+ status_code = 200
233
+ try:
234
+ if "statusCode" in response:
235
+ status_code = response["statusCode"]
236
+
237
+ print("Inside handler function: response inside get_handler function firststatus code ", status_code)
238
+
239
+ except Exception as e:
240
+ print("Error occurred in get status code {}".format(e))
241
+
242
+
243
+
244
+ ###############################
245
+ # HAVOC
246
+ ###############################
247
+
248
+ # Apply Inbound Delay --> agent/start_business_transaction
249
+
250
+ # Apply Inbound Failure
251
+
252
+ try:
253
+ print("Url request: ", context_obj.url_path)
254
+ btname = _agent.get_transaction_context().btname if _agent.get_transaction_context() else None
255
+ havoc_monitor.apply_inbound_service_failure(context_obj.url_path, btname)
256
+
257
+ except Exception as e:
258
+ if isinstance(e, NDHavocException):
259
+ print("Havoc Exception {}".format(e))
260
+ _agent.method_exit(bt, fqmmethodentry, 503)
261
+ _agent.set_current_status_code(503)
262
+ rc = _agent.end_business_transaction(bt)
263
+ havoc_monitor.refresh_configs(_agent)
264
+ raise e
265
+ else:
266
+ print("Non-Havoc Exception {}".format(e))
267
+
268
+ # Apply Outbound Delay --> agent/method_entry_http_callout
269
+
270
+ # Apply Outbound Failure --> agent/probes/base.py/http_call_end
271
+ # --> agent/probes/sql/dynamodb.py/_cav_boto_api_method
272
+
273
+ # Apply Method Delay --> Instrumentation/__init__
274
+
275
+ # Apply Method Failure --> Instrumentation/__init__
276
+
277
+ ####################################################################################
278
+
279
+ # havoc_monitor.apply_outbound_service_failure("sample_hostname")
280
+
281
+ havoc_monitor.refresh_configs(_agent)
282
+
283
+ try:
284
+ _agent.method_exit(bt, fqmmethodentry, status_code)
285
+ _agent.set_current_status_code(status_code)
286
+ rc = _agent.end_business_transaction(bt)
287
+
288
+ except Exception as e:
289
+ print("Error occurred in End Business transaction Call {}".format(e))
290
+
291
+ return response
@@ -0,0 +1,47 @@
1
+ import requests
2
+ import boto3
3
+ from flask import Flask
4
+
5
+
6
+ def http_callout():
7
+ print("Client Lambda - HTTP Callout Begin")
8
+ x = requests.get('https://www.facebook.com/')
9
+ # x = requests.put('https://httpbin.org/put', data={'key': 'value'})
10
+ # x = requests.post('https://www.w3schools.com/python/demopage.php', data={'key': 'value'})
11
+ # x = requests.delete('https://httpbin.org/delete', data={'key': 'value'})
12
+ print("Client Lambda - HTTP Callout End")
13
+
14
+
15
+ def first():
16
+ print("Client Lambda - First Function")
17
+
18
+
19
+ def second():
20
+ print("Client Lambda - Second Function")
21
+
22
+
23
+ def db_callout():
24
+ print("Client Lambda - DB Callout Begin")
25
+ client = boto3.client('dynamodb')
26
+ print("client METHODS FOR THIS SESSION::", dir(client))
27
+ data = client.scan(TableName='Person')
28
+ item = {
29
+ "id": {"N": "556"},
30
+ "address": {"S": "United States"},
31
+ "firstName": {"S": "John"},
32
+ "lastName": {"S": "Doe"},
33
+ "age": {"N": "30"}
34
+ }
35
+ response = client.put_item(TableName='Person', Item=item)
36
+ print("Client Lambda - DB Call out Begin")
37
+
38
+
39
+ def flask_wsgi():
40
+ app = Flask(__name__)
41
+
42
+ @app.route("/")
43
+ def hello_world():
44
+ return "<p>Hello, World!</p>"
45
+
46
+ app.run(port=6063)
47
+