|
|
@@ -1,13 +1,97 @@
|
|
|
package ebpftracer
|
|
|
|
|
|
import (
|
|
|
+ "bytes"
|
|
|
"fmt"
|
|
|
"os"
|
|
|
"os/exec"
|
|
|
- "bytes"
|
|
|
+ "regexp"
|
|
|
+ "strconv"
|
|
|
"strings"
|
|
|
+ "unicode"
|
|
|
)
|
|
|
|
|
|
+func GetJvmVersion(filePath string) (string, error) {
|
|
|
+ minLength := 4
|
|
|
+ var maxFileSize int64 = 3 * 1024 * 1024 // 3MB
|
|
|
+ // 打开文件
|
|
|
+ sofile, err := os.Open(filePath)
|
|
|
+ if err != nil {
|
|
|
+ return "", fmt.Errorf("failed to open file: %w", err)
|
|
|
+ }
|
|
|
+ defer sofile.Close()
|
|
|
+
|
|
|
+ // 检查文件大小
|
|
|
+ fileInfo, err := sofile.Stat()
|
|
|
+ if err != nil {
|
|
|
+ return "", fmt.Errorf("failed to stat file: %w", err)
|
|
|
+ }
|
|
|
+ if fileInfo.Size() > maxFileSize {
|
|
|
+ return "", fmt.Errorf("file size exceeds limit of %d bytes", maxFileSize)
|
|
|
+ }
|
|
|
+
|
|
|
+ var result []string
|
|
|
+ var buffer []rune
|
|
|
+
|
|
|
+ // 逐字节读取文件
|
|
|
+ buf := make([]byte, 4096) // 4KB 缓冲区
|
|
|
+ for {
|
|
|
+ n, err := sofile.Read(buf)
|
|
|
+ if n > 0 {
|
|
|
+ for _, b := range buf[:n] {
|
|
|
+ // 检查是否是可打印字符
|
|
|
+ if unicode.IsPrint(rune(b)) {
|
|
|
+ buffer = append(buffer, rune(b))
|
|
|
+ } else if len(buffer) >= minLength {
|
|
|
+ // 如果当前缓冲区长度满足要求,则存入结果
|
|
|
+ result = append(result, string(buffer))
|
|
|
+ buffer = nil
|
|
|
+ } else {
|
|
|
+ // 清空缓冲区
|
|
|
+ buffer = nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ if err.Error() != "EOF" {
|
|
|
+ return "", fmt.Errorf("failed to read file: %w", err)
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果缓冲区有剩余字符串,添加到结果中
|
|
|
+ if len(buffer) >= minLength {
|
|
|
+ result = append(result, string(buffer))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查找 `java.version` 的下一行
|
|
|
+ keyword := "java.version"
|
|
|
+
|
|
|
+ for i, str := range result {
|
|
|
+ if str == keyword && i+1 < len(result) {
|
|
|
+ return result[i+1], nil // 返回关键字下一行内容
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return "", fmt.Errorf("failed to extract java version from %s", filePath)
|
|
|
+}
|
|
|
+
|
|
|
+// 解析版本号为大版本、中间版本和小版本
|
|
|
+func ParseVersion(version string) (int, int, int, error) {
|
|
|
+ re := regexp.MustCompile(`^(\d+)\.(\d+)\.(\d+)`)
|
|
|
+ matches := re.FindStringSubmatch(version)
|
|
|
+ if len(matches) != 4 {
|
|
|
+ return 0, 0, 0, fmt.Errorf("invalid version format")
|
|
|
+ }
|
|
|
+
|
|
|
+ major, _ := strconv.Atoi(matches[1])
|
|
|
+ minor, _ := strconv.Atoi(matches[2])
|
|
|
+ patch, _ := strconv.Atoi(matches[3])
|
|
|
+
|
|
|
+ return major, minor, patch, nil
|
|
|
+}
|
|
|
+
|
|
|
func parseQuotedString(input string) (string, error) {
|
|
|
// 找到第一个双引号的位置
|
|
|
start := strings.Index(input, "\"")
|
|
|
@@ -39,7 +123,7 @@ func getExecutablePath(pid uint32) (string, error) {
|
|
|
return execPath, nil
|
|
|
}
|
|
|
|
|
|
-func UsePIDToGetJDKVersion(pid uint32) string{
|
|
|
+func UsePIDToGetJDKVersion(pid uint32) string {
|
|
|
execPath, err := getExecutablePath(pid)
|
|
|
if err != nil {
|
|
|
fmt.Println("Error:", err)
|
|
|
@@ -69,5 +153,5 @@ func UsePIDToGetJDKVersion(pid uint32) string{
|
|
|
return ""
|
|
|
}
|
|
|
return version
|
|
|
-
|
|
|
+
|
|
|
}
|