AppMap Agent for Java

About

appmap-agent is a Java agent JAR for recording AppMaps of your code.

The AppMap data format includes code structure (packages, modules, classes, and methods), trace events (function calls, web services, RPC calls, SQL, parameters, return values, exceptions, etc), and code metadata (repo URL, commit SHA, etc). It’s more granular than a performance profile, but it’s less granular than a full debug trace. It’s designed to be optimal for understanding the design intent and structure of code and key data flows.

Supported versions

Supported Java versions: JDK 8, 11, 17

Configuration

When you run your program, the agent reads configuration settings from appmap.yml. Here’s a sample configuration file for a typical Java project:

# 'name' should generally be the same as the code repo name.
name: MyProject
packages:
- path: com.mycorp.myproject
  exclude: [ com.mycorp.myproject.MyClass#MyMethod ]
- path: org.springframework.web
  shallow: true
  exclude: 
  - org.springframework.web.util
- path: java.util.logging
  methods:
  - class: Logger
    name: log

  • name Provides the project name (required)
  • packages A list describing how packages should be instrumented. For backwards compatibility, classes and methods can also be specified here. New projects should use the methods property to specify which methods to instrument.

packages

Each entry in the packages list is a YAML object which has the following keys:

  • path A Java package, class, or method that will be instrumented.
  • exclude A list of fully-qualified sub-packages, sub-classes and sub-methods that will be ignored. The exclude list only applies to the path specified in the same package entry.

  • shallow When set to true, only the first function call entry into a package will be recorded. Subsequent function calls within the same package are not recorded unless code execution leaves the package and re-enters it. Default: false.

  • methods A list of YAML objects describing how specific methods should be handled.
    • class a regular expressiom matching names of classes in the package
    • name a regular expression matching names of methods in class that should be instrumented
    • labels (optional) a list of labels that should be applied to all matching methods.

Each of the class and name regular expressions is a java.util.regex.Pattern . They will be surrounded with \A( )\z to match whole symbols. This means, in the example above, log will match exactly that method of Logger, but not the logp or logrb methods. To match all three methods, use log(|p|rb) or log.*. To include the literal symbols . or $ in the patterns, they must be properly escaped: \. or \$.

If the methods attribute is specified for a package, each element in the list will be matched in the order specified, and only the matching methods will be instrumented. When the methods attribute is set, the exclude attribute is ignored.

Labels

appmap-java suports the addition of code labels through the com.appland.appmap.annotation.Labels annotation.

The Labels annotation is provided in the package com.appland:appmap-annotation, available on Maven Central. To use it, add it as a dependency in your build configuration file (pom.xml, build.gradle).

Usage

Once the Labels annotation is available, you can apply it to methods in your application. For example:

import com.appland.appmap.annotation.Labels;

public class ExampleClass {
  ...
  @Labels({"label1", "label2"})
  public void labeledFunction() {
    ...
  }
}

When labeledFunction appears in an AppMap, it will have the labels label1 and label2.

Tests recording

When running test cases with the agent attached to the JVM, methods marked with JUnit’s @Test annotation will be recorded. A new AppMap file will be created for each unique test case.

To disable recording for a particular JUnit test (for example, a performance test), list the class or methods under an exclude in appmap.yml.

Recording tests with Maven

We recommend using the AppMap Maven plugin.

Recording tests with Gradle

We recommend using the AppMap Gradle plugin.

Other build systems

You can download the latest release of appmap-agent-<version>.jar from https://mvnrepository.com/artifact/com.appland/appmap-agent/latest

The recorder is run as a Java agent. Currently, it must be started along with the JVM. This is done by passing the -javaagent argument to your JVM when recording tests. For example:

$ java -javaagent:lib/appmap-agent-1.15.1.jar myapp.jar

Remote recording

appmap-java supports the AppMap remote recording API. This functionality is provided by the AppMap agent. It will hook an existing servlet, serving HTTP requests to toggle recording on and off.

To run your Java application with remote recording enabled, add the -javaagent JVM parameter to the startup parameters of your application. For example:

java -javaagent:/Users/JavaPowerUser/.m2/repository/com/appland/appmap-agent/1.5.0/appmap-agent-1.5.0.jar -jar target/*.jar

To setup your Java application for remote recording and make a remote recording, follow the Remote recording documentation.

System Properties

  • appmap.config.file Path to the appmap.yml config file. Default: appmap.yml
  • appmap.output.directory Output directory for .appmap.json files. Default: ./tmp/appmap
  • appmap.debug Enable debug logging. Default: null (disabled)
  • appmap.event.valueSize Specifies the length of a value string before truncation occurs. If set to 0, truncation is disabled. Default: 1024
  • appmap.record.private Record private methods, as well as methods with package and protected access. Default: false (no private methods will be recorded).
  • appmap.recording.auto Automatically begin recording at boot time. Default: false
  • appmap.recording.file The file name of the automatic recording to be emitted. Note that the file name will still be prefixed by appmap.output.directory. Default: $TIMESTAMP.appmap.json
  • appmap.recording.name Populates the metadata.name field of the AppMap. Default: $TIMESTAMP

GitHub repository

https://github.com/getappmap/appmap-java


Was this page helpful? thumb_up Yes thumb_down No
Thank you for your feedback!