appmap 2.0.7__tar.gz → 2.0.9__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.
- {appmap-2.0.7 → appmap-2.0.9}/PKG-INFO +1 -1
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/env.py +28 -1
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/event.py +3 -1
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/instrument.py +3 -2
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/recorder.py +24 -2
- {appmap-2.0.7 → appmap-2.0.9}/pyproject.toml +1 -1
- {appmap-2.0.7 → appmap-2.0.9}/vendor/_appmap/wrapt/wrappers.py +6 -7
- {appmap-2.0.7 → appmap-2.0.9}/LICENSE +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/README.md +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/configuration.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/django.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/fastapi.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/flask.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/generation.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/importer.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/labels.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/metadata.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/noappmap.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/py_version_check.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/recording.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/remote_recording.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/singleton.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/appmap_test_base.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/bin/server_runner +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/conftest.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-all-paths-malformed.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-broken.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-class.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-empty-path.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-exclude-fn.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-func.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-malformed-path.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap-no-pyyaml.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap_testing/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/appmap_testing/django_simplelazyobject.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config/src/package/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config/test/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config/test/foo.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-exclude/.hide/hidden_mod/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-exclude/node_modules/node_mod/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-exclude/src/package/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-exclude/test/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-exclude/venv/venv_mod/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-up/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-up/project/p1/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-up/project/p2/sub1/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/djangoapp.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/hello_world.html +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/middleware.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/settings.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/settings_dev.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/djangoapp/urls.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/init/sitecustomize.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/manage.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/pytest.ini +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/test/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/django/test/test_app.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/example_class.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/expected.appmap.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/fastapi/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/fastapi/fastapiapp/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/fastapi/fastapiapp/main.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/fastapi/init/sitecustomize.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/fastapi/test_app.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/flask/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/flask/flaskapp.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/flask/init/sitecustomize.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/flask/templates/test.html +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/flask/test_app.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/package1/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/package1/package2/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/package1/package2/__main__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/package1/package2/mod1.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/params.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/expected/pytest.appmap.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/expected/status_errored.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/expected/status_failed.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/expected/status_xfailed.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/simple.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/test_noappmap.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/test_simple.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/remote.appmap.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/trial/.gitignore +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/trial/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/trial/expected/pytest.appmap.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/trial/init/sitecustomize.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/trial/test/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/trial/test/test_deferred.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/appmap.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/pytest.appmap.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_errored.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_failed.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_xfailed.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_xsucceeded.metadata.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/unittest.appmap.json +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/init/sitecustomize.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/simple/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/simple/test_noappmap.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/simple/test_simple.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/helpers.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/normalize.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_command.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_configuration.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_describe_value.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_django.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_django_simplelazyobject.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_env.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_events.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_fastapi.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_flask.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_generation.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_http.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_importer.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_labels.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_metadata.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_params.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_recording.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_runner.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_sqlalchemy.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_test_frameworks.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/test_util.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/test/web_framework.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/testing_framework.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/trace_logger.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/unittest.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/utils.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/_appmap/web_framework.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/command/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/command/appmap_agent_init.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/command/appmap_agent_status.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/command/appmap_agent_validate.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/command/runner.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/django.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/fastapi.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/flask.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/http.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/crypto.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/django.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/flask.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/formats.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/http.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/jobs.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/jwt.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/logger.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/labeling/random.yml +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/pytest.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/sqlalchemy.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/unittest.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap/uvicorn.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/appmap.pth +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/vendor/_appmap/wrapt/LICENSE +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/vendor/_appmap/wrapt/__init__.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/vendor/_appmap/wrapt/arguments.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/vendor/_appmap/wrapt/decorators.py +0 -0
- {appmap-2.0.7 → appmap-2.0.9}/vendor/_appmap/wrapt/importer.py +0 -0
|
@@ -37,6 +37,7 @@ class Env(metaclass=SingletonMeta):
|
|
|
37
37
|
else:
|
|
38
38
|
self._env.pop(k, None)
|
|
39
39
|
|
|
40
|
+
self.log_file_creation_failed = False
|
|
40
41
|
self._configure_logging()
|
|
41
42
|
enabled = self._env.get("_APPMAP", "false")
|
|
42
43
|
self._enabled = enabled is None or enabled.lower() != "false"
|
|
@@ -133,6 +134,21 @@ class Env(metaclass=SingletonMeta):
|
|
|
133
134
|
def getLogger(self, name) -> trace_logger.TraceLogger:
|
|
134
135
|
return cast(trace_logger.TraceLogger, logging.getLogger(name))
|
|
135
136
|
|
|
137
|
+
def determine_log_file(self):
|
|
138
|
+
log_file = "appmap.log"
|
|
139
|
+
|
|
140
|
+
# Try creating the log file in the current directory
|
|
141
|
+
try:
|
|
142
|
+
with open(log_file, 'a', encoding='UTF8'):
|
|
143
|
+
pass
|
|
144
|
+
except IOError:
|
|
145
|
+
# The circumstances in which creation is going to fail
|
|
146
|
+
# are also those in which the user doesn't care whether
|
|
147
|
+
# there's a log file (e.g. when starting a REPL).
|
|
148
|
+
return None
|
|
149
|
+
return log_file
|
|
150
|
+
|
|
151
|
+
|
|
136
152
|
def _configure_logging(self):
|
|
137
153
|
trace_logger.install()
|
|
138
154
|
|
|
@@ -179,13 +195,19 @@ class Env(metaclass=SingletonMeta):
|
|
|
179
195
|
log_level = self.get("APPMAP_LOG_LEVEL", "info").upper()
|
|
180
196
|
loggers = config_dict["loggers"]
|
|
181
197
|
loggers["appmap"]["level"] = loggers["_appmap"]["level"] = log_level
|
|
198
|
+
|
|
199
|
+
log_file = self.determine_log_file()
|
|
200
|
+
# Use NullHandler if log_file is None to avoid complicating the configuration
|
|
201
|
+
# with the absence of the "default" handler.
|
|
182
202
|
config_dict["handlers"] = {
|
|
183
203
|
"default": {
|
|
184
204
|
"class": "logging.handlers.RotatingFileHandler",
|
|
185
205
|
"formatter": "default",
|
|
186
|
-
"filename":
|
|
206
|
+
"filename": log_file,
|
|
187
207
|
"maxBytes": 50 * 1024 * 1024,
|
|
188
208
|
"backupCount": 1,
|
|
209
|
+
} if log_file is not None else {
|
|
210
|
+
"class": "logging.NullHandler"
|
|
189
211
|
},
|
|
190
212
|
"stderr": {
|
|
191
213
|
"class": "logging.StreamHandler",
|
|
@@ -194,6 +216,7 @@ class Env(metaclass=SingletonMeta):
|
|
|
194
216
|
"stream": "ext://sys.stderr",
|
|
195
217
|
},
|
|
196
218
|
}
|
|
219
|
+
self.log_file_creation_failed = log_file is None
|
|
197
220
|
|
|
198
221
|
if log_config is not None:
|
|
199
222
|
name, level = log_config.split("=", 2)
|
|
@@ -213,3 +236,7 @@ def initialize(**kwargs):
|
|
|
213
236
|
Env.reset(**kwargs)
|
|
214
237
|
logger = logging.getLogger(__name__)
|
|
215
238
|
logger.info("appmap enabled: %s", Env.current.enabled)
|
|
239
|
+
if Env.current.log_file_creation_failed:
|
|
240
|
+
# Writing to stderr makes the REPL fail in vscode-python.
|
|
241
|
+
# https://github.com/microsoft/vscode-python/blob/c71c85ebf3749d5fac76899feefb21ee321a4b5b/src/client/common/process/rawProcessApis.ts#L268-L269
|
|
242
|
+
logger.info("appmap.log cannot be created")
|
|
@@ -111,7 +111,9 @@ def describe_value(name, val, max_depth=5):
|
|
|
111
111
|
"object_id": id(val),
|
|
112
112
|
"value": display_string(val),
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
if Env.current.display_params:
|
|
115
|
+
ret.update(_describe_schema(name, val, 0, max_depth))
|
|
116
|
+
|
|
115
117
|
if any(_is_list_or_dict(type(val))):
|
|
116
118
|
ret["size"] = len(val)
|
|
117
119
|
|
|
@@ -6,7 +6,7 @@ from contextlib import contextmanager
|
|
|
6
6
|
from . import event
|
|
7
7
|
from .env import Env
|
|
8
8
|
from .event import CallEvent
|
|
9
|
-
from .recorder import Recorder,
|
|
9
|
+
from .recorder import Recorder, AppMapLimitExceeded
|
|
10
10
|
from .utils import appmap_tls
|
|
11
11
|
|
|
12
12
|
logger = Env.current.getLogger(__name__)
|
|
@@ -90,6 +90,7 @@ def call_instrumented(f, instance, args, kwargs):
|
|
|
90
90
|
call_event_id = call_event.id
|
|
91
91
|
start_time = time.time()
|
|
92
92
|
try:
|
|
93
|
+
Recorder.check_time(start_time)
|
|
93
94
|
ret = f.fn(*args, **kwargs)
|
|
94
95
|
elapsed_time = time.time() - start_time
|
|
95
96
|
|
|
@@ -98,7 +99,7 @@ def call_instrumented(f, instance, args, kwargs):
|
|
|
98
99
|
)
|
|
99
100
|
Recorder.add_event(return_event)
|
|
100
101
|
return ret
|
|
101
|
-
except
|
|
102
|
+
except AppMapLimitExceeded:
|
|
102
103
|
raise
|
|
103
104
|
except Exception: # noqa: E722
|
|
104
105
|
elapsed_time = time.time() - start_time
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import threading
|
|
2
|
+
import time
|
|
2
3
|
import traceback
|
|
3
4
|
from abc import ABC, abstractmethod
|
|
4
5
|
|
|
@@ -17,11 +18,23 @@ _MAX_EVENTS = Env.current.get("APPMAP_MAX_EVENTS")
|
|
|
17
18
|
if _MAX_EVENTS is not None:
|
|
18
19
|
_MAX_EVENTS = int(_MAX_EVENTS)
|
|
19
20
|
|
|
21
|
+
_MAX_TIME = Env.current.get("APPMAP_MAX_TIME")
|
|
22
|
+
if _MAX_TIME is not None:
|
|
23
|
+
_MAX_TIME = int(_MAX_TIME)
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
|
|
26
|
+
class AppMapLimitExceeded(RuntimeError):
|
|
27
|
+
"""Class of events thrown when some limit has been exceeded"""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AppMapTooManyEvents(AppMapLimitExceeded):
|
|
22
31
|
"""Thrown when a recorder has more than APPMAP_MAX_EVENTS"""
|
|
23
32
|
|
|
24
33
|
|
|
34
|
+
class AppMapSessionTooLong(AppMapLimitExceeded):
|
|
35
|
+
"""Throw when an individual recording session has exceeded APPMAP_MAX_TIME"""
|
|
36
|
+
|
|
37
|
+
|
|
25
38
|
class Recorder(ABC):
|
|
26
39
|
"""
|
|
27
40
|
A base class for Recorders.
|
|
@@ -97,6 +110,13 @@ class Recorder(ABC):
|
|
|
97
110
|
def stop_recording(cls):
|
|
98
111
|
return cls.get_current()._stop_recording() # pylint: disable=protected-access
|
|
99
112
|
|
|
113
|
+
@classmethod
|
|
114
|
+
def check_time(cls, event_time):
|
|
115
|
+
if _MAX_TIME is None:
|
|
116
|
+
return
|
|
117
|
+
if event_time - cls.get_current()._start_time > _MAX_TIME:
|
|
118
|
+
raise AppMapSessionTooLong(f"Session exceeded {_MAX_TIME} seconds")
|
|
119
|
+
|
|
100
120
|
@classmethod
|
|
101
121
|
def add_event(cls, event):
|
|
102
122
|
"""
|
|
@@ -124,6 +144,7 @@ class Recorder(ABC):
|
|
|
124
144
|
self._events = []
|
|
125
145
|
self._enabled = enabled
|
|
126
146
|
self.start_tb = None
|
|
147
|
+
self._start_time = None
|
|
127
148
|
|
|
128
149
|
@abstractmethod
|
|
129
150
|
def _start_recording(self):
|
|
@@ -134,6 +155,7 @@ class Recorder(ABC):
|
|
|
134
155
|
raise RuntimeError("Recording already in progress")
|
|
135
156
|
self.start_tb = traceback.extract_stack()
|
|
136
157
|
self._enabled = True
|
|
158
|
+
self._start_time = time.time()
|
|
137
159
|
|
|
138
160
|
@abstractmethod
|
|
139
161
|
def _stop_recording(self):
|
|
@@ -150,7 +172,7 @@ class Recorder(ABC):
|
|
|
150
172
|
self._events.append(event)
|
|
151
173
|
if _MAX_EVENTS is not None and len(self._events) > _MAX_EVENTS:
|
|
152
174
|
Recorder._aborting = True
|
|
153
|
-
raise AppMapTooManyEvents()
|
|
175
|
+
raise AppMapTooManyEvents(f"Session exceeded {_MAX_EVENTS} events")
|
|
154
176
|
|
|
155
177
|
@staticmethod
|
|
156
178
|
def _initialize():
|
|
@@ -457,9 +457,11 @@ class ObjectProxy(with_metaclass(_ObjectProxyMetaType)):
|
|
|
457
457
|
raise NotImplementedError(
|
|
458
458
|
'object proxy must define __reduce_ex__()')
|
|
459
459
|
|
|
460
|
+
# Return the qualname of the wrapped function instead of a tuple. This allows an instance of
|
|
461
|
+
# subclasses to be pickled as the function it wraps. This seems to be adequate for generating
|
|
462
|
+
# AppMaps.
|
|
460
463
|
def __reduce_ex__(self, protocol):
|
|
461
|
-
|
|
462
|
-
'object proxy must define __reduce_ex__()')
|
|
464
|
+
return self.__wrapped__.__qualname__
|
|
463
465
|
|
|
464
466
|
class CallableObjectProxy(ObjectProxy):
|
|
465
467
|
|
|
@@ -740,12 +742,9 @@ class FunctionWrapper(_FunctionWrapperBase):
|
|
|
740
742
|
# new FunctionWrapper will be created. If it doesn't, then __reduce_ex__ can simply return a
|
|
741
743
|
# string, which would cause deepcopy to return the original FunctionWrapper.
|
|
742
744
|
#
|
|
743
|
-
# Update: We'll return the qualname of the wrapped function instead of a tuple allows a
|
|
744
|
-
# FunctionWrapper to be pickled (as the function it wraps). This seems to be adequate for
|
|
745
|
-
# generating AppMaps, so go with that.
|
|
746
745
|
|
|
747
|
-
def __reduce_ex__(self, protocol):
|
|
748
|
-
|
|
746
|
+
# def __reduce_ex__(self, protocol):
|
|
747
|
+
# return self.__wrapped__.__qualname__
|
|
749
748
|
|
|
750
749
|
# return FunctionWrapper, (
|
|
751
750
|
# self.__wrapped__,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/config-exclude/node_modules/node_mod/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/expected/status_errored.metadata.json
RENAMED
|
File without changes
|
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/pytest/expected/status_xfailed.metadata.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_errored.metadata.json
RENAMED
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_failed.metadata.json
RENAMED
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_xfailed.metadata.json
RENAMED
|
File without changes
|
{appmap-2.0.7 → appmap-2.0.9}/_appmap/test/data/unittest/expected/status_xsucceeded.metadata.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|