Skip to content
/ ulyp Public

Simple and small recording debugger for JVM-based apps

License

Notifications You must be signed in to change notification settings

0xaa4eb/ulyp

Repository files navigation

Price Build Status Quality Gate Status Maintainability

TL;DR

Ulyp instruments all third-party library classes and record their method calls including return values and arguments, so that you can have a better understanding of what your code does. Instrumentation is done by byte-buddy library. UI is written using JavaFX.

Example of usage

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:~/Work/ulyp/ulyp-agent/build/libs/ulyp-agent-0.2.1.0.jar
    -Dulyp.methods=**.HibernateShowcase.save
    -Dulyp.file=/tmp/hibernate-recording.dat
    

Whenever methods with name save and class name **.HibernateShowcase (inheritors including) are called, recording will start. The data is dropped to the specified file.

  • Run your code with system properties set.

    @Transactional
    public void save() throws Exception {
        User user = new User("Test", "User");
        saver.save(user);
    }
    
  • Run the UI and open the recording file

Hibernate call recorded

Build from source

Build with gradle: ./gradlew build

Build UI jar file (Java 11+ is preferable) : ./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

Similar projects

Ulyp is POC and unstable all the time since the beginning. There are already similar projects which you might consider to use before Ulyp.

Project Link Source
Bugjailbugjail.comClosed source
Findtheflowfindtheflow.ioClosed source

Key details

All instrumentation is done using byte buddy library. All Java objects are recorded by the recorders. Each recorder supports a particular set of Java types and is responsible for serializing object values into bytes. Note that Ulyp doesn't fully serialize objects. Let's say, for String the first couple of hundred symbols are only recorded.

All data is written to file in a flat format. UI later uses RocksDB in order to build the index

What's not recorded

Currently, none of java standard library classes are instrumented. This means calls of, let's say, add method of java collections are not recorded. However, Ulyp does record object values of java system library classes like strings, numbers, collections (more on that below) etc.

Type initializers (static blocks) are not recorded and there are no plans to support this.

Constructors are not recorded by default (which may distort the view), but may be recorded by specifying system prop -Dulyp.constructors. The reason why constructors are not recorded by default, is simply that it's not possible to instrument constructors in such fashion that any exception thrown inside the constructor is caught and rethrown. But this is exactly what should be done, but is not possible. Therefore, when such case happens, the corresponding recording file may become invalid. In that case UI will show error, and a user should disable the option and run the code again without constructors recorded.

Collections are not recorded by default but can be with system prop -Dulyp.collections. The available values are JAVA and ALL. When set to ALL all collection values will be recorded (actually only first three items are recorded). This means Ulyp will iterate any object which implements java.util.Collection interface. This may be too much especially for certain programs where there are a lot of proxy collections (like Hibernate or Hazelcast proxy collections when iteration triggers network calls). Hence the JAVA option value which only records Java collections.

Try running some code with additional properties -Dulyp.constructors -Dulyp.collections=JAVA to see the difference:

Hibernate call recorded with constructors

UI

UI Controls

Hotkey Action
Hold ShiftShow full type names
Hold XShow method call duration (if enabled with -Dulyp.timestamps)
Press =Increase font size
Press -Decrease font size