From 7c7b235c640326cdbe9039aa8a13ef167c28e364 Mon Sep 17 00:00:00 2001 From: xin053 <13207130066.cool@163.com> Date: Wed, 28 Jul 2021 11:28:03 +0800 Subject: [PATCH] use go module and update README --- .vscode/launch.json | 11 +++++- .vscode/settings.json | 5 +-- .vscode/tasks.json | 5 +-- README.md | 81 ++++++++++++++++++++++++++-------------- cmd/{cli.go => hstat.go} | 2 +- demo/demo.go | 39 +++++++++++++++++++ go.mod | 3 ++ 7 files changed, 109 insertions(+), 37 deletions(-) rename cmd/{cli.go => hstat.go} (87%) create mode 100644 demo/demo.go create mode 100644 go.mod diff --git a/.vscode/launch.json b/.vscode/launch.json index d3ca6ab..dc0a67a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,5 +1,5 @@ { - // 使用 IntelliSense 了解相关属性。 + // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", @@ -9,6 +9,13 @@ "type": "go", "request": "launch", "mode": "debug", + "program": "${file}" + }, + { + "name": "go: debug hstat", + "type": "go", + "request": "launch", + "mode": "debug", "remotePath": "", "port": 2345, "host": "127.0.0.1", @@ -21,4 +28,4 @@ "useApiV1": false, } ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 5870f6e..79d5686 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,3 @@ { - "go.inferGopath": true, - "git.ignoreLimitWarning": true -} \ No newline at end of file + "git.ignoreLimitWarning": true, +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d5937ac..22adca3 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -15,7 +15,6 @@ ], "options": { "env": { - "GOPATH": "${workspaceFolder}/../../../../", "GOOS": "windows", "GOARCH": "amd64", // if you want to download somthings that needs to go through the GFW, please uncomment the follow two lines and run shadowsocks. @@ -38,7 +37,6 @@ ], "options": { "env": { - "GOPATH": "${workspaceFolder}/../../../../", "GOOS": "linux", "GOARCH": "amd64", // if you want to download somthings that needs to go through the GFW, please uncomment the follow two lines and run shadowsocks. @@ -61,7 +59,6 @@ ], "options": { "env": { - "GOPATH": "${workspaceFolder}/../../../../", "GOOS": "darwin", "GOARCH": "amd64", // if you want to download somthings that needs to go through the GFW, please uncomment the follow two lines and run shadowsocks. @@ -73,4 +70,4 @@ "problemMatcher": ["$go"] } ] -} \ No newline at end of file +} diff --git a/README.md b/README.md index 20e3a84..d5ade9a 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,78 @@ # hsperfdata -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata?ref=badge_shield) - +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata?ref=badge_shield) + +## What's this? This is a golang parser for the newest V2 java HotSpot virtual machine performance data, support all platform theoretically. -## What's this? +## What's hsperfdata file? It is a log directory created by JVM while running your code. By default it is created inside the tmp folder of the operating system that you are using! This directory is a part of Java Performance counter. And the file in this directory is named by the pid number of java process. +For example, if you are running a java process which pid is `1111`, the hsperfdata file is `%TEMP%/hsperfdata_/1111` on `windows`, `/tmp/hsperfdata_/1111` on `linux`. + You can disable creating this directory by using `-XX:-UsePerfData` or `-XX:+PerfDisableSharedMem` which is not recommended. ## Used as a library -You can just read the `cli.go` file at the root directory to figure out how to use. +**First, you should get the file path string of the hsperfdata file that you want to parser, then use `ReadPerfData` function to parser the hsperfdata file** +There are several functions to get the path, include `PerfDataPath(pid string)`, `PerfDataPaths(pids []string)`, `UserPerfDataPaths(user string)`, `CurrentUserPerfDataPaths()`, `AllPerfDataPaths()`, `DataPathsByProcessName(processName string)`. + +For how to use these functions, look at [`hsperfdata function documentation`](https://pkg.go.dev/github.com/xin053/hsperfdata#section-documentation) or you can just read the [`hsperfdata.go`](./hsperfdata.go) to figure out how to use them, the source code is easy to read through. + +There is a demo using this project as a go library: ```go +package main + import ( - "fmt" - "log" + "fmt" + "log" + "sort" - "github.com/xin053/hsperfdata" + "github.com/xin053/hsperfdata" ) -// first, you should get the file path string of the hsperfdata file that you want to parser. -// there are several function to get the path, include PerfDataPath(pid string), PerfDataPaths(pids []string), UserPerfDataPaths(user string), CurrentUserPerfDataPaths(), AllPerfDataPaths(), DataPathsByProcessName(processName string) -// the source code is easy to read through, you can just read the hsperfdata.go to figure out how to use them. - -entryMap, err := hsperfdata.ReadPerfData(filePath, true) -if err != nil { - log.Fatal("open fail", err) -} - -for _, key := range keys { - fmt.Printf("%s=%v\n", key, entryMap[key]) +func main() { + filePaths, err := hsperfdata.DataPathsByProcessName("java") + if err != nil { + log.Fatal(err) + } + + for pid := range filePaths { + entryMap, err := hsperfdata.ReadPerfData(filePaths[pid], true) + if err != nil { + log.Fatal("open fail", err) + } + + var keys []string + for k := range entryMap { + keys = append(keys, k) + } + + sort.Strings(keys) + + for _, key := range keys { + fmt.Printf("%s=%v\n", key, entryMap[key]) + } + } } ``` ## Used as a command -### build yourself +There is a demo [`hstat.go`](./cmd/hstat.go) + +### build hstat yourself ```shell -export GOPATH=`pwd` -go get -d github.com/xin053/hsperfdata -cd src/github.com/xin053/hsperfdata -go build cli.exe +# go1.12+ +go build .\cmd\hstat.go + +# Usage: hstat pid +# if you have a java process which pid is 1111, then run this +hstat 1111 ``` ### use the release package @@ -106,7 +133,7 @@ The newest java HotSpot virtual machine performance data structures was V2 when 2. https://github.com/tokuhirom/go-hsperfdata 3. https://github.com/njwhite/telegraf/blob/master/plugins/inputs/hsperfdata/hsperfdata.go 4. https://github.com/twitter/commons/blob/master/src/python/twitter/common/java/perfdata/bin/jammystat.py -5. https://github.com/YaSuenag/hsbeat/blob/master/module/hotspot/hsperfdata/parser.go - -## License -[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata?ref=badge_large) \ No newline at end of file +5. https://github.com/YaSuenag/hsbeat/blob/master/module/hotspot/hsperfdata/parser.go + +## License +[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fxin053%2Fhsperfdata?ref=badge_large) diff --git a/cmd/cli.go b/cmd/hstat.go similarity index 87% rename from cmd/cli.go rename to cmd/hstat.go index b135d04..2c154c0 100644 --- a/cmd/cli.go +++ b/cmd/hstat.go @@ -11,7 +11,7 @@ import ( func main() { if len(os.Args) == 1 { - fmt.Printf("Usage: hsstat pid\n") + fmt.Printf("Usage: hstat pid\n") return } diff --git a/demo/demo.go b/demo/demo.go new file mode 100644 index 0000000..d823f80 --- /dev/null +++ b/demo/demo.go @@ -0,0 +1,39 @@ +// Copyright (c) 2021 xin053 +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +package main + +import ( + "fmt" + "log" + "sort" + + "github.com/xin053/hsperfdata" +) + +func main() { + filePaths, err := hsperfdata.DataPathsByProcessName("java") + if err != nil { + log.Fatal(err) + } + + for pid := range filePaths { + entryMap, err := hsperfdata.ReadPerfData(filePaths[pid], true) + if err != nil { + log.Fatal("open fail", err) + } + + var keys []string + for k := range entryMap { + keys = append(keys, k) + } + + sort.Strings(keys) + + for _, key := range keys { + fmt.Printf("%s=%v\n", key, entryMap[key]) + } + } +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0009100 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/xin053/hsperfdata + +go 1.16