Java Performance Agent is a lightweight, pluggable Java agent designed to monitor, trace, and analyze the performance of Java applications in real time. It provides actionable insights into method execution times, call stacks, and resource usage, helping to identify bottlenecks and optimize application performance.
Enables real-time performance monitoring and tracing for Java applications, helping to identify bottlenecks and optimize code execution.
- AgentEntrypoint & AgentInitializer: Bootstrap and configure the agent at JVM startup.
- AgentStarter & AgentStarterImpl: Manage the lifecycle and instrumentation logic.
- PerformanceTracer & TimerContext: Collect and aggregate timing data for instrumented methods.
- Instrumentation via ByteBuddy: Uses ByteBuddy to dynamically instrument classes and methods at runtime, enabling precise and flexible performance tracing without modifying application code.
- ManagementHttpServer: Embedded HTTP server exposing REST APIs and a web interface for trace management and visualization.
- Handlers (GetTrace, GetTraces, DeleteTrace, StopTrace, etc.): REST endpoints for trace operations (start, stop, list, download, delete).
- StaticResourceHandler: Serves the web UI (HTML, CSS, JS) for interactive trace exploration.
- File Writers & Utilities: Serialize, compress, and store trace data efficiently.
- Java 17+ (compatible with modern JVMs)
- Works with Tomcat, WildFly, and other servlet containers
- No code changes required in the target application
This project uses ByteBuddy for runtime instrumentation of Java classes and methods.
- ByteBuddy is licensed under the Apache License, Version 2.0. License
- By using ByteBuddy, this project complies with the terms of the Apache License 2.0, including attribution and license notice.
This project uses official Docker images for:
- Apache Tomcat (Apache License 2.0) License
- Wildfly (LGPL v2.1) License
By using these images, you accept the terms of their respective licenses.
- Attach to JVM: Add the agent JAR to your JVM startup parameters:
-javaagent:/path/to/performance-agent.jar -Dcmdev.profiler.filters.path=/path/to/filters.properties
- Configure Filters: Use
filters.propertiesto specify which classes/methods to instrument. - Access Web UI: Open the embedded HTTP server (default port 8090) to interact with traces and view results.
- API Endpoints: The REST endpoints are primarily called by the web UI for trace management and visualization, but are also available for automation and integration with CI/CD or monitoring tools.
- Startup: The agent is attached to the JVM (via
-javaagent), initializing its configuration and HTTP server. - Instrumentation: Classes and methods are instrumented based on filters and configuration, enabling precise timing and call tracking.
- Trace Collection: When a trace is started (via API or UI), the agent records method execution data and call stacks.
- Trace Management: Traces can be listed, downloaded, deleted, or stopped via REST API or the web interface.
- Analysis: Collected traces are available for download and analysis, helping to pinpoint performance issues.
GET /traces– List available tracesPOST /trace/start– Start a new tracePOST /trace/stop– Stop the current traceGET /trace/{id}– Download a trace fileDELETE /trace/{id}– Delete a trace
- Build the agent and your target application.
- Start your application with the agent attached.
- Access the web UI or use the REST API to manage and analyze traces.
To run and test the Performance Agent with Tomcat or Wildfly, follow these steps:
export MSYS_NO_PATHCONV=1
JAVA_TOOL_OPTIONS="-XX:-UseContainerSupport -javaagent:/usr/local/tomcat/performance-agent.jar -Dcmdev.profiler.filters.path=/usr/local/tomcat/filters.properties"
mvn -q clean install
rootDir=$PWD
pushd test-app
mvn -q clean install
docker build -t test-app-tomcat -f Dockerfile-Tomcat10jdk17 .
docker run -p 8080:8080 -p 8090:8090 -p 8787:8787 \
-e JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS}" \
-v $rootDir/test-app/filters.properties:/usr/local/tomcat/filters.properties \
-v $rootDir/target/performance-agent.jar:/usr/local/tomcat/performance-agent.jar \
-v $rootDir/test-app/traces:/tmp/traces \
test-app-tomcat
popdexport MSYS_NO_PATHCONV=1
JAVA_TOOL_OPTIONS=" -agentlib:jdwp=transport=dt_socket,server=y,address=*:8787,suspend=n -javaagent:/opt/jboss/wildfly/performance-agent.jar -Dcmdev.profiler.filters.path=/opt/jboss/wildfly/filters.properties"
mvn -q clean install
rootDir=$PWD
pushd test-app
mvn -q clean install
docker build -t test-app-wildfly -f Dockerfile-Wildfly28jdk17 .
docker run -p 8080:8080 -p 8090:8090 -p 8787:8787 \
-e JAVA_OPTS="${JAVA_TOOL_OPTIONS}" \
-v $rootDir/test-app/filters.properties:/opt/jboss/wildfly/filters.properties \
-v $rootDir/target/performance-agent.jar:/opt/jboss/wildfly/performance-agent.jar \
-v $rootDir/test-app/traces:/tmp/traces \
test-app-wildfly
popdexport MSYS_NO_PATHCONV=1
JAVA_TOOL_OPTIONS="-XX:-UseContainerSupport -javaagent:/usr/src/app/performance-agent.jar -Dcmdev.profiler.filters.path=/usr/src/app/filters.properties"
mvn -q clean install
rootDir=$PWD
pushd test-app
mvn -q clean install
docker build -t test-app-jdk -f Dockerfile-jdk17 .
docker run -p 8090:8090 -p 8787:8787 \
-e JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS}" \
-v $rootDir/test-app/filters.properties:/usr/src/app/filters.properties \
-v $rootDir/target/performance-agent.jar:/usr/src/app/performance-agent.jar \
-v $rootDir/test-app/traces:/tmp/traces \
test-app-jdk
popdOpen source project – contributions and feedback are welcome!