Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 107 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,129 @@ _Based on [async-profiler 2.8.3](https://github.com/jvm-profiling-tools/java-pro
This is not a fork of [async-profiler](https://github.com/jvm-profiling-tools/async-profiler). This is a work derived from __async-profiler__ but tailored very specifically for Datadog needs.
If you need a full-fledged Java profiler head back to [async-profiler](https://github.com/jvm-profiling-tools/async-profiler)

## Usage
**!TODO!**


## Build

### Prerequisites
1. This project contains Java code and is built by gradle, as such, you need to install a JDK in order to build it. Run `brew install openjdk` to install it on MacOS.
If building and testing on Apple Silicon (M1+), be sure to install an aarch64 OpenJDK distribution, otherwise the architecture used for compilation and the JVM based test suite will not match, which means the tests will not be able to load the dynamic library at runtime.
2. The build requires make, which is included in XCode, but can also be installed by running `brew install make`
3. The build supports googletest for unit testing. To install it, run `brew install googletest` or `sudo apt install libgtest-dev` or `apk add gtest-dev` depending on your platform.
4. The build is applying consistent formatting using 'spotless' Gradle plugin. For C/C++ files it will use `clang-format` version 11. To install it, run `brew install clang-format-11` or `sudo apt install clang-format-11` or `apk add clang-format-11` depending on your platform. If the installed version does not provide `/usr/bin/clang-format` executable create a link like `sudo ln -s /usr/bin/clang-format-11 /usr/bin/clang-format` in order for the 'spotles' pluging to function correctly.
1. JDK 8 or later (required for building)
2. Gradle (included in wrapper)
3. C++ compiler (gcc/g++ or clang)
4. Make (included in XCode on Macos)
5. Google Test (for unit testing)
- On Ubuntu/Debian: `sudo apt install libgtest-dev`
- On macOS: `brew install googletest`
- On Alpine: `apk add gtest-dev`
6. clang-format 11 (for code formatting)
- On Ubuntu/Debian: `sudo apt install clang-format-11`
- On macOS: `brew install clang-format-11`
- On Alpine: `apk add clang-format-11`

### Building the Project
1. Clone the repository:
```bash
git clone https://github.com/DataDog/java-profiler.git
cd java-profiler
```

Once prerequisites have been installed simple as `./gradlew assembleAll`. The resulting artifact is located in `ddprof-lib/build/libs/ddprof-<version>.jar`
2. Build a release version of the project:
```bash
./gradle buildRelease
```

The resulting artifact will be in `ddprof-lib/build/libs/ddprof-<version>.jar`

## Testing
The associated test cases can be run for each specific configuration:
- `testRelase` - test the release artifacts
- `testDebug` - test the debug artifacts
- `testAsan` - test with ASan
- `testTsan` - test with TSan

The tests that create a JFR recording for the purpose of asserting will delete this recording at the end, unless `-PkeepJFRs` is provided to gradle.
### Unit Tests
The project includes both Java and C++ unit tests. You can run them using:

```bash
# Run all tests
./gradlew test

# Run specific test configurations
./gradlew testRelease # Run release build tests
./gradlew testDebug # Run debug build tests
./gradlew testAsan # Run tests with ASan
./gradlew testTsan # Run tests with TSan

One can also completely skip all tests by adding `-Pskip-tests` gradle property.
# Run C++ unit tests only
./gradlew gtestDebug # Run C++ tests in debug mode
./gradlew gtestRelease # Run C++ tests in release mode
```

### Test Options
- Skip all tests: `./gradlew build -Pskip-tests`
- Keep JFR recordings: `./gradlew test -PkeepJFRs`
- Skip native build: `./gradlew build -Pskip-native`
- Skip C++ tests: `./gradlew build -Pskip-gtest`

## Development

### Code Quality
The project uses several tools for code quality:

1. clang-format for C++ code formatting
2. scan-build for static analysis
3. cppcheck for additional C++ checks

Run code quality checks:
```bash
# Run scan-build (this will use the scan-build binary)
./gradlew scanBuild

# Run cppcheck (if configured)
./gradlew cppcheck

# Run spotless (including code formatting)
./gradlew spotlessApply
```

### Debugging
**!TODO!**

### Stress Tests
The project includes JMH-based stress tests:

```bash
# Run all stress tests
./gradlew :ddprof-stresstest:runStressTests

### Common Issues
1. If you encounter strange crashes Asan:
```bash
sudo sysctl vm.mmap_rnd_bits=28
```

2. For ASan/TSan issues, ensure you have the required libraries installed:
- ASan: `libasan`
- TSan: `libtsan`

## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests: `./gradlew test`
5. Submit a pull request

## License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

## Usage

### Example

Download the latest version of dd-trace-java and add `-Ddd.profiling.ddprof.debug.lib`. Example of a command line:
```bash
DD_SERVICE=your-service DD_TRACE_DEBUG=true java -javaagent:./temp/dd-java-agent.jar -Ddd.profiling.enabled=true -Ddd.profiling.ddprof.enabled=true -Ddd.profiling.ddprof.liveheap.enabled=true -Ddd.profiling.upload.period=10 -Ddd.profiling.start-force-first=true -Ddd.profiling.ddprof.debug.lib=~/dd/java-profiler/ddprof-lib/build/lib/main/debug/linux/x64/libjavaProfiler.so -XX:ErrorFile=${PWD}/hs_err_pid%p.log -XX:OnError='java -jar temp/dd-java-agent.jar uploadCrash hs_err_pid%p.log' -jar ./temp/renaissance-gpl-0.15.0.jar akka-uct -r 5
```

### Consuming the artifact

For dd-trace-java you just need to set the `ddprof.jar` project property.
Eg. you can run the gradle build like this - ./gradlew clean -Pddprof.jar=file://<path-to-artifact.jar> :dd-java-agent:shadowJar` - which will result in a custom `dd-java-agent.jar` build containing your test version of Java profiler.

## Working with upstream

Although this project still shares the git history with the upstream the code structure is different. This makes it dificult to reliably
cherry-pick the upstream changes. To make this easier we have a script that will prepare a filtered version of the upstream repository
and add it as 'cherry' remote to this repository. This way you can cherry-pick the changes from the upstream repository with (relative) ease.