Ulyp
Tracing debugger/profiler for JVM apps
Install / Use
/learn @cheb0/UlypREADME
TL;DR
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.

Blog posts
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)
How to use
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:
<table> <tr> <th>Matcher</th> <th>Explanation</th> </tr> <tr><td>org.springframework.**.Service.*</td><td>Record any method of class Service in package org.springframework (or nested) package</td></tr> <tr><td>**.Runnable.run</td><td>Record all Runnable instances</td></tr> <tr><td>*.*</td><td>Record all calls (Experimental)</td></tr> </table>Options
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.<br/> 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 |
UI
Controls
<table border="1"> <tr> <th>Hotkey</th> <th>Action</th> </tr> <tr><td>Hold Shift</td><td>Show full type names</td></tr> <tr><td>Hold X</td><td>Show method call duration (if enabled with -Dulyp.record-timestamps while recording)</td></tr> <tr><td>Press =</td><td>Increase font size</td></tr> <tr><td>Press -</td><td>Decrease font size</td></tr> </table>Build from source
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 pl
Related Skills
node-connect
338.7kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
338.7kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.6kCommit, push, and open a PR
