Skip to content

Commit 7921844

Browse files
author
Yuriy Bezsonov
committed
WIP
1 parent 781c18e commit 7921844

19 files changed

+882
-128
lines changed

apps/ai-jvm-analyzer/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
target/
2+
*.class
3+
*.jar
4+
*.log
5+
.idea/
6+
*.iml
7+
.DS_Store
8+
.jqwik-database

apps/ai-jvm-analyzer/pom.xml

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>4.0.1</version>
9+
<relativePath/>
10+
</parent>
11+
<groupId>com.example.ai</groupId>
12+
<artifactId>ai-jvm-analyzer</artifactId>
13+
<version>1.0.0</version>
14+
<name>ai-jvm-analyzer</name>
15+
<description>AI-powered JVM performance analyzer using Amazon Bedrock</description>
16+
17+
<properties>
18+
<java.version>25</java.version>
19+
<maven.compiler.release>25</maven.compiler.release>
20+
<maven.compiler.source>25</maven.compiler.source>
21+
<maven.compiler.target>25</maven.compiler.target>
22+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24+
<spring-ai.version>1.1.1</spring-ai.version>
25+
<testcontainers.version>2.0.3</testcontainers.version>
26+
</properties>
27+
28+
<dependencyManagement>
29+
<dependencies>
30+
<dependency>
31+
<groupId>software.amazon.awssdk</groupId>
32+
<artifactId>bom</artifactId>
33+
<version>2.40.15</version>
34+
<type>pom</type>
35+
<scope>import</scope>
36+
</dependency>
37+
<dependency>
38+
<groupId>org.springframework.ai</groupId>
39+
<artifactId>spring-ai-bom</artifactId>
40+
<version>${spring-ai.version}</version>
41+
<type>pom</type>
42+
<scope>import</scope>
43+
</dependency>
44+
<dependency>
45+
<groupId>org.apache.commons</groupId>
46+
<artifactId>commons-compress</artifactId>
47+
<version>1.27.1</version>
48+
<scope>runtime</scope>
49+
</dependency>
50+
</dependencies>
51+
</dependencyManagement>
52+
53+
<dependencies>
54+
<dependency>
55+
<groupId>org.springframework.boot</groupId>
56+
<artifactId>spring-boot-starter-web</artifactId>
57+
<exclusions>
58+
<exclusion>
59+
<groupId>commons-logging</groupId>
60+
<artifactId>commons-logging</artifactId>
61+
</exclusion>
62+
</exclusions>
63+
</dependency>
64+
<dependency>
65+
<groupId>org.springframework.boot</groupId>
66+
<artifactId>spring-boot-starter-actuator</artifactId>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.springframework.ai</groupId>
70+
<artifactId>spring-ai-starter-model-bedrock</artifactId>
71+
</dependency>
72+
<dependency>
73+
<groupId>software.amazon.awssdk</groupId>
74+
<artifactId>s3</artifactId>
75+
<exclusions>
76+
<exclusion>
77+
<groupId>commons-logging</groupId>
78+
<artifactId>commons-logging</artifactId>
79+
</exclusion>
80+
</exclusions>
81+
</dependency>
82+
<dependency>
83+
<groupId>io.micrometer</groupId>
84+
<artifactId>micrometer-registry-prometheus</artifactId>
85+
</dependency>
86+
<dependency>
87+
<groupId>com.fasterxml.jackson.core</groupId>
88+
<artifactId>jackson-databind</artifactId>
89+
</dependency>
90+
<dependency>
91+
<groupId>org.springframework.boot</groupId>
92+
<artifactId>spring-boot-starter-test</artifactId>
93+
<scope>test</scope>
94+
</dependency>
95+
<dependency>
96+
<groupId>org.springframework.boot</groupId>
97+
<artifactId>spring-boot-testcontainers</artifactId>
98+
<scope>test</scope>
99+
</dependency>
100+
<dependency>
101+
<groupId>net.jqwik</groupId>
102+
<artifactId>jqwik</artifactId>
103+
<version>1.9.3</version>
104+
<scope>test</scope>
105+
</dependency>
106+
<dependency>
107+
<groupId>org.testcontainers</groupId>
108+
<artifactId>testcontainers-junit-jupiter</artifactId>
109+
<version>${testcontainers.version}</version>
110+
<scope>test</scope>
111+
</dependency>
112+
<dependency>
113+
<groupId>org.testcontainers</groupId>
114+
<artifactId>testcontainers-localstack</artifactId>
115+
<version>${testcontainers.version}</version>
116+
<scope>test</scope>
117+
</dependency>
118+
</dependencies>
119+
120+
<build>
121+
<plugins>
122+
<plugin>
123+
<groupId>org.apache.maven.plugins</groupId>
124+
<artifactId>maven-compiler-plugin</artifactId>
125+
</plugin>
126+
<plugin>
127+
<groupId>org.apache.maven.plugins</groupId>
128+
<artifactId>maven-surefire-plugin</artifactId>
129+
<version>3.5.4</version>
130+
</plugin>
131+
</plugins>
132+
</build>
133+
134+
<profiles>
135+
<profile>
136+
<id>native</id>
137+
<build>
138+
<plugins>
139+
<plugin>
140+
<groupId>org.graalvm.buildtools</groupId>
141+
<artifactId>native-maven-plugin</artifactId>
142+
<version>0.11.3</version>
143+
<extensions>true</extensions>
144+
<configuration>
145+
<metadataRepository>
146+
<enabled>true</enabled>
147+
</metadataRepository>
148+
<requiredVersion>25</requiredVersion>
149+
<buildArgs>
150+
<arg>--verbose</arg>
151+
</buildArgs>
152+
</configuration>
153+
<executions>
154+
<execution>
155+
<id>build-native</id>
156+
<goals>
157+
<goal>compile-no-fork</goal>
158+
</goals>
159+
<phase>package</phase>
160+
</execution>
161+
<execution>
162+
<id>test-native</id>
163+
<goals>
164+
<goal>test</goal>
165+
</goals>
166+
<phase>test</phase>
167+
</execution>
168+
</executions>
169+
</plugin>
170+
<plugin>
171+
<groupId>org.springframework.boot</groupId>
172+
<artifactId>spring-boot-maven-plugin</artifactId>
173+
<configuration>
174+
<classifier>exec</classifier>
175+
</configuration>
176+
</plugin>
177+
</plugins>
178+
</build>
179+
</profile>
180+
<profile>
181+
<id>jvm</id>
182+
<activation>
183+
<activeByDefault>true</activeByDefault>
184+
</activation>
185+
<build>
186+
<plugins>
187+
<plugin>
188+
<groupId>com.google.cloud.tools</groupId>
189+
<artifactId>jib-maven-plugin</artifactId>
190+
<version>3.5.1</version>
191+
<configuration>
192+
<from>
193+
<image>public.ecr.aws/docker/library/amazoncorretto:25-al2023</image>
194+
</from>
195+
<container>
196+
<user>1000</user>
197+
</container>
198+
</configuration>
199+
</plugin>
200+
<plugin>
201+
<groupId>org.springframework.boot</groupId>
202+
<artifactId>spring-boot-maven-plugin</artifactId>
203+
<executions>
204+
<execution>
205+
<id>repackage</id>
206+
<configuration>
207+
<classifier>exec</classifier>
208+
<mainClass>com.example.ai.jvmanalyzer.Application</mainClass>
209+
<layout>JAR</layout>
210+
</configuration>
211+
</execution>
212+
</executions>
213+
</plugin>
214+
</plugins>
215+
</build>
216+
</profile>
217+
</profiles>
218+
</project>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package com.example.ai.jvmanalyzer;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.ai.chat.client.ChatClient;
6+
import org.springframework.stereotype.Service;
7+
8+
import java.time.LocalDateTime;
9+
import java.time.format.DateTimeFormatter;
10+
11+
@Service
12+
public class AiService {
13+
14+
private static final Logger logger = LoggerFactory.getLogger(AiService.class);
15+
16+
private final ChatClient chatClient;
17+
18+
private static final String SYSTEM_PROMPT = """
19+
You are an expert in Java performance analysis with extensive experience \
20+
diagnosing production issues. Analyze thread dumps and profiling data to \
21+
identify performance bottlenecks and provide actionable recommendations. \
22+
Be thorough, specific, and focus on practical solutions.""";
23+
24+
public AiService(ChatClient.Builder chatClientBuilder) {
25+
if (chatClientBuilder != null) {
26+
this.chatClient = chatClientBuilder
27+
.defaultSystem(SYSTEM_PROMPT)
28+
.build();
29+
} else {
30+
this.chatClient = null;
31+
}
32+
}
33+
34+
public String analyze(String threadDump, String profilingData) {
35+
var prompt = buildPrompt(threadDump, profilingData);
36+
37+
try {
38+
logger.info("Sending analysis request to Bedrock...");
39+
var response = chatClient.prompt()
40+
.user(prompt)
41+
.call()
42+
.content();
43+
logger.info("Received analysis response from Bedrock");
44+
return response;
45+
} catch (Exception e) {
46+
logger.warn("AI analysis failed: {}", e.getMessage());
47+
return buildFallbackReport(e, threadDump, profilingData);
48+
}
49+
}
50+
51+
String buildPrompt(String threadDump, String profilingData) {
52+
return """
53+
Analyze this Java performance data and provide a focused report:
54+
55+
## Health Status
56+
Rate: Healthy/Degraded/Critical with brief explanation
57+
58+
## Thread Analysis
59+
- Total threads and state distribution (RUNNABLE, WAITING, BLOCKED)
60+
- Key patterns: what threads are doing and why
61+
- Bottlenecks: specific thread contention or blocking issues
62+
63+
## Top Issues (max 3)
64+
For each critical issue found:
65+
- **Problem**: Specific technical issue with affected components
66+
- **Root Cause**: Why this is happening (code/config/resource issue)
67+
- **Impact**: Quantified performance/stability effect
68+
- **Fix**: Concrete action with implementation details
69+
70+
## Performance Hotspots
71+
From flamegraph analysis:
72+
- Top 3 CPU consumers with method names
73+
- Memory allocation patterns
74+
- I/O bottlenecks (database, network, file operations)
75+
- Lock contention areas
76+
77+
## Recommendations
78+
**Immediate (< 1 day)**:
79+
- 3 quick configuration or code changes
80+
81+
**Short-term (< 1 week)**:
82+
- 3 architectural improvements with expected impact
83+
84+
**Thread Dump:**
85+
%s
86+
87+
**Flamegraph Data:**
88+
%s
89+
90+
Provide specific method names, class names, and quantified metrics where possible.
91+
Keep response under 5KB but include enough detail for actionable insights.
92+
""".formatted(threadDump, profilingData);
93+
}
94+
95+
String buildFallbackReport(Exception e, String threadDump, String profilingData) {
96+
return """
97+
# Thread Dump Analysis Report
98+
99+
**Generated:** %s
100+
101+
**Error:** AI analysis failed - %s
102+
103+
## Inputs Summary
104+
- Thread dump size: %d characters
105+
- Profiling data size: %d characters
106+
107+
## Manual Review Required
108+
The AI analysis could not be completed. Please review the thread dump \
109+
and profiling data manually or retry the analysis.
110+
111+
## Thread Dump Preview
112+
```
113+
%s
114+
```
115+
""".formatted(
116+
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),
117+
e.getMessage(),
118+
threadDump != null ? threadDump.length() : 0,
119+
profilingData != null ? profilingData.length() : 0,
120+
threadDump != null ? threadDump.substring(0, Math.min(500, threadDump.length())) : "N/A"
121+
);
122+
}
123+
}

0 commit comments

Comments
 (0)