Turn your software inside out. The tool records everything you app does, and you then can analyze the execution flow. Bytecode instrumentation is handled by byte-buddy, UI is built on JavaFX.
Here is a basic example. We have a transactional method service and Hibernate is used as a JPA provider.
```
@Service
@Transactional
public class PersonStoreService {
@Autowired
private PersonRepository repository;
public void save(Person person) {
repository.save(person);
}
}
```
Calling this method with ulyp agent enabled is able to provide a full call tree. No code change is required.
The underlying rationale for the development, technical design, as well as some use cases are outlined in the following blog posts:
- Ulyp: Recording Java code execution for faster debugging (ENG)
- Reverse engineer Spring Web in 5 minutes using a recording debugger (ENG)
Usage is relatively simple.
-
First, download or build the agent
-
Second, use VM properties in order to enable the recording. Here is the minimum set of options one will need for recording.
-javaagent:/path/to/ulyp-agent-1.0.0.jar -Dulyp.methods=**.HibernateShowcase.* -Dulyp.file=/tmp/recording.dat
Recording starts when any method of a class which has class name HibernateShowcase
is called. The data is written to the
specified file which can later be opened in the UI.
Examples of method matchers are:
Matcher | Explanation |
---|---|
org.springframework.**.Service.* | Record any method of class Service in package org.springframework (or nested) package |
**.Runnable.run | Record all Runnable instances |
*.* | Record all calls (Experimental) |
The agent is controlled via JVM system properties.
Property | Description | Example | Default |
---|---|---|---|
ulyp.file | A path to a file where all recording data should be written | -Dulyp.file=/tmp/test.dat |
- |
ulyp.methods | A list of method matchers where recording should start | -Dulyp.methods=**.Runnable.run |
Main method |
ulyp.start | Controls when recording can start. default is start recording any time when some of ulyp.method is called.Another option is delay:X where X is the number of seconds to wait from the app launch, api - remote enable/disable (WIP) |
-Dulyp.start=delay:120 |
default |
ulyp.packages | A list of packages to instrument | -Dulyp.packages=org.springframework,io.grpc |
All packages |
ulyp.record-timestamps | Record duration of calls | -Dulyp.record-timestamps |
Disabled |
ulyp.exclude-packages | A list of packages to exclude from instrumentation | -Dulyp.exclude-packages=org.springframework |
- |
ulyp.exclude-types | A list of type matchers to exclude from instrumentation | -Dulyp.exclude-types=org.springframework.**.Interceptor |
- |
ulyp.record-constructors | Enables instrumentation (and possibly recording) of constructors | -Dulyp.record-constructors |
Disabled |
ulyp.record-collections | Records values (some number of items) of collections. Possible values are: NONE , JDK (only JDK collections), ALL (dangerous) |
-Dulyp.record-collections=JDK |
NONE |
ulyp.record-collections.max-items | Max items of collections to record | -Dulyp.record-collections.max-items=5 |
3 |
ulyp.record-arrays | Records values (some number of items) of arrays | -Dulyp.record-arrays |
Disabled |
ulyp.record-arrays.max-items | Max items of arrays to record | -Dulyp.record-arrays.max-items=10 |
3 |
ulyp.record-lambdas | Enabled instrumentation (and possibly recording) of lambdas (experimental) | -Dulyp.record-lambdas |
Disabled |
ulyp.record-static-blocks | Enabled instrumentation (and possibly recording) of static blocks (experimental) | -Dulyp.record-static-blocks |
Disabled |
ulyp.print-types | A list of type matchers to print with toString() while recording their values | -Dulyp.print-types=com.enterprise.**.SomeEntity |
- |
ulyp.recorder.max-string-length | A maximum number of characters for String recording | -Dulyp.recorder.max-string-length=400 |
200 |
Hotkey | Action |
---|---|
Hold Shift | Show full type names |
Hold X | Show method call duration (if enabled with -Dulyp.record-timestamps while recording) |
Press = | Increase font size |
Press - | Decrease font size |
Build agent (no tests):
./gradlew :ulyp-agent:shadowJar
Build UI jar file (Java 11+ (preferred) or Java 8 Oracle with Java FX bundled) :
./gradlew :ulyp-ui:fatJar
UI jar file for a particular platform can be built as follows:
./gradlew :ulyp-ui:fatJar -Pplatform=mac
Available platforms for the build are: linux
, linux-aarch64
, win
, mac
, mac-aarch64