@appland/appmap 3.146.0 → 3.147.0
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.
- package/CHANGELOG.md +7 -0
- package/built/docs/CLA Instructions.pdf +0 -0
- package/built/docs/Code of Conduct for Contributors.pdf +0 -0
- package/built/docs/analysis/rules-reference.html +27 -0
- package/built/docs/appmap-docs.md +27 -0
- package/built/docs/community.md +28 -0
- package/built/docs/guides/exporting-appmap-diagrams.md +50 -0
- package/built/docs/guides/handling-large-appmap-diagrams.md +138 -0
- package/built/docs/guides/index.md +21 -0
- package/built/docs/guides/navigating-code-objects.md +67 -0
- package/built/docs/guides/openapi.md +105 -0
- package/built/docs/guides/reading-sql-in-appmap-diagrams.md +69 -0
- package/built/docs/guides/refine-appmap-data.md +186 -0
- package/built/docs/guides/reverse-engineering.md +377 -0
- package/built/docs/guides/runtime-code-review.md +111 -0
- package/built/docs/guides/using-appmap-analysis.md +206 -0
- package/built/docs/guides/using-appmap-diagrams.md +331 -0
- package/built/docs/integrations/atlassian-compass.md +25 -0
- package/built/docs/integrations/atlassian-confluence.md +51 -0
- package/built/docs/integrations/circle-ci.md +424 -0
- package/built/docs/integrations/docker.md +109 -0
- package/built/docs/integrations/github-actions.md +524 -0
- package/built/docs/integrations/index.md +20 -0
- package/built/docs/integrations/plantuml.md +66 -0
- package/built/docs/integrations/postman.md +30 -0
- package/built/docs/integrations/readme.md +39 -0
- package/built/docs/integrations/smartbear-swaggerhub.md +119 -0
- package/built/docs/reference/analysis-labels.md +49 -0
- package/built/docs/reference/analysis-rules.md +61 -0
- package/built/docs/reference/appmap-client-cli.md +628 -0
- package/built/docs/reference/appmap-gradle-plugin.md +141 -0
- package/built/docs/reference/appmap-java.md +311 -0
- package/built/docs/reference/appmap-maven-plugin.md +164 -0
- package/built/docs/reference/appmap-node.md +185 -0
- package/built/docs/reference/appmap-python.md +520 -0
- package/built/docs/reference/appmap-ruby.md +514 -0
- package/built/docs/reference/github-action.md +171 -0
- package/built/docs/reference/index.md +25 -0
- package/built/docs/reference/jetbrains.md +136 -0
- package/built/docs/reference/license-key-install.md +74 -0
- package/built/docs/reference/navie.md +261 -0
- package/built/docs/reference/remote-recording-api.md +97 -0
- package/built/docs/reference/uninstalling-appmap.md +119 -0
- package/built/docs/reference/vscode.md +122 -0
- package/built/docs/setup-appmap-in-ci/example-projects.md +21 -0
- package/built/docs/setup-appmap-in-ci/how-it-works.md +43 -0
- package/built/docs/setup-appmap-in-ci/in-circleci.md +423 -0
- package/built/docs/setup-appmap-in-ci/in-github-actions.md +177 -0
- package/built/docs/setup-appmap-in-ci/index.md +22 -0
- package/built/docs/setup-appmap-in-ci/matrix-builds.md +225 -0
- package/built/docs/setup-appmap-in-ci/troubleshooting.md +71 -0
- package/built/docs/setup-appmap-in-your-code-editor/add-appmap-to-your-code-editor.md +93 -0
- package/built/docs/setup-appmap-in-your-code-editor/appmap-analysis.md +77 -0
- package/built/docs/setup-appmap-in-your-code-editor/generate-appmap-data-from-tests.md +93 -0
- package/built/docs/setup-appmap-in-your-code-editor/generate-appmap-data-with-remote-recording.md +112 -0
- package/built/docs/setup-appmap-in-your-code-editor/generate-appmap-data-with-request-recording.md +77 -0
- package/built/docs/setup-appmap-in-your-code-editor/how-appmap-works.md +166 -0
- package/built/docs/setup-appmap-in-your-code-editor/index.md +25 -0
- package/built/docs/setup-appmap-in-your-code-editor/navigating-appmap-diagrams.md +59 -0
- package/built/docs/setup-appmap-in-your-code-editor/navigating-code-objects.md +67 -0
- package/built/docs/unused_for_now_index.html +11 -0
- package/package.json +2 -2
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
title: Docs - Reference
|
|
4
|
+
description: "Learn about the AppMap Agent for Node.js. Explore usage, configuration, tests, remote, request, and process recording."
|
|
5
|
+
toc: true
|
|
6
|
+
reference: true
|
|
7
|
+
name: AppMap Agent for Node.js
|
|
8
|
+
step: 6
|
|
9
|
+
redirect_from: [/docs/reference/appmap-agent-js]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# AppMap Agent for Node.js
|
|
13
|
+
|
|
14
|
+
**Note**: this agent is currently in early access. It replaces [appmap-agent-js](/docs/reference/appmap-agent-js) which is no longer in active development. [Let us know](https://github.com/getappmap/appmap-node/issues)
|
|
15
|
+
if your project is unable to create AppMap Data with `appmap-node`.
|
|
16
|
+
|
|
17
|
+
- [About](#about)
|
|
18
|
+
- [Supported versions](#supported-versions)
|
|
19
|
+
- [Usage](#usage)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [Tests recording](#tests-recording)
|
|
22
|
+
- [Recording Mocha, Jest, or Vitest test cases](#recording-mocha-jest-or-vitest-test-cases)
|
|
23
|
+
- [Remote recording](#remote-recording)
|
|
24
|
+
- [Process recording](#process-recording)
|
|
25
|
+
- [Request recording](#request-recording)
|
|
26
|
+
- [Viewing AppMap Diagrams](#viewing-appmap-diagrams)
|
|
27
|
+
- [GitHub repository](#github-repository)
|
|
28
|
+
- [Troubleshooting](#troubleshooting)
|
|
29
|
+
|
|
30
|
+
## About
|
|
31
|
+
|
|
32
|
+
`appmap-node` records [AppMap Data](https://github.com/getappmap/appmap) of your Node.js applications.
|
|
33
|
+
|
|
34
|
+
{% include docs/what_is_appmap_snippet.md %}
|
|
35
|
+
|
|
36
|
+
### Supported versions
|
|
37
|
+
|
|
38
|
+
{% include docs/node_support_matrix.html %}
|
|
39
|
+
|
|
40
|
+
AppMap for Node.js can record applications written in both JavaScript and TypeScript.
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
npx appmap-node <launch command>
|
|
46
|
+
```
|
|
47
|
+
{: .example-code}
|
|
48
|
+
|
|
49
|
+
AppMap for Node.js wraps your existing application launch command, and typically does not require
|
|
50
|
+
any special installation or configuration.
|
|
51
|
+
|
|
52
|
+
For example, if your Node.js application is normally run with the command `npm run dev`, the following
|
|
53
|
+
command would create AppMap recordings of that application's behavior when it runs:
|
|
54
|
+
|
|
55
|
+
```console
|
|
56
|
+
$ npx appmap-node npm run dev
|
|
57
|
+
```
|
|
58
|
+
{: .example-code}
|
|
59
|
+
|
|
60
|
+
The `appmap-node` command works by passing a modified version of the environment variable `NODE_OPTIONS`
|
|
61
|
+
to the launch command. This allows it to work with any Node.js command, including ones based on `npm`,
|
|
62
|
+
`npx`, `node`, or even shell scripts that launch Node.js applications.
|
|
63
|
+
|
|
64
|
+
AppMap Data is saved to the directory `tmp/appmap` by default, and each AppMap file ends in `.appmap.json`.
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
When you run your program, the agent reads configuration settings from `appmap.yml`. If not found, a default config file will be created. This is typically appropriate for most projects but you're welcome to review and adjust it.
|
|
69
|
+
|
|
70
|
+
Here's a sample configuration file for a typical JavaScript project:
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
name: MyApp
|
|
74
|
+
appmap_dir: tmp/appmap
|
|
75
|
+
packages:
|
|
76
|
+
- path: .
|
|
77
|
+
exclude:
|
|
78
|
+
- node_modules
|
|
79
|
+
- .yarn
|
|
80
|
+
```
|
|
81
|
+
{: .example-code}
|
|
82
|
+
|
|
83
|
+
- **name** Provides the project name (autodetected from *package.json*).
|
|
84
|
+
- **appmap_dir** Directory to place the AppMap Data in. Defaults to `tmp/appmap`.
|
|
85
|
+
- **packages** A list of paths which should be instrumented.
|
|
86
|
+
|
|
87
|
+
**packages**
|
|
88
|
+
|
|
89
|
+
Each entry in the `packages` list is a YAML object which has the following keys:
|
|
90
|
+
|
|
91
|
+
- **path** A path to JavaScript source files; if the project is transpiled, this should include the final js files. Relative paths are resolved with respect to *appmap.yml* location.
|
|
92
|
+
- **exclude** A list of path, functions and methods that will be ignored. The exclude list only applies to the *path* specified in the same package entry. Paths are resolved with respect to that *path*. For example:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
packages:
|
|
96
|
+
- path: dist/users
|
|
97
|
+
exclude:
|
|
98
|
+
- util.js
|
|
99
|
+
- findUser
|
|
100
|
+
- UsersController.index
|
|
101
|
+
- path: dist # catch-all to instrument the rest of the code
|
|
102
|
+
```
|
|
103
|
+
{: .example-code}
|
|
104
|
+
|
|
105
|
+
## Tests recording
|
|
106
|
+
|
|
107
|
+
When running test cases with `appmap-node`, a new AppMap file will be created for each unique test case.
|
|
108
|
+
|
|
109
|
+
### Recording Mocha, Jest, or Vitest test cases
|
|
110
|
+
|
|
111
|
+
Wrap your existing `mocha`, `jest`, or `vitest` test command with `appmap-node`. For example:
|
|
112
|
+
|
|
113
|
+
```console
|
|
114
|
+
$ npx appmap-node mocha specs/test.js
|
|
115
|
+
$ npx appmap-node npm test
|
|
116
|
+
$ npx appmap-node yarn test
|
|
117
|
+
```
|
|
118
|
+
{: .example-code}
|
|
119
|
+
|
|
120
|
+
When the tests are complete, the AppMap files will be stored in the default output directory `tmp/appmap/<test-framework>`,
|
|
121
|
+
where `<test-framework>` will be one of `mocha`, `jest`, or `vitest`.
|
|
122
|
+
|
|
123
|
+
{% include vimeo.html id='921256248' %}
|
|
124
|
+
|
|
125
|
+
## Remote recording
|
|
126
|
+
|
|
127
|
+
The `appmap-node` agent supports the [AppMap remote recording API](/docs/reference/remote-recording-api).
|
|
128
|
+
AppMap adds HTTP APIs that can be used to toggle recording on and off after an application has started.
|
|
129
|
+
Remote recording is useful when you'd like to record only during a specific time during your application's execution.
|
|
130
|
+
|
|
131
|
+
1. Run `appmap-node` as normal, passing your application's starting command as the arguments.
|
|
132
|
+
2. `appmap-node` will start the app and inject itself in its http stack. It will listen for [remote recording requests](/docs/reference/remote-recording-api).
|
|
133
|
+
3. Start the remote recording:
|
|
134
|
+
- [in VS Code](/docs/reference/vscode.html#remote-recording)
|
|
135
|
+
- [in JetBrains IDEs](/docs/reference/jetbrains.html#remote-recording)
|
|
136
|
+
- [with curl](/docs/reference/remote-recording-api)
|
|
137
|
+
4. Interact with your application's API or UI to so that those features get recorded.
|
|
138
|
+
5. Stop the recording using the AppMap code editor plugin or curl to save the new AppMap to disk.
|
|
139
|
+
|
|
140
|
+
{% include vimeo.html id='921270684' %}
|
|
141
|
+
|
|
142
|
+
## Request Recording
|
|
143
|
+
|
|
144
|
+
AppMap for Node.js supports Request Recording. This feature automatically records an AppMap for each HTTP request
|
|
145
|
+
served by the application at runtime.
|
|
146
|
+
|
|
147
|
+
Request recording occurs automatically once any HTTP requests are served, and does not require special
|
|
148
|
+
configuration. Pass your application launch command as the argument to `npx appmap-node` and make HTTP requests
|
|
149
|
+
to your application as normal.
|
|
150
|
+
|
|
151
|
+
Each API request served will create an AppMap representing the full processing of that single HTTP
|
|
152
|
+
request, and will be stored in `tmp/appmap/requests`.
|
|
153
|
+
|
|
154
|
+
{% include vimeo.html id='921273327' %}
|
|
155
|
+
|
|
156
|
+
## Process recording
|
|
157
|
+
|
|
158
|
+
In the absence of tests or HTTP requests, AppMap can record an entire
|
|
159
|
+
Node.js application's execution from start to finish.
|
|
160
|
+
|
|
161
|
+
Run the `appmap-node` command and give it an argument for starting your application, and it will record the entire
|
|
162
|
+
application's behavior by default.
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
npx appmap-node <add your Node.js application launch command here>
|
|
166
|
+
```
|
|
167
|
+
{: .example-code}
|
|
168
|
+
|
|
169
|
+
Then interact with your app using its UI or API, and AppMap Diagrams will be generated automatically.
|
|
170
|
+
|
|
171
|
+
## Viewing AppMap Diagrams
|
|
172
|
+
|
|
173
|
+
Recorded AppMap are saved as `.appmap.json` files `tmp/appmap`.
|
|
174
|
+
|
|
175
|
+
Follow the documentation for your IDE to open recorded `.appmap.json` AppMap files:
|
|
176
|
+
- [in VS Code](/docs/reference/vscode)
|
|
177
|
+
- [in JetBrains IDEs](/docs/reference/jetbrains)
|
|
178
|
+
|
|
179
|
+
## GitHub repository
|
|
180
|
+
|
|
181
|
+
[https://github.com/getappmap/appmap-node](https://github.com/getappmap/appmap-node)
|
|
182
|
+
|
|
183
|
+
## Troubleshooting
|
|
184
|
+
|
|
185
|
+
If you run into any issues, please make sure if you have the latest version by running `npx appmap-node@latest` first.
|
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
title: Docs - Reference
|
|
4
|
+
description: "AppMap reference documentation for AppMap Python. Learn installation, configuration, tests, request recording, decorators, and environment variables."
|
|
5
|
+
toc: true
|
|
6
|
+
reference: true
|
|
7
|
+
name: AppMap Agent for Python
|
|
8
|
+
step: 5
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# AppMap Agent for Python
|
|
12
|
+
- [About](#about)
|
|
13
|
+
- [Supported versions](#supported-versions)
|
|
14
|
+
- [Installation](#installation)
|
|
15
|
+
- [Configuration](#configuration)
|
|
16
|
+
- [Enabling and disabling recording](#enabling-and-disabling-recording)
|
|
17
|
+
- [`appmap-python` script](#appmap-python-script)
|
|
18
|
+
- [Test recording](#test-recording)
|
|
19
|
+
- [pytest](#pytest)
|
|
20
|
+
- [unittest](#unittest)
|
|
21
|
+
- [Request recording](#request-recording)
|
|
22
|
+
- [Remote recording](#remote-recording)
|
|
23
|
+
- [Code Block Recording](#code-block-recording)
|
|
24
|
+
- [Web framework support](#web-framework-support)
|
|
25
|
+
- [Django](#django)
|
|
26
|
+
- [Flask](#flask)
|
|
27
|
+
- [FastAPI](#fastapi)
|
|
28
|
+
- [uvicorn](#uvicorn)
|
|
29
|
+
- [Other ASGI servers](#other-asgi-servers)
|
|
30
|
+
- [Decorators](#decorators)
|
|
31
|
+
- [@appmap.labels](#appmaplabels)
|
|
32
|
+
- [@appmap.noappmap](#appmapnoappmap)
|
|
33
|
+
- [Environment variables](#environment-variables)
|
|
34
|
+
- [Controlling recording](#controlling-recording)
|
|
35
|
+
- [Other configuration](#other-configuration)
|
|
36
|
+
- [GitHub repository](#github-repository)
|
|
37
|
+
|
|
38
|
+
## About
|
|
39
|
+
|
|
40
|
+
`appmap` is a Python package for creating [AppMap Diagrams](https://github.com/getappmap/appmap) of
|
|
41
|
+
your code.
|
|
42
|
+
|
|
43
|
+
{% include docs/what_is_appmap_snippet.md %}
|
|
44
|
+
|
|
45
|
+
`appmap` works by modifying the way python imports the modules of an application. After a module is
|
|
46
|
+
imported, `appmap` examines it for function definitions. Each function is instrumented, so that when
|
|
47
|
+
it is called, a trace event will be added to the current recording.
|
|
48
|
+
|
|
49
|
+
### Supported versions
|
|
50
|
+
|
|
51
|
+
{% include docs/python_support_matrix.html %}
|
|
52
|
+
|
|
53
|
+
Support for new versions is added frequently, please check back regularly for updates.
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
`appmap` works best when installed in a virtual environment, usually one associated with a project.
|
|
57
|
+
This helps ensure that the project's code will be instrumented, while reducing the chance of
|
|
58
|
+
interference with other python utilities.
|
|
59
|
+
|
|
60
|
+
If your project uses `pip` for dependency management, add the `appmap` package to the project's
|
|
61
|
+
requirements file or install it directly. Specifying the `--require-virtualenv` switch ensures that
|
|
62
|
+
it will only be installed in a virtual environment.
|
|
63
|
+
|
|
64
|
+
```shell
|
|
65
|
+
pip install --require-virtualenv appmap
|
|
66
|
+
```
|
|
67
|
+
{: .example-code}
|
|
68
|
+
|
|
69
|
+
For projects that use `poetry` , add the `appmap` package to `pyproject.toml`. Note that, by
|
|
70
|
+
default, `poetry` manages dependencies using a virtual environment.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
poetry add --group=dev appmap
|
|
74
|
+
```
|
|
75
|
+
{: .example-code}
|
|
76
|
+
|
|
77
|
+
`pipenv` is also supported. Like `poetry`, `pipenv` installs dependencies in a virtual environment.
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
pipenv install --dev appmap
|
|
81
|
+
```
|
|
82
|
+
{: .example-code}
|
|
83
|
+
|
|
84
|
+
{% include docs/install_appmap_extension.md %}
|
|
85
|
+
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
`appmap` is configured using a YAML file. By default, `appmap` looks in the current working
|
|
89
|
+
directory for a file named `appmap.yml`.
|
|
90
|
+
|
|
91
|
+
`appmap.yml` contains information used to create AppMap Data files. It allows you to specify the
|
|
92
|
+
application's name, as well as the modules that should be instrumented.
|
|
93
|
+
|
|
94
|
+
For each module, add the fully-qualified module name as the value of a `path` property. These names
|
|
95
|
+
should be in the format used in an `import` statement:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
name: my_python_app
|
|
99
|
+
packages:
|
|
100
|
+
- path: app.mod1
|
|
101
|
+
shallow: true
|
|
102
|
+
- path: app.mod2
|
|
103
|
+
exclude:
|
|
104
|
+
- MyClass
|
|
105
|
+
- MyOtherClass.my_instance_method
|
|
106
|
+
- MyOtherClass.my_class_method
|
|
107
|
+
# You can record dependency packages, such as Django.
|
|
108
|
+
# We don't recommend recording Django by default though, your AppMap Diagram will be quite large
|
|
109
|
+
# and mostly about Django itself, not your own code.
|
|
110
|
+
#- dist: Django
|
|
111
|
+
# exclude:
|
|
112
|
+
# - django.db
|
|
113
|
+
```
|
|
114
|
+
Notes about this example:
|
|
115
|
+
* The application has two modules that will be recorded: `app.mod1` and
|
|
116
|
+
`app.mod2`. When the python interpreter imports one of those modules (e.g. by evaluating `import
|
|
117
|
+
app.mod1`, `from app import mod1`, `from app import *`, etc), `appmap` will instrument the
|
|
118
|
+
functions in the imported module.
|
|
119
|
+
|
|
120
|
+
If the value of a `path` property cannot be parsed as a module name, `appmap` will issue an error
|
|
121
|
+
and exit.
|
|
122
|
+
|
|
123
|
+
* An `exclude` is resolved relative to the associated path. So, for example, this configuration
|
|
124
|
+
excludes `app.mod2.MyClass`.
|
|
125
|
+
|
|
126
|
+
* An external [distribution
|
|
127
|
+
package](https://packaging.python.org/glossary/#term-Distribution-Package) can be specified using
|
|
128
|
+
the `dist` specifier. The names are looked up in the [database of installed Python
|
|
129
|
+
distributions](https://www.python.org/dev/peps/pep-0376/). This is generally the same package name
|
|
130
|
+
as you'd give to `pip install` or put in `pyproject.toml`. You can additionally use `path` and
|
|
131
|
+
`exclude` on `dist` entries to limit the capture to specific patterns.
|
|
132
|
+
|
|
133
|
+
By default, shallow capture is enabled on `dist` packages, suppressing tracking of most internal
|
|
134
|
+
execution flow. This allows you to capture the interaction without getting bogged down with detail.
|
|
135
|
+
To see these details, set `shallow: false`. You can also use `shallow: true` on `path` entries.
|
|
136
|
+
|
|
137
|
+
## Enabling and disabling recording
|
|
138
|
+
|
|
139
|
+
In the simplest case, AppMap recording can be either "enabled" or "disabled". When it's enabled, AppMap
|
|
140
|
+
data files will be created whenever a supported test case is run, and whenever a web request is
|
|
141
|
+
served. The remote recording endpoint will also be available. Recording of test cases, requests, and
|
|
142
|
+
remote recording can be further controlled with [additional environment
|
|
143
|
+
variables](#controlling-recording). When it's disabled, no application code will be instrumented, and
|
|
144
|
+
no AppMap files will be created.
|
|
145
|
+
|
|
146
|
+
Currently, AppMap is enabled by default. So if your python environment (either global, or in a
|
|
147
|
+
virtualenv) has the `appmap` package installed, AppMap will (a) instrument your python code whenever
|
|
148
|
+
you run a python program, and (b) the enabled behavior described above will be applied.
|
|
149
|
+
|
|
150
|
+
In the upcoming version 2 of the `appmap` package, the default behavior will change: AppMap will be
|
|
151
|
+
disabled by default. To enable AppMap, you can either (a) launch your python program with the new
|
|
152
|
+
`appmap-python` launch script, or (b) set the `APPMAP` environment variable (e.g. `export APPMAP=true`
|
|
153
|
+
in Bash, `$Env:APPMAP="true"` in PowerShell, etc).
|
|
154
|
+
|
|
155
|
+
### `appmap-python` script
|
|
156
|
+
```
|
|
157
|
+
% appmap-python --help
|
|
158
|
+
usage: appmap-python [-h] [--record unittest,requests,remote,pytest,process] [--no-record unittest,requests,remote,pytest,process] [--enable-log | --no-enable-log] [command ...]
|
|
159
|
+
|
|
160
|
+
Enable recording of the provided command, optionally specifying the
|
|
161
|
+
type(s) of recording to enable and disable. If a recording type is
|
|
162
|
+
specified as both enabled and disabled, it will be enabled.
|
|
163
|
+
|
|
164
|
+
This command sets the environment variables described here:
|
|
165
|
+
https://appmap.io/docs/reference/appmap-python.html#controlling-recording.
|
|
166
|
+
For any recording type that is not explicitly specified, the
|
|
167
|
+
corresponding environment variable will not be set.
|
|
168
|
+
|
|
169
|
+
If no command is provided, the computed set of environment variables
|
|
170
|
+
will be displayed.
|
|
171
|
+
|
|
172
|
+
positional arguments:
|
|
173
|
+
command the command to run (default: display the environment variables)
|
|
174
|
+
|
|
175
|
+
options:
|
|
176
|
+
-h, --help show this help message and exit
|
|
177
|
+
--record unittest,requests,remote,pytest,process
|
|
178
|
+
recording types to enable
|
|
179
|
+
--no-record unittest,requests,remote,pytest,process
|
|
180
|
+
recording types to disable
|
|
181
|
+
--enable-log, --no-enable-log
|
|
182
|
+
create a log file (default: False)
|
|
183
|
+
```
|
|
184
|
+
## Test recording
|
|
185
|
+
|
|
186
|
+
`appmap` supports recording [pytest](https://pytest.org) and
|
|
187
|
+
[unittest](https://docs.python.org/3/library/unittest.html) test cases.
|
|
188
|
+
|
|
189
|
+
### pytest
|
|
190
|
+
|
|
191
|
+
`appmap` is a `pytest` plugin. When it's installed in a project that uses
|
|
192
|
+
`pytest`, it will be available to generate AppMap Diagrams by default.
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
root@e9987eaa93c8:/src/appmap/test/data/pytest# pip show appmap
|
|
196
|
+
Name: appmap
|
|
197
|
+
Version: 0.0.0
|
|
198
|
+
Summary: Create AppMap files by recording a Python application.
|
|
199
|
+
Home-page: None
|
|
200
|
+
Author: Alan Potter
|
|
201
|
+
Author-email: alan@app.land
|
|
202
|
+
License: None
|
|
203
|
+
Location: /usr/local/lib/python3.9/site-packages
|
|
204
|
+
Requires: orjson, PyYAML, inflection
|
|
205
|
+
Required-by:
|
|
206
|
+
root@e9987eaa93c8:/src/appmap/test/data/pytest# APPMAP_LOG_LEVEL=info pytest -svv
|
|
207
|
+
[2021-02-10 11:37:59,345] INFO root: appmap enabled: True
|
|
208
|
+
[2021-02-10 11:37:59,350] INFO appmap._implementation.configuration: ConfigFilter, includes {'simple'}
|
|
209
|
+
[2021-02-10 11:37:59,350] INFO appmap._implementation.configuration: ConfigFilter, excludes set()
|
|
210
|
+
===================================================================== test session starts =====================================================================
|
|
211
|
+
platform linux -- Python 3.9.1, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- /usr/local/bin/python
|
|
212
|
+
cachedir: .pytest_cache
|
|
213
|
+
rootdir: /src, configfile: pytest.ini
|
|
214
|
+
plugins: appmap-0.0.0
|
|
215
|
+
collected 1 item
|
|
216
|
+
|
|
217
|
+
test_simple.py::test_hello_world [2021-02-10 11:37:59,482] INFO appmap.pytest: starting recording /tmp/pytest/test_hello_world.appmap.json
|
|
218
|
+
[2021-02-10 11:37:59,484] INFO appmap._implementation.configuration: included class simple.Simple
|
|
219
|
+
[2021-02-10 11:37:59,484] INFO appmap._implementation.configuration: included function simple.Simple.hello
|
|
220
|
+
[2021-02-10 11:37:59,489] INFO appmap._implementation.configuration: included function simple.Simple.hello_world
|
|
221
|
+
[2021-02-10 11:37:59,490] INFO appmap._implementation.configuration: included function simple.Simple.world
|
|
222
|
+
[2021-02-10 11:37:59,828] INFO appmap.pytest: wrote recording /tmp/pytest/test_hello_world.appmap.json
|
|
223
|
+
PASSED
|
|
224
|
+
|
|
225
|
+
====================================================================== 1 passed in 0.45s ======================================================================
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### unittest
|
|
229
|
+
|
|
230
|
+
A subclass of `unittest.TestCase` is instrumented automatically, and an AppMap is recorded for each
|
|
231
|
+
`test_*` function in the subclass.
|
|
232
|
+
|
|
233
|
+
## Request recording
|
|
234
|
+
|
|
235
|
+
`appmap-python` can automatically record and save an AppMap for each HTTP server request. To do this, the AppMap agent hooks into the web server request processing framework. It starts a recording when each new request is received,
|
|
236
|
+
records the execution thread into an AppMap, and saves in when the request is completed.
|
|
237
|
+
|
|
238
|
+
**Note** Your application must be running in a supported web framework for request recording to work.
|
|
239
|
+
|
|
240
|
+
## Remote recording
|
|
241
|
+
|
|
242
|
+
The AppMap agent supports remote recording of web applications during development. When your application is run with debugging support, remote recording will be enabled automatically.
|
|
243
|
+
|
|
244
|
+
To enable debugging support, ensure:
|
|
245
|
+
|
|
246
|
+
* **Django** `DEBUG = True` in settings.py
|
|
247
|
+
* **Flask** run with the `--debug` option
|
|
248
|
+
|
|
249
|
+
**Note** Your application must be running in a supported web framework for remote recording to work.
|
|
250
|
+
|
|
251
|
+
## Code Block Recording
|
|
252
|
+
|
|
253
|
+
You can use `appmap.record` as a context manager to record a specific span of code. With this method, you can control exactly
|
|
254
|
+
what code is recorded, and where the recording is saved.
|
|
255
|
+
|
|
256
|
+
Given a source file `record_sample.py`:
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
import os
|
|
260
|
+
import sys
|
|
261
|
+
from datetime import datetime
|
|
262
|
+
from pathlib import Path
|
|
263
|
+
|
|
264
|
+
import appmap
|
|
265
|
+
|
|
266
|
+
output_directory = Path('tmp/appmap/codeblock')
|
|
267
|
+
output_directory.mkdir(parents=True, exist_ok=True) # Step 2: Ensure the directory exists
|
|
268
|
+
|
|
269
|
+
timestamp = datetime.now().isoformat(timespec='seconds')
|
|
270
|
+
output_file = output_directory / f'{timestamp}.appmap.json'
|
|
271
|
+
|
|
272
|
+
r = appmap.Recording()
|
|
273
|
+
with r:
|
|
274
|
+
import sample
|
|
275
|
+
print(sample.C().hello_world(), file=sys.stderr)
|
|
276
|
+
|
|
277
|
+
with open(output_file, "w") as f:
|
|
278
|
+
f.write(
|
|
279
|
+
appmap.generation.dump(
|
|
280
|
+
r,
|
|
281
|
+
{
|
|
282
|
+
"name": str(timestamp),
|
|
283
|
+
"recorder": {
|
|
284
|
+
"type": "process",
|
|
285
|
+
"name": "process",
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
)
|
|
289
|
+
)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
and a source file `sample.py`:
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
class C:
|
|
296
|
+
def make_str(self, s):
|
|
297
|
+
return s;
|
|
298
|
+
|
|
299
|
+
def hello_world(self):
|
|
300
|
+
return f'{self.make_str("Hello")} {self.make_str("world!")}'
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
as well as `appmap.yml`:
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
name: sample
|
|
307
|
+
packages:
|
|
308
|
+
- path: sample
|
|
309
|
+
language: python
|
|
310
|
+
appmap_dir: tmp/appmap
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
you can generate a recording of the code
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
% python record_sample.py
|
|
317
|
+
% jq '.events | length' tmp/appmap/codeblock/*.appmap.json
|
|
318
|
+
6
|
|
319
|
+
% jq < tmp/appmap/codeblock/*.appmap.json | head -10
|
|
320
|
+
{
|
|
321
|
+
"version": "1.9",
|
|
322
|
+
"metadata": {
|
|
323
|
+
"language": {
|
|
324
|
+
"name": "python",
|
|
325
|
+
"engine": "CPython",
|
|
326
|
+
"version": "3.10.13"
|
|
327
|
+
},
|
|
328
|
+
"client": {
|
|
329
|
+
"name": "appmap",
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Web framework support
|
|
333
|
+
|
|
334
|
+
`appmap-python` integrates with the Django, Flask, and FastAPI web frameworks. When an application is started in a development environment, it inserts itself into the application's request processing stack. This enables recording of requests, as well as support for the [AppMap remote recording API](./remote-recording-api).
|
|
335
|
+
|
|
336
|
+
### Django
|
|
337
|
+
|
|
338
|
+
To start a Django app with AppMap integration enabled, add
|
|
339
|
+
```
|
|
340
|
+
DEBUG = True
|
|
341
|
+
```
|
|
342
|
+
to your application's `settings.py`.
|
|
343
|
+
|
|
344
|
+
### Flask
|
|
345
|
+
|
|
346
|
+
When `flask` is invoked with the `--debug` switch, debugging is enabled, as well as AppMap integration.
|
|
347
|
+
|
|
348
|
+
### FastAPI
|
|
349
|
+
The FastAPI integration supports both request recording and remote recording. Request
|
|
350
|
+
recording is enabled by default. When running during application development,
|
|
351
|
+
remote recording can also be enabled.
|
|
352
|
+
|
|
353
|
+
#### uvicorn
|
|
354
|
+
To create remote recordings of a FastAPI application run with `uvicorn`, use the
|
|
355
|
+
`--reload` switch:
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
$ uvicorn main:app --reload
|
|
359
|
+
INFO: Will watch for changes in these directories: ['/Users/example/fastapiapp']
|
|
360
|
+
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
|
361
|
+
INFO: Started reloader process [57259] using StatReload
|
|
362
|
+
INFO: Started server process [57261]
|
|
363
|
+
INFO: Waiting for application startup.
|
|
364
|
+
INFO: Application startup complete.
|
|
365
|
+
```
|
|
366
|
+
#### Other ASGI servers
|
|
367
|
+
To create remote recordings with other ASGI servers, you must modify your application code to add the agent's middleware. For example:
|
|
368
|
+
|
|
369
|
+
```
|
|
370
|
+
from fastapi import FastAPI, HTTPException, Request
|
|
371
|
+
import appmap.fastapi
|
|
372
|
+
|
|
373
|
+
app = FastAPI()
|
|
374
|
+
|
|
375
|
+
@app.get("/")
|
|
376
|
+
def root():
|
|
377
|
+
return {"hello":"world"}
|
|
378
|
+
|
|
379
|
+
app = appmap.fastapi.Middleware(app, remote_enabled=True).init_app()
|
|
380
|
+
```
|
|
381
|
+
Remote recordings will be enabled when `remote_enabled` is `True`.
|
|
382
|
+
|
|
383
|
+
## Decorators
|
|
384
|
+
|
|
385
|
+
### @appmap.labels
|
|
386
|
+
|
|
387
|
+
The [AppMap Data Format](https://github.com/getappmap/appmap) provides for class and
|
|
388
|
+
function `labels`, which can be used to enhance the AppMap Diagrams, and to
|
|
389
|
+
programmatically analyze the data.
|
|
390
|
+
|
|
391
|
+
You can apply function labels using the `appmap.labels` decorator in your Python code. To
|
|
392
|
+
apply a label to a function, decorate the function with `@appmap.labels`.
|
|
393
|
+
|
|
394
|
+
For example, to label a function as an authentication provider:
|
|
395
|
+
```
|
|
396
|
+
import appmap
|
|
397
|
+
|
|
398
|
+
class ApiKey
|
|
399
|
+
@appmap.labels('provider.authentication', 'security')
|
|
400
|
+
def authenticate(self, key):
|
|
401
|
+
# logic to verify the key here...
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Then the AppMap metadata section for this function will include:
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
{
|
|
408
|
+
"name": "authenticate",
|
|
409
|
+
"type": "function",
|
|
410
|
+
"labels": [ "provider.authentication", "security" ]
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### @appmap.noappmap
|
|
415
|
+
The `@appmap.noappmap` decorator can be used to disable recording of `pytest` and `unittest` tests. If applied to a specific function, that function will not generate an AppMap. Alternatively, it can be applied to a test class to disable generation of AppMap Data for all tests in the class.
|
|
416
|
+
|
|
417
|
+
For example:
|
|
418
|
+
```
|
|
419
|
+
import appmap
|
|
420
|
+
|
|
421
|
+
def test_test1():
|
|
422
|
+
...
|
|
423
|
+
|
|
424
|
+
@appmap.noappmap
|
|
425
|
+
def test_test2():
|
|
426
|
+
....
|
|
427
|
+
```
|
|
428
|
+
When the tests above are executed, `test_test1` will generate an AppMap, but `test_test2` will not.
|
|
429
|
+
|
|
430
|
+
For example, to decorate a test class:
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
import unitest
|
|
434
|
+
|
|
435
|
+
import appmap
|
|
436
|
+
|
|
437
|
+
@appmap.noappmap
|
|
438
|
+
class TestNoAppMaps(unittest.TestCase):
|
|
439
|
+
def test_test1(self):
|
|
440
|
+
...
|
|
441
|
+
|
|
442
|
+
def test_test2(self):
|
|
443
|
+
...
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
When functions within `TestNoAppMaps` are executed, no AppMap Data will be generated.
|
|
447
|
+
|
|
448
|
+
## Environment variables
|
|
449
|
+
|
|
450
|
+
### Controlling recording
|
|
451
|
+
These variables control the types of recordings generated by the agent. The values of the variables are not case-sensitive.
|
|
452
|
+
|
|
453
|
+
* `APPMAP` controls all instrumentation and recording. When unset, or explicitly set to `true`, all application code will be instrumented, and the generation of recordings will be controlled by the variables below. When set to `false`, application code will run as if the AppMap agent was not installed.
|
|
454
|
+
|
|
455
|
+
Note that, as described above, the default behavior will change in version 2: by default (or if `APPMAP` is set to `false`), no code will be instrumented, and no recordings generated.
|
|
456
|
+
|
|
457
|
+
* `APPMAP_RECORD_<PYTEST|UNITTEST>` controls recording generation when test cases are run by `pytest` or `unittest`. When unset or set to `true`, each test case will generate a recording. When set to `false`, no recordings for individual test cases will be created. For example, to disable recording when using `pytest`, use `APPMAP_RECORD_PYTEST=false`:
|
|
458
|
+
|
|
459
|
+
```
|
|
460
|
+
$ env APPMAP_RECORD_PYTEST=false pytest
|
|
461
|
+
```
|
|
462
|
+
or
|
|
463
|
+
```
|
|
464
|
+
$ appmap-python --no-record pytest pytest
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
In version 2, these two variables will be combined into a single variable named `APPMAP_RECORD_TESTS`, controlling recording for these (and any future) test frameworks.
|
|
468
|
+
|
|
469
|
+
* `APPMAP_RECORD_REMOTE` controls the installation of the AppMap remote recording API. When unset, and run in a development environment (described [above](#web-framework-support)), remote recording will be enabled. When set to `true`, remote recording will always be enabled, regardless of environment. When set to `false`, remote recording will always be disabled.
|
|
470
|
+
|
|
471
|
+
Note that enabling remote recording other than in a development environment is a security risk, and `appmap` will issue a warning if you do so. However, sometimes the behavior of interest only occurs in some other environment. Setting `APPMAP_RECORD_REMOTE=true` allows this. For example, to enable remote recording for a Flask app started without debug, run:
|
|
472
|
+
|
|
473
|
+
```
|
|
474
|
+
$ env APPMAP_RECORD_REMOTE=true flask --app main.app
|
|
475
|
+
```
|
|
476
|
+
or
|
|
477
|
+
```
|
|
478
|
+
$ appmap-python --record remote flask --app main.app
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
* `APPMAP_RECORD_REQUESTS` controls creation of request recordings created when a web framework processes HTTP requests. When unset or `true`, request recordings will be created, otherwise they will not.
|
|
482
|
+
|
|
483
|
+
* `APPMAP_RECORD_PROCESS` controls recording of the entire python process that loads the agent. When
|
|
484
|
+
`true`, recording starts when the agent is loaded. When the process exits, an AppMap will be
|
|
485
|
+
created.
|
|
486
|
+
|
|
487
|
+
**Important note:** process recording is not compatible with other recording methods. If you start
|
|
488
|
+
a python process when `APPMAP_RECORD_PROCESS` is `true`, other attempts to create a recording will
|
|
489
|
+
raise a `RuntimeError` with the message "Recording already in progress".
|
|
490
|
+
|
|
491
|
+
For example, when `APPMAP_RECORD_PROCESS` is `true`, trying to start a request recording will
|
|
492
|
+
raise this error. To avoid this, you should disable request recording. For example:
|
|
493
|
+
|
|
494
|
+
```
|
|
495
|
+
$ appmap-python --record process --no-record requests flask --app main.app
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
In addition, using code block recording, running tests, or starting a remote recording, will
|
|
499
|
+
all raise this error and should not be attempted.
|
|
500
|
+
|
|
501
|
+
### Other configuration
|
|
502
|
+
These environment variables can be used to control various aspects of the AppMap agent.
|
|
503
|
+
|
|
504
|
+
* `APPMAP_CONFIG` specifies the configuration file to use. Defaults to `appmap.yml` in the
|
|
505
|
+
current directory.
|
|
506
|
+
|
|
507
|
+
* `APPMAP_LOG_LEVEL` specifies log level to use, from the set `CRITICAL`, `ERROR`,
|
|
508
|
+
`WARNING`, `INFO`, `DEBUG`. Not case-sensitive, defaults to `INFO`.
|
|
509
|
+
|
|
510
|
+
* `APPMAP_DISPLAY_PARAMS` enables rendering of parameters as strings. If `true` (the
|
|
511
|
+
default, not case-sensitive), parameters are rendered using `repr`. If
|
|
512
|
+
`false`, a generic string is used instead.
|
|
513
|
+
|
|
514
|
+
* `APPMAP_DISABLE_LOG_FILE` controls the automatic creation of a log file by the
|
|
515
|
+
AppMap agent. If not `true` (the default), a log file will be created.
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
## GitHub repository
|
|
519
|
+
|
|
520
|
+
[https://github.com/getappmap/appmap-python](https://github.com/getappmap/appmap-python)
|