@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,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
title: Docs - Guides
|
|
4
|
+
description: "Optimize AppMap Diagrams by refining recordings to exclude noise. Start with inclusive config, analyze stats, update config, create concise AppMap Diagrams."
|
|
5
|
+
guides: true
|
|
6
|
+
name: Refining AppMap Data
|
|
7
|
+
step: 6
|
|
8
|
+
redirect_from: [/docs/reference/refine-appmaps, /docs/guides/refine-appmaps]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Refining AppMap Data <!-- omit in toc -->
|
|
12
|
+
|
|
13
|
+
When you initially create a client configuration, it can be hard to know what classes to
|
|
14
|
+
include. Most often, you will simply select everything just to see what a recording looks
|
|
15
|
+
like. The resulting AppMap Diagrams can be quite large and noisy. The presence of calls to many
|
|
16
|
+
utility methods makes it hard to understand the bigger picture.
|
|
17
|
+
|
|
18
|
+
To refine your recordings, it's best to start with the smallest use-case that's
|
|
19
|
+
representative of the entire application. For example, while a single unit test will
|
|
20
|
+
produce a small recording, such tests typically avoid accessing external resources
|
|
21
|
+
(e.g. web services, a database, or the file system) for the sake of speed. Recording a
|
|
22
|
+
single functional or integration test is a better choice.
|
|
23
|
+
|
|
24
|
+
Once you've made a recording of a use-case, you can use the `stats` subcommand
|
|
25
|
+
of the [AppMap CLI](/docs/reference/appmap-client-cli.html).
|
|
26
|
+
tools to generate some simple statistics about your AppMap Data. Based on these statistics,
|
|
27
|
+
you will be able to update your configuration so that less-interesting methods are
|
|
28
|
+
excluded. When new recordings are created with the improved configuration, they will be
|
|
29
|
+
more concise and easier to understand.
|
|
30
|
+
|
|
31
|
+
To illustrate the refinement process, we'll look at a recording made for
|
|
32
|
+
[Jenkins](https://github.com/land-of-apps/jenkins). [CONTRIBUTING.md](https://github.com/land-of-apps/jenkins/blob/master/CONTRIBUTING.md#testing-changes)
|
|
33
|
+
in that repository mentions that there are functional tests in the `test` module. For this
|
|
34
|
+
example, we'll use the tests in
|
|
35
|
+
[test/src/test/java/hudson/model/DirectlyModifiableViewTest.java](https://github.com/land-of-apps/jenkins/blob/master/test/src/test/java/hudson/model/DirectlyModifiableViewTest.java).
|
|
36
|
+
|
|
37
|
+
- [Step 1: Make a recording with an inclusive configuration](#step-1-make-a-recording-with-an-inclusive-configuration)
|
|
38
|
+
- [Step 2: Eliminate the noise](#step-2-eliminate-the-noise)
|
|
39
|
+
- [Step 3: Update the configuration and create new AppMap Diagrams](#step-3-update-the-configuration-and-create-new-appmap-diagrams)
|
|
40
|
+
|
|
41
|
+
## Step 1: Make a recording with an inclusive configuration
|
|
42
|
+
|
|
43
|
+
We'll start with a very broad configuration specified in
|
|
44
|
+
`appmap.yml`:
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
name: Jenkins
|
|
48
|
+
packages:
|
|
49
|
+
- path: org.acegisecurity.context
|
|
50
|
+
- path: hudson
|
|
51
|
+
- path: jenkins
|
|
52
|
+
```
|
|
53
|
+
{: .example-code}
|
|
54
|
+
|
|
55
|
+
These are the three top-level packages used by Jenkins. We include them to make sure all
|
|
56
|
+
calls to methods that might be interesting get recorded.
|
|
57
|
+
|
|
58
|
+
Running the tests in `DirectlyModifiableViewTest.java` produces five very large AppMap Diagrams:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
% mvn test -Dtest=DirectlyModifiableViewTest
|
|
62
|
+
...
|
|
63
|
+
% ls -lsh | sort -n
|
|
64
|
+
total 310312
|
|
65
|
+
11456 -rw-r--r-- 1 ajp staff 5.6M Nov 11 10:04 hudson_model_DirectlyModifiableViewTest_manipulateViewContent.appmap.json
|
|
66
|
+
32952 -rw-r--r-- 1 ajp staff 16M Nov 11 10:04 hudson_model_DirectlyModifiableViewTest_doAddJobToView.appmap.json
|
|
67
|
+
41240 -rw-r--r-- 1 ajp staff 20M Nov 11 10:04 hudson_model_DirectlyModifiableViewTest_doRemoveJobFromView.appmap.json
|
|
68
|
+
109864 -rw-r--r-- 1 ajp staff 53M Nov 11 10:04 hudson_model_DirectlyModifiableViewTest_doAddNestedJobToRecursiveView.appmap.json
|
|
69
|
+
114800 -rw-r--r-- 1 ajp staff 56M Nov 11 10:05 hudson_model_DirectlyModifiableViewTest_failWebMethodForIllegalRequest.appmap.jso
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The statistics for these show that there's substantial noise in them:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
% appmap stats tmp/appmap
|
|
76
|
+
232356 calls, top 20 methods
|
|
77
|
+
hudson.util.AdaptedIterator#hasNext:50: 30433 (1 distinct)
|
|
78
|
+
hudson.util.Iterators$5#hasNext:295: 30433 (1 distinct)
|
|
79
|
+
hudson.ExtensionComponent#getInstance:73: 25040 (1 distinct)
|
|
80
|
+
hudson.util.AdaptedIterator#next:54: 24779 (1 distinct)
|
|
81
|
+
hudson.util.Iterators$5#next:299: 24779 (1 distinct)
|
|
82
|
+
jenkins.model.Jenkins$3#getInstance:763: 8101 (1 distinct)
|
|
83
|
+
jenkins.security.stapler.StaticRoutingDecisionProvider#decide:85: 7913 (1838 distinct)
|
|
84
|
+
jenkins.model.Jenkins#getExtensionList:2702: 5963 (15 distinct)
|
|
85
|
+
hudson.ExtensionList#iterator:172: 5849 (1 distinct)
|
|
86
|
+
hudson.util.Iterators.readOnly:293: 5849 (5849 distinct)
|
|
87
|
+
hudson.ExtensionList.lookup:433: 5831 (14 distinct)
|
|
88
|
+
hudson.ExtensionList#size:191: 5452 (1 distinct)
|
|
89
|
+
jenkins.security.stapler.DoActionFilter#keep:54: 2445 (2445 distinct)
|
|
90
|
+
jenkins.security.stapler.TypedFilter#keep:193: 2352 (2352 distinct)
|
|
91
|
+
jenkins.model.Jenkins.get:775: 1702 (1 distinct)
|
|
92
|
+
hudson.util.RobustReflectionConverter$1#visit:193: 1517 (122 distinct)
|
|
93
|
+
hudson.util.RobustReflectionConverter$2#visit:211: 1517 (122 distinct)
|
|
94
|
+
hudson.util.xstream.MapperDelegate#getConverterFromItemType:103: 1517 (28 distinct)
|
|
95
|
+
hudson.util.xstream.MapperDelegate#getConverterFromItemType:123: 1517 (73 distinct)
|
|
96
|
+
hudson.util.xstream.MapperDelegate#getConverterFromItemType:95: 1517 (67 distinct)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The top 20 methods in these files are called more than 1500 times! Removing them from the
|
|
100
|
+
recordings will make the AppMap Diagrams easier to understand, without eliminating any
|
|
101
|
+
interesting information.
|
|
102
|
+
|
|
103
|
+
## Step 2: Eliminate the noise
|
|
104
|
+
|
|
105
|
+
We'll start by generating more detailed statistics:
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
% appmap stats --limit 0 --files --json tmp/appmap > jenkins-unfiltered-stats.json
|
|
109
|
+
```
|
|
110
|
+
{: .example-code}
|
|
111
|
+
|
|
112
|
+
The output will contain statistics for all calls in all files, formatted as JSON.
|
|
113
|
+
|
|
114
|
+
Next, examine the statistics to look for methods that can be considered for exclusion:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
% jq -r '.totals[] | select(.calls > 75) | " - \(.method)"' jenkins-unfiltered-stats.json | sort | uniq > exclusions.yml
|
|
118
|
+
% grep hudson exclusions.yml | head -5
|
|
119
|
+
- hudson.ExpressionFactory2#createExpression
|
|
120
|
+
- hudson.ExpressionFactory2$JellyJexlContext#getVars
|
|
121
|
+
- hudson.ExpressionFactory2$JellyMap#get
|
|
122
|
+
- hudson.ExpressionFactory2$JexlExpression#evaluate
|
|
123
|
+
- hudson.ExtensionComponent#getInstance
|
|
124
|
+
% grep jenkins exclusions.yml | head -5
|
|
125
|
+
- jenkins.MetaLocaleDrivenResourceProvider#lookup
|
|
126
|
+
- jenkins.model.Jenkins#getACL
|
|
127
|
+
- jenkins.model.Jenkins#getAuthorizationStrategy
|
|
128
|
+
- jenkins.model.Jenkins#getCrumbIssuer
|
|
129
|
+
- jenkins.model.Jenkins#getDescriptor
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This finds methods that are called more than 75 times and saves them in a useful
|
|
133
|
+
form. Sorting them makes them easier to include in `appmap.yml`. Duplicate
|
|
134
|
+
method names will appear in the recording because of method overloading, but it's not
|
|
135
|
+
necessary to list them separately in the configuration. They can be removed.
|
|
136
|
+
|
|
137
|
+
Note that there's nothing special about the 75-call threshold used to select calls for
|
|
138
|
+
exclusion. Depending on your application, a different value may produce better results.
|
|
139
|
+
|
|
140
|
+
## Step 3: Update the configuration and create new AppMap Diagrams
|
|
141
|
+
|
|
142
|
+
The new configuration in `appmap.yml` gets updated to look like this:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
name: Jenkins
|
|
146
|
+
packages:
|
|
147
|
+
- path: org.acegisecurity.context
|
|
148
|
+
exclude:
|
|
149
|
+
- org.acegisecurity.context.SecurityContextHolder.setContext
|
|
150
|
+
- org.acegisecurity.context.SecurityContextImpl#getAuthentication
|
|
151
|
+
- org.acegisecurity.context.ThreadLocalSecurityContextHolderStrategy#getContext
|
|
152
|
+
- org.acegisecurity.context.ThreadLocalSecurityContextHolderStrategy#setContext
|
|
153
|
+
|
|
154
|
+
- path: hudson
|
|
155
|
+
exclude:
|
|
156
|
+
- hudson.ExpressionFactory2#createExpression
|
|
157
|
+
- hudson.ExpressionFactory2$JellyJexlContext#getVars
|
|
158
|
+
- hudson.ExpressionFactory2$JellyMap#get
|
|
159
|
+
- hudson.ExpressionFactory2$JexlExpression#evaluate
|
|
160
|
+
...
|
|
161
|
+
- path: jenkins
|
|
162
|
+
exclude:
|
|
163
|
+
- jenkins.MetaLocaleDrivenResourceProvider#lookup
|
|
164
|
+
- jenkins.model.Jenkins#getACL
|
|
165
|
+
- jenkins.model.Jenkins#getAuthorizationStrategy
|
|
166
|
+
- jenkins.model.Jenkins#getCrumbIssuer
|
|
167
|
+
...
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
where the `exclude` sections should contain all the appropriate exclusions from
|
|
172
|
+
`exclusions.yml`.
|
|
173
|
+
|
|
174
|
+
With the configuration in place, rerun the tests and see the results:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
% mvn test -Dtest=NodeCanTakeTaskTest
|
|
178
|
+
...
|
|
179
|
+
% ls -lsh tmp/appmap | sort -n
|
|
180
|
+
total 11176
|
|
181
|
+
776 -rw-r--r-- 1 ajp staff 329K Nov 11 10:41 hudson_model_DirectlyModifiableViewTest_doRemoveJobFromView.appmap.json
|
|
182
|
+
776 -rw-r--r-- 1 ajp staff 370K Nov 11 10:41 hudson_model_DirectlyModifiableViewTest_doAddJobToView.appmap.json
|
|
183
|
+
1416 -rw-r--r-- 1 ajp staff 693K Nov 11 10:41 hudson_model_DirectlyModifiableViewTest_manipulateViewContent.appmap.json
|
|
184
|
+
4104 -rw-r--r-- 1 ajp staff 1.3M Nov 11 10:41 hudson_model_DirectlyModifiableViewTest_doAddNestedJobToRecursiveView.appmap.json
|
|
185
|
+
4104 -rw-r--r-- 1 ajp staff 1.8M Nov 11 10:41 hudson_model_DirectlyModifiableViewTest_failWebMethodForIllegalRequest.appmap.json
|
|
186
|
+
```
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
guides: true
|
|
4
|
+
title: Docs - Guides
|
|
5
|
+
description: "Learn to reverse engineer efficiently using AppMap. Capture code execution details effortlessly. Visualize data for insights. Automate AppMap creation and storage for collaboration."
|
|
6
|
+
step: 9
|
|
7
|
+
render_with_liquid: false
|
|
8
|
+
name: Reverse Engineering
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Reverse Engineering with AppMap <!-- omit in toc -->
|
|
12
|
+
|
|
13
|
+
- [Introduction](#introduction)
|
|
14
|
+
- [Pre-requisites](#pre-requisites)
|
|
15
|
+
- [Step 1: Install the AppMap extension for your code editor](#step-1-install-the-appmap-extension-for-your-code-editor)
|
|
16
|
+
- [Add AppMap to your project](#add-appmap-to-your-project)
|
|
17
|
+
- [Commit your changes](#commit-your-changes)
|
|
18
|
+
- [Step 2: Make AppMap Diagrams for one aspect of your code](#step-2-make-appmap-diagrams-for-one-aspect-of-your-code)
|
|
19
|
+
- [Run applicable test cases](#run-applicable-test-cases)
|
|
20
|
+
- [Expand AppMap coverage with requests recording](#expand-appmap-coverage-with-requests-recording)
|
|
21
|
+
- [Step 3: Use AppMap Diagrams in your code editor](#step-3-use-appmap-diagrams-in-your-code-editor)
|
|
22
|
+
- [Inspect a specific request](#inspect-a-specific-request)
|
|
23
|
+
- [Declutter your AppMap](#declutter-your-appmap)
|
|
24
|
+
- [Hide a function](#hide-a-function)
|
|
25
|
+
- [Exclude a function from future AppMap Diagrams](#exclude-a-function-from-future-appmap-diagrams)
|
|
26
|
+
- [Set the Root event](#set-the-root-event)
|
|
27
|
+
- [Inspect timing and performance](#inspect-timing-and-performance)
|
|
28
|
+
- [Inspect a code object](#inspect-a-code-object)
|
|
29
|
+
- [Checklist](#checklist)
|
|
30
|
+
- [Step 4: Share AppMap Diagrams with your team](#step-4-share-appmap-diagrams-with-your-team)
|
|
31
|
+
- [Checklist](#checklist-1)
|
|
32
|
+
- [Step 5: Automate collection and storage of AppMap Data](#step-5-automate-collection-and-storage-of-appmap-data)
|
|
33
|
+
- [Saving AppMap Data in CI](#saving-appmap-data-in-ci)
|
|
34
|
+
- [In GitHub Actions](#in-github-actions)
|
|
35
|
+
- [In other CI tools](#in-other-ci-tools)
|
|
36
|
+
- [Matrix builds](#matrix-builds)
|
|
37
|
+
- [Checklist](#checklist-2)
|
|
38
|
+
- [Step 6: Use AppMap Diagrams to investigate a code issue](#step-6-use-appmap-diagrams-to-investigate-a-code-issue)
|
|
39
|
+
- [Obtain the archive](#obtain-the-archive)
|
|
40
|
+
- [Checklist](#checklist-3)
|
|
41
|
+
- [Step 7: Improve application coverage](#step-7-improve-application-coverage)
|
|
42
|
+
- [Next Steps - AppMap analysis](#next-steps---appmap-analysis)
|
|
43
|
+
|
|
44
|
+
# Introduction
|
|
45
|
+
AppMap is a powerful tool for reverse-engineering legacy code. Unlike telemetry-based approaches, no modifications to the source code are needed. Simply run the application with the AppMap recording agent enabled, and all the details of code execution are recorded into plain JSON files. These files contain HTTP server requests, internal function calls, SQL, HTTP client requests, and more. AppMap can render this data in powerful interactive visualizations, including dependency map, sequence diagram, trace view, and flame graph.
|
|
46
|
+
|
|
47
|
+
The data can be further combined, compared, and analyzed to obtain key insights about how the code works and how it can be improved. The purpose of this guide is to provide a step-by-step procedure for characterizing a large codebase with AppMap and obtaining these insights.
|
|
48
|
+
|
|
49
|
+
## Pre-requisites
|
|
50
|
+
You should first review our guide on [how to make AppMap Data](/docs/get-started-with-appmap/making-appmap-data).
|
|
51
|
+
|
|
52
|
+
# Reverse Engineering an Application - A Step by Step Process
|
|
53
|
+
This section provides a procedure for characterizing your code using AppMap. Consider this procedure as a recommendation on how to get started. For your specific needs, you’ll likely find useful ways to extend and customize these recommendations.
|
|
54
|
+
|
|
55
|
+
## Step 1: Install the AppMap extension for your code editor
|
|
56
|
+
The code editor is the best way to get started using AppMap. Install the AppMap extension for [VSCode](https://marketplace.visualstudio.com/items?itemName=appland.appmap) or [JetBrains](https://plugins.jetbrains.com/plugin/16701-appmap), then follow the install workflow that will be prompted inside the code editor.
|
|
57
|
+
|
|
58
|
+
#### Add AppMap to your project
|
|
59
|
+
|
|
60
|
+
**Note (Monorepo / Multi-project)** If you have an “umbrella” project that contains multiple sub-projects, aka “monorepo”, choose one project to start. The best choice is a web application or web service API, since AppMap is optimized for web apps.
|
|
61
|
+
|
|
62
|
+
Here’s a checklist:
|
|
63
|
+
|
|
64
|
+
- ☐ Prepare a working development environment for your project. Confirm that you can either run the application locally or in a Docker container. If your project has test cases, confirm that they are working as expected.
|
|
65
|
+
- ☐ Create a new branch of the code, called `install-appmap`.
|
|
66
|
+
- ☐ Install AppMap extension for the code editor.
|
|
67
|
+
- ☐ When prompted, Activate AppMap using GitHub or GitLab OAuth. You’ll be redirected back to your code editor.
|
|
68
|
+
- ☐ Open the Install instructions, which are built into the code editor via the AppMap extension.
|
|
69
|
+
- ☐ Select the project you want to configure for AppMap.
|
|
70
|
+
- ☐ Ruby, Python - Add the AppMap language agent to your project
|
|
71
|
+
- ☐ Java - Confirm that the AppMap agent JAR is downloaded, and that you have a Run Configuration (JetBrains) or Launch Configuration (VSCode) that configures the JVM to load the AppMap agent JAR. You can also install AppMap for Maven and/or Gradle, as you wish. This will make it easier to make AppMap Data from the command line - you may or may not care about that right now.
|
|
72
|
+
- ☐ Node.js - Change how you launch your application by prepending `npx appmap-node` to it.
|
|
73
|
+
- ☐ Confirm that the AppMap configuration is working. You can do this by either:
|
|
74
|
+
a) [Recording a test case](/docs/recording-methods.html#test-case-recording), or
|
|
75
|
+
b) Starting your application and making [requests recordings](/docs/recording-methods.html#requests-recording).
|
|
76
|
+
|
|
77
|
+
**Note (Java)** AppMap recording depends on having the AppMap Java agent enabled in your process using the javaagent JVM argument. The AppMap extension will download the AppMap Java agent to $HOME/lib/java. However this may be blocked in certain corporate environments. You can download the AppMap Java agent manually from [GitHub](https://github.com/getappmap/appmap-java/releases). Different tools (IntelliJ, Maven, Gradle, Tomcat etc) have different ways of specifying JVM arguments. AppMap does provide plugins for Maven and Gradle - these can be helpful in many cases. Or you can configure the javaagent flag yourself using online resources and examples.
|
|
78
|
+
|
|
79
|
+
#### Commit your changes
|
|
80
|
+
|
|
81
|
+
At this point, you’ve added AppMap to your project and confirmed that it’s working. Prepare a commit that includes:
|
|
82
|
+
|
|
83
|
+
* Any modified package management files (e.g. `pom.xml`, `requirements.txt`, `Gemfile`, `package.json`, `yarn.lock`, etc.).
|
|
84
|
+
* `appmap.yml`
|
|
85
|
+
* Recommended project extensions, e.g. `extensions.json`
|
|
86
|
+
* `.gitignore` of the AppMap directory
|
|
87
|
+
|
|
88
|
+
**Note (Monorepo / Multi-project)** The package management and `appmap.yml` changes should be within the sub-project that you’re configuring for AppMap. The `extensions.json` will be in the project root directory.
|
|
89
|
+
|
|
90
|
+
## Step 2: Make AppMap Diagrams for one aspect of your code
|
|
91
|
+
In a large project, it’s best to start making AppMap Diagrams in one functional area. For example, suppose you want to characterize the login and password reset functionality.
|
|
92
|
+
|
|
93
|
+
#### Run applicable test cases
|
|
94
|
+
Start by recording any test cases that are applicable to this functional area. Test cases that traverse through the HTTP and SQL stack are the most useful. Unit tests and tests that mock or stub SQL are of less utility, since they don’t show the actual behavior of the application API and interactions with the data store. If you don’t have relevant tests - or just can’t easily determine if you do or not - proceed to the next step: requests recording.
|
|
95
|
+
|
|
96
|
+
If you have a really large test suite, it’s useful to start generating AppMap Data of a subset of it, to make the turnaround times quicker for getting through this process. This approach also enables you to roll out AppMap incrementally to your team via the [GitHub Action](/docs/integrations/github-actions) or [CircleCI](/docs/integrations/circle-ci), without worrying about introducing too much overhead to the CI job.
|
|
97
|
+
|
|
98
|
+
<table class="table table-striped table-bordered">
|
|
99
|
+
<tr>
|
|
100
|
+
<th>Language</th>
|
|
101
|
+
<th>Test Framework</th>
|
|
102
|
+
<th>Subsetting Strategy</th>
|
|
103
|
+
</tr>
|
|
104
|
+
<tr>
|
|
105
|
+
<td>Ruby</td>
|
|
106
|
+
<td><code>rspec</code></td>
|
|
107
|
+
<td>Enable tests selectively with the rspec tag <code>appmap: true</code>.<br><br>Run <code>rspec -t @appmap=true</code></td>
|
|
108
|
+
</tr>
|
|
109
|
+
<tr>
|
|
110
|
+
<td>Java</td>
|
|
111
|
+
<td><code>JUnit</code></td>
|
|
112
|
+
<td>Run specific tests from the IDE UI. Use VSCode Launch configuration or IntelliJ “Start with AppMap”</td>
|
|
113
|
+
</tr>
|
|
114
|
+
<tr>
|
|
115
|
+
<td>Python</td>
|
|
116
|
+
<td><code>pytest</code></td>
|
|
117
|
+
<td>Filter by test names using the <code>-k</code> argument.</td>
|
|
118
|
+
</tr>
|
|
119
|
+
<tr>
|
|
120
|
+
<td>Python</td>
|
|
121
|
+
<td><code>unittest</code></td>
|
|
122
|
+
<td>Specify tests using the <code>-m</code> argument, or aggregate using <code>unittest.TestSuite</code></td>
|
|
123
|
+
</tr>
|
|
124
|
+
<tr>
|
|
125
|
+
<td>Node</td>
|
|
126
|
+
<td><code>jest</code></td>
|
|
127
|
+
<td>Pass jest a path to a directory of tests, or use <code>-t</code> to run tests matching a regex pattern</td>
|
|
128
|
+
</tr>
|
|
129
|
+
<tr>
|
|
130
|
+
<td>Node</td>
|
|
131
|
+
<td><code>mocha</code></td>
|
|
132
|
+
<td>Pass mocha a path to a directory of tests, or use <code>--grep</code> to run tests matching a regex pattern</td>
|
|
133
|
+
</tr>
|
|
134
|
+
</table>
|
|
135
|
+
_Test subsetting strategies_
|
|
136
|
+
|
|
137
|
+
#### Expand AppMap coverage with requests recording
|
|
138
|
+
You can expand your AppMap coverage beyond what’s available with your test suite using [Requests recording](/docs/recording-methods.html#requests-recording).
|
|
139
|
+
|
|
140
|
+
Requests recording is like a “live mode” for making AppMap Diagrams - it emits AppMap Data as you use the app. To continue the example of characterizing the login + password flow, start your application with AppMap enabled. Then proceed through a predefined user flow - for example: login in, unable to login, request a password reset. QA scripts will often provide reproducible scenarios like this for stepping through the application. If no QA scripts are available, just step through the application as a user would. As you interact with the application, “requests recording” will be create an AppMap Diagram for every request. You can find them in `$appmap_dir/requests`. Open any AppMap from this folder to visualize the end-to-end code behavior for that request.
|
|
141
|
+
|
|
142
|
+
## Step 3: Use AppMap Diagrams in your code editor
|
|
143
|
+
|
|
144
|
+
#### Inspect a specific request
|
|
145
|
+
AppMap Diagrams that contain HTTP server requests contain the most rich and useful data. Open the AppMap view in your code editor. There you’ll find a section called “Code objects”. It contains all the HTTP server routes and SQL statements that have been recorded in your AppMap Diagram. It also contains a tree of Code, which you can expand from packages into classes and functions.
|
|
146
|
+
|
|
147
|
+

|
|
148
|
+
|
|
149
|
+
Choose an HTTP server request and click on it. If there is one AppMap of that route, it will open in your code editor. If there are multiple AppMap Diagrams of that route, you’ll be prompted to choose one.
|
|
150
|
+
|
|
151
|
+
This is an example of a test case AppMap. It includes 4 HTTP server requests, plus code and SQL.
|
|
152
|
+
|
|
153
|
+

|
|
154
|
+
|
|
155
|
+
You can [download this file](/assets/appmaps/authn_provider_not_logged_in.appmap.json) if you'd like to open it within your code editor.
|
|
156
|
+
|
|
157
|
+
#### Declutter your AppMap
|
|
158
|
+
One of the challenges with reverse engineering large applications is that the AppMap Data can be large and complicated. AppMap offers tools to declutter and filter your AppMap Data. We will look more closely at that here.
|
|
159
|
+
|
|
160
|
+
##### Hide a function
|
|
161
|
+
In most code bases, there are a few very frequently occurring functions that are mostly noise. You can take two steps to declutter your diagram and reduce the noise.
|
|
162
|
+
|
|
163
|
+
Open the AppMap stats using the icon in the top-right corner of the AppMap.
|
|
164
|
+
|
|
165
|
+

|
|
166
|
+
|
|
167
|
+
You’ll see a list of the most frequently occurring methods.
|
|
168
|
+
|
|
169
|
+

|
|
170
|
+

|
|
171
|
+
|
|
172
|
+
Click on one of these methods to reveal it in the diagram, and on the left hand side panel. Then click “Hide” to remove all occurrences from the display.
|
|
173
|
+
|
|
174
|
+

|
|
175
|
+
|
|
176
|
+
To reveal it again, you can use “Reset all”, or open the Filter menu pop up where you will see a list of all hidden code objects.
|
|
177
|
+
|
|
178
|
+
##### Exclude a function from future AppMap Diagrams
|
|
179
|
+
You can also go further, by excluding a class function from the AppMap at recording time. To do this, you’ll add a line to your `appmap.yml`. Consult the [reference for your language agent](/docs/reference). For example, in Java you can exclude specific functions like this:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
packages:
|
|
183
|
+
- path: com.mycorp.myproject
|
|
184
|
+
exclude: [ com.mycorp.myproject.MyClass#MyMethod ]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This function will be excluded from all future AppMap Diagrams. Some language agents also support exclusion by wildcard.
|
|
188
|
+
|
|
189
|
+
#### Set the Root event
|
|
190
|
+
You can also choose any event in the AppMap to be the root event. Only descendants of this event will be displayed.
|
|
191
|
+
|
|
192
|
+
You can clear the root by clicking `Reset all`.
|
|
193
|
+
|
|
194
|
+

|
|
195
|
+
|
|
196
|
+
#### Inspect timing and performance
|
|
197
|
+
Use the filter `Hide elapsed time under` to focus the diagram only on slow functions and queries.
|
|
198
|
+
|
|
199
|
+

|
|
200
|
+
|
|
201
|
+
You can also drill into timing data using the Flame Graph view.
|
|
202
|
+
|
|
203
|
+

|
|
204
|
+
|
|
205
|
+
#### Inspect a code object
|
|
206
|
+
In the previous section, we covered how to analyze the implementation of an HTTP route. You can do the same thing starting with a function or class.
|
|
207
|
+
|
|
208
|
+
Expand the Code tree until you find the class or function you’re interested in. When you click on it, you’ll either be taken to the AppMap, or prompted to choose an AppMap.
|
|
209
|
+
|
|
210
|
+

|
|
211
|
+
|
|
212
|
+
The AppMap will open to the Dependency Map with the function pre-selected. You can click the “Eye” icon to open the event in the Sequence Diagram.
|
|
213
|
+
|
|
214
|
+

|
|
215
|
+
|
|
216
|
+
#### Checklist
|
|
217
|
+
- ☐ Open Code Objects view, select an HTTP server request and open the AppMap from it
|
|
218
|
+
- ☐ Review the Stats view
|
|
219
|
+
- ☐ Declutter by Hiding a function - from the stats view, from the left hand side panel, or by clicking a package X on the sequence diagram
|
|
220
|
+
- ☐ Declutter by setting the Root
|
|
221
|
+
- ☐ Add a frequent / noisy function to the exclude list in appmap.yml - consult the reference for you language on syntax
|
|
222
|
+
- ☐ Try the filter to hide by elapsed time
|
|
223
|
+
- ☐ Try the Flame Graph view
|
|
224
|
+
|
|
225
|
+
## Step 4: Share AppMap Diagrams with your team
|
|
226
|
+
If you’ve made any more updates to `appmap.yml`, be sure and commit the changes to the repo. It’s time to share AppMap with other members of your team!
|
|
227
|
+
|
|
228
|
+
When a new user pulls down your branch, they will automatically inherit the AppMap configuration that you’ve created. So, a new team member only needs to do the following steps in order to start using AppMap:
|
|
229
|
+
|
|
230
|
+
- ☐ Install AppMap extension for the code editor.
|
|
231
|
+
- ☐ Activate AppMap using GitHub or GitLab OAuth. Follow the redirect back to the code editor.
|
|
232
|
+
- ☐ Open the install flow to the `Record AppMap` step. There, they can start making their own AppMap Diagrams using any of the supported [Recording methods](/docs/recording-methods.html). The work that you’ve done to configure the code paths and exclusions will apply automatically to their installation.
|
|
233
|
+
|
|
234
|
+
In addition to code paths and exclusions, your team members might want to share AppMap Diagram configuration with each other as well - for example Filter settings.
|
|
235
|
+
|
|
236
|
+

|
|
237
|
+
|
|
238
|
+
You can use the Saved Filters within your own installation. To share Filter settings with other users, create a new entry in `appmap.yml` called `filters`. Use the VSCode command `Copy Current AppMap State to Clipboard` to place the Filter configuration on your clipboard. It will be a Base64 encoded string - which is just a wrapper around JSON.
|
|
239
|
+
|
|
240
|
+

|
|
241
|
+
|
|
242
|
+
Add that filter configuration to `appmap.yml`:
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
# appmap.yml
|
|
246
|
+
filters:
|
|
247
|
+
my_filter: eyJjdXJyZW50VmlldyI6InZpZXdDb21wb25lbnQiLCJzZWxlY3RlZE9iamVjdCI6ImV2ZW50OjUxMiIsImZpbHRlcnMiOnsiaGlkZUV4dGVybmFsUGF0aHMiOlsidmVuZG9yIiwibm9kZV9tb2R1bGVzIl19fQ
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Commit and push your changes to `appmap.yml`.
|
|
251
|
+
|
|
252
|
+
When a user wants to apply that filter to their AppMap, they can copy the filter string out of the `appmap.yml` and then run the command `Set AppMap State from Serialized String`.
|
|
253
|
+
|
|
254
|
+

|
|
255
|
+
|
|
256
|
+
Of course, you can also share filter strings using other channels, like Slack, or store them in a common location such as a Wiki.
|
|
257
|
+
|
|
258
|
+
#### Checklist
|
|
259
|
+
- ☐ Commit and push changes to appmap.yml
|
|
260
|
+
- ☐ Send an AppMap to a colleague - you can send the JSON file via email or chat, they can drag and drop it into their code editor
|
|
261
|
+
- ☐ Save Filter settings to the clipboard, then save to appmap.yml or send via chat
|
|
262
|
+
|
|
263
|
+
## Step 5: Automate collection and storage of AppMap Data
|
|
264
|
+
Now that the project is configured for AppMap and you’ve decided if you want to ignore any code in the AppMap, it’s time to run AppMap on the full test suite (or, if you prefer, an expanded subset). Doing this will enable you to see how well your app is covered by tests, and understand how you need to augment the tests in order to cover the app fully. You’ll also be ready to take future steps such as:
|
|
265
|
+
|
|
266
|
+
* Exporting AppMap Diagrams to an external documentation repository.
|
|
267
|
+
* Using AppMap Diagrams to troubleshoot a code issue.
|
|
268
|
+
* Creating pull request reports using AppMap Analysis.
|
|
269
|
+
|
|
270
|
+
**Note:** You can do all these steps in your current branch, or you can merge the `install-appmap` branch and create a new branch called `install-appmap-ci`. In either case, you don’t have to change the CI configuration on the main/master branch until you’re fully done integrating and evaluating AppMap.
|
|
271
|
+
|
|
272
|
+
To create AppMap Data in CI, you’ll need to confirm that the test command you’re using in your CI job is AppMap-enabled. In Ruby and Python, this is already going to be the case because adding the appmap dependency is all that’s needed. In Java, you need to configure the test command to load the `javaagent`. Specific instructions are available for doing this with [Maven](/docs/reference/appmap-maven-plugin.html#installation) and [Gradle](/docs/reference/appmap-gradle-plugin.html#installation). Confirm that your test command makes AppMap Data locally before pushing it up to CI.
|
|
273
|
+
|
|
274
|
+
Once you’re ready, go ahead and push the branch to kick off a CI run. In the meantime, we’ll work on the next steps for your CI job.
|
|
275
|
+
|
|
276
|
+
#### Saving AppMap Data in CI
|
|
277
|
+
Once you’ve created AppMap in CI, you don’t want them to disappear when the job ends. AppMap provides tool support for saving AppMap Data as a build artifact.
|
|
278
|
+
|
|
279
|
+
#### In GitHub Actions
|
|
280
|
+
[getappmap/archive-action](https://github.com/marketplace/actions/build-and-save-an-appmap-archive) is a GitHub Action that will save a GitHub Artifact containing all the AppMap Data created in a workflow. To use the archive action, you need to install the AppMap CLI tools, then run the archive-action. It looks like this:
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
- name: Install AppMap tools
|
|
284
|
+
uses: getappmap/install-action@v1
|
|
285
|
+
with:
|
|
286
|
+
install-appmap-library: false
|
|
287
|
+
|
|
288
|
+
(run your tests)
|
|
289
|
+
|
|
290
|
+
- name: Archive AppMap Data
|
|
291
|
+
uses: getappmap/archive-action@v1
|
|
292
|
+
with:
|
|
293
|
+
commit: ${{ github.event.pull_request.base.sha }}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### In other CI tools
|
|
297
|
+
If you’re using a CI environment other than GitHub Actions, you can use the AppMap CLI tools directly.
|
|
298
|
+
|
|
299
|
+
Start by downloading the latest [@appland/appmap](https://github.com/getappmap/appmap-js/releases) distribution for your platform. The appmap CLI includes an `archive` command, which performs the following steps:
|
|
300
|
+
|
|
301
|
+
* Updates all index files associated with the AppMap Data
|
|
302
|
+
* Generates a sequence diagram file of each AppMap
|
|
303
|
+
* Runs the AppMap scanner to identify performance and security flaws.
|
|
304
|
+
* Generates OpenAPI definitions of the project.
|
|
305
|
+
* Stores all this data, along with identifying metadata, in a TAR file. The TAR file contains a gzipped TAR of the AppMap Data.
|
|
306
|
+
|
|
307
|
+
You can then store this archive anywhere you keep large files. The `appmap restore` command can be used to expand this archive back into individual AppMap files, along with the indexes, sequence diagram files, findings, and OpenAPI definitions.
|
|
308
|
+
|
|
309
|
+
So, once the AppMap Data is created by the CI job, run `appmap archive` to create an AppMap archive file. You can save this archive file to the artifact store of your CI provider.
|
|
310
|
+
|
|
311
|
+
#### Matrix builds
|
|
312
|
+
Large projects often use matrix builds to distribute the testing load across multiple machines. AppMap in CI supports matrix builds.
|
|
313
|
+
|
|
314
|
+
For GitHub Actions, you can find further information about matrix builds [here](/docs/integrations/github-actions.html#matrix-builds).
|
|
315
|
+
|
|
316
|
+
For other CI tools, you need to create an appmap archive on each worker node. Then add a single “gather” step to collect the worker archives together, unpack them, and merge them into a single final archive using the archive --no-index flag.
|
|
317
|
+
|
|
318
|
+
#### Checklist
|
|
319
|
+
- ☐ Enable AppMap in CI
|
|
320
|
+
- ☐ Run a build job to create AppMap Data
|
|
321
|
+
- ☐ Run the `appmap archive` command to save AppMap Data
|
|
322
|
+
- ☐ Store the archive in the CI server as a build artifact
|
|
323
|
+
|
|
324
|
+
## Step 6: Use AppMap Diagrams to investigate a code issue
|
|
325
|
+
At this point, you have archives of AppMap Data for different versions of your code, and you can restore those archives into your code editor to use the AppMap extension to investigate any type of code problem.
|
|
326
|
+
|
|
327
|
+
Let’s take a deeper dive into how that works. Suppose your team has recently deployed new code, and you’re getting an alarm from the production monitoring system. There is a web route that’s performing badly, a SQL query that’s running slow, or an exception that keeps being raised and disrupting user sessions.
|
|
328
|
+
|
|
329
|
+
* Obtain the archive for the affected version of the code
|
|
330
|
+
* Find the problematic query, exception or route in the code objects view
|
|
331
|
+
* Investigate the scenarios in which this code is used
|
|
332
|
+
* Take a look at which code paths have been tested in CI, and which haven’t been tested. This can help you to reproduce the problem locally
|
|
333
|
+
* For SQL, identify where in the code the query is being issued. This can be difficult when queries are generated by ORM. AppMap makes it easy to figure this out.
|
|
334
|
+
|
|
335
|
+
##### Obtain the archive
|
|
336
|
+
Note If you don’t have saved archives yet, you can build AppMap Data for troubleshooting using remote recording or requests recording. This section shows how restoring AppMap archives can enable you to skip that step and get right to code investigation.
|
|
337
|
+
|
|
338
|
+
Once you’ve integrated AppMap with CI, you’ll have a saved AppMap archive for each version of the code that’s been merged to the main branch. So your first troubleshooting step is to determine which version of the code is affected. Then you can obtain the AppMap archive for that version of the code.
|
|
339
|
+
|
|
340
|
+
You can use the AppMap `restore` command to expand the AppMap archive into your local, working environment. Copy the archive file into the project directory `.appmap/archive/full/<revision>.tar`. Then run the restore command to unpack it:
|
|
341
|
+
|
|
342
|
+
```
|
|
343
|
+
appmap restore --revision <revision> --exact --output-dir tmp/appmap
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Now the AppMap Data are unpacked into the `tmp/appmap` directory and they will be detected and listed by the AppMap extension in your code editor. You can use all the techniques described in the [Use AppMap Diagrams](#step-3-use-appmap-diagrams-in-your-code-editor) section to investigate the problem.
|
|
347
|
+
|
|
348
|
+
#### Checklist
|
|
349
|
+
- ☐ Download an AppMap archive from CI server
|
|
350
|
+
- ☐ Use appmap restore to unpack the archive
|
|
351
|
+
- ☐ Open the AppMap Diagram in your code editor
|
|
352
|
+
- ☐ Open the Code Objects view to find AppMap Diagrams for a particular HTTP route, SQL query or function.
|
|
353
|
+
|
|
354
|
+
## Step 7: Improve application coverage
|
|
355
|
+
|
|
356
|
+
You probably have some idea of the test coverage of your application from applying a dedicated code coverage tool. These types of tools will tell you whether you have code that is completely uncovered by tests. But AppMap goes beyond that, to tell you:
|
|
357
|
+
|
|
358
|
+
* Whether different operational scenarios are covered for a function.
|
|
359
|
+
* Which parts of your web services API are actually exercised.
|
|
360
|
+
How your application interacts with external services and the database.
|
|
361
|
+
|
|
362
|
+
The Code Objects view is a good starting point for doing this investigation. You’re looking for:
|
|
363
|
+
|
|
364
|
+
1. How well do the HTTP routes listed in the Code Objects view cover the known API of the application?
|
|
365
|
+
2. Is there functionality that the application is known to have, which is not reflected in these HTTP routes? If so, there is no test coverage of those routes that actually traverses through the web stack.
|
|
366
|
+
|
|
367
|
+
Similarly, with SQL. The Code Objects view provides the inventory of known SQL queries. If there is known code behavior that’s NOT reflected in the Code Objects view, then test coverage that actually exercises the SQL is lacking.
|
|
368
|
+
|
|
369
|
+
When the web stack or SQL queries are not exercised by the test suite, the application is at much higher risk of production security, stability, and performance problems. It’s also very difficult to know how a code change will affect the application when it’s deployed, because a simple code change might turn out to affect many different API routes - or none at all...
|
|
370
|
+
|
|
371
|
+
* Compare with known OpenAPI
|
|
372
|
+
* Compare with known SQL
|
|
373
|
+
* Compare with known code inventory
|
|
374
|
+
|
|
375
|
+
## Next Steps - AppMap analysis
|
|
376
|
+
|
|
377
|
+
Thus far, we’ve shown how to build, maintain and use AppMap archives to investigate, learn and fix code. The next step with AppMap is to use the [GitHub Action](/docs/integrations/github-actions) or [CircleCI](/docs/integrations/circle-ci) to analyze each Pull Request.
|