perfmonger 0.12.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/NEWS +25 -1
- data/Rakefile +18 -7
- data/core/Makefile +20 -21
- data/core/build.sh +4 -6
- data/core/{perfmonger-player.go → cmd/perfmonger-player/perfmonger-player.go} +34 -10
- data/core/cmd/perfmonger-plot-formatter/README.md +24 -0
- data/core/{perfmonger-plot-formatter.go → cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go} +116 -3
- data/core/{perfmonger-recorder.go → cmd/perfmonger-recorder/perfmonger-recorder.go} +0 -0
- data/core/{perfmonger-summarizer.go → cmd/perfmonger-summarizer/perfmonger-summarizer.go} +3 -1
- data/core/{perfmonger-viewer.go → cmd/perfmonger-viewer/perfmonger-viewer.go} +0 -0
- data/core/go.mod +10 -0
- data/core/go.sum +17 -0
- data/core/subsystem/perfmonger_linux.go +2 -0
- data/core/subsystem/stat.go +2 -0
- data/core/utils.go +2 -2
- data/lib/exec/perfmonger-player_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-player_linux_amd64 +0 -0
- data/lib/exec/perfmonger-plot-formatter_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-plot-formatter_linux_amd64 +0 -0
- data/lib/exec/perfmonger-recorder_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-recorder_linux_amd64 +0 -0
- data/lib/exec/perfmonger-summarizer_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-summarizer_linux_amd64 +0 -0
- data/lib/exec/perfmonger-viewer_darwin_amd64 +0 -0
- data/lib/exec/perfmonger-viewer_linux_amd64 +0 -0
- data/lib/perfmonger/command/play.rb +10 -0
- data/lib/perfmonger/command/plot.rb +144 -2
- data/lib/perfmonger/command/record.rb +23 -2
- data/lib/perfmonger/version.rb +1 -1
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42856e6da789b3ad1a522b95bc642bdf7abe1e2fb7679e4839b7da7e3157b6a9
|
4
|
+
data.tar.gz: 937b2f2557ad06fe36e230c623ab07773d17bc1dd278e80b87bb8fb881a9427c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f06a76145f4f4aafd9f4fa8e2de7ef855190729d25b98a6ab36a8bcbcb1ee41242736e96b3c15693ffeb341ee229f3852f00f36b27785b84124e587fdcfad41
|
7
|
+
data.tar.gz: 86b957bb0edbf89f0cb7904b0059d75db11366eb26ca1b1112cd4c7566aa896240dc430d4d56a177c00c4862ebbf677f73f3447bda9e798226d7fcbf60836408
|
data/NEWS
CHANGED
@@ -1,4 +1,28 @@
|
|
1
|
-
##
|
1
|
+
## 2021-XX-XX: PerfMonger 0.15.0
|
2
|
+
|
3
|
+
## 2021-12-01: PerfMonger 0.14.1
|
4
|
+
* Changes
|
5
|
+
* [plot] subcommand:
|
6
|
+
* Skip plotting memory usage if it is not recorded
|
7
|
+
|
8
|
+
## 2021-07-27: PerfMonger 0.14.0
|
9
|
+
* New features
|
10
|
+
* [plot] subcommand:
|
11
|
+
* Added memory usage plot
|
12
|
+
* Changes
|
13
|
+
* [record] subcommand:
|
14
|
+
* Additionaly record 'Hugepagesize' in memory usage
|
15
|
+
|
16
|
+
## 2021-07-26: PerfMonger 0.13.1
|
17
|
+
* New features
|
18
|
+
* [play] subcommand:
|
19
|
+
* Added --disk-only option to filter results of not interesting disks
|
20
|
+
* Note: v0.13.0 is yanked from rubygems.org
|
21
|
+
|
22
|
+
## 2021-07-08: PerfMonger 0.12.1
|
23
|
+
* Bug fixes
|
24
|
+
* [record] subcommand:
|
25
|
+
* --kill waits until a recorder process surely exits
|
2
26
|
|
3
27
|
## 2021-05-10: PerfMonger 0.12.0
|
4
28
|
* New features
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
|
5
|
-
task :default => [:spec, :test_core]
|
5
|
+
task :default => [:spec, :test_core, :analyze_core]
|
6
6
|
|
7
7
|
desc "Run all specs in spec directory"
|
8
8
|
RSpec::Core::RakeTask.new(:spec)
|
@@ -30,19 +30,30 @@ task :go_get do
|
|
30
30
|
sh "go get -u github.com/jroimartin/gocui"
|
31
31
|
end
|
32
32
|
|
33
|
-
desc "Run tests of core
|
33
|
+
desc "Run tests of golang core library"
|
34
34
|
task :test_core => [:cross_build_core] do
|
35
35
|
Dir.chdir("./core/subsystem") do
|
36
|
+
# check coverage
|
36
37
|
sh "go test -v -cover"
|
37
|
-
|
38
|
-
# running static analysis
|
39
|
-
sh "go vet *.go"
|
40
38
|
end
|
39
|
+
end
|
41
40
|
|
42
|
-
|
43
|
-
|
41
|
+
desc "Run static-analysis of golang core library"
|
42
|
+
task :analyze_core => [:cross_build_core] do
|
43
|
+
# running static analysis
|
44
|
+
Dir.chdir("./core/subsystem") do
|
45
|
+
["linux", "darwin"].each do |platform|
|
46
|
+
puts "* ./core/subsystem"
|
47
|
+
sh "go vet perfmonger_#{platform}.go $(ls *.go | grep -v perfmonger_)"
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
51
|
+
Dir["./core", "./core/cmd/*"].each do |dir|
|
52
|
+
Dir.chdir(dir) do
|
53
|
+
puts "* #{dir}"
|
54
|
+
sh "go vet *.go"
|
55
|
+
end
|
56
|
+
end
|
46
57
|
end
|
47
58
|
|
48
59
|
desc "Removed generated files"
|
data/core/Makefile
CHANGED
@@ -2,51 +2,50 @@
|
|
2
2
|
# generated by build.sh
|
3
3
|
|
4
4
|
GO_DEPS := subsystem/perfmonger_darwin.go subsystem/perfmonger.go subsystem/perfmonger_linux.go subsystem/perfmonger_linux_test.go subsystem/stat.go subsystem/stat_test.go subsystem/usage.go subsystem/usage_test.go utils.go
|
5
|
-
GO_SRC := utils.go
|
6
5
|
|
7
6
|
.PHONY: all build clean
|
8
7
|
|
9
8
|
all: build
|
10
9
|
|
11
10
|
|
12
|
-
../lib/exec/perfmonger-recorder_linux_amd64: perfmonger-recorder.go $(GO_DEPS)
|
13
|
-
go build -o
|
11
|
+
../lib/exec/perfmonger-recorder_linux_amd64: cmd/perfmonger-recorder/perfmonger-recorder.go $(GO_DEPS)
|
12
|
+
cd cmd/perfmonger-recorder && go build -o ../../$@ perfmonger-recorder.go
|
14
13
|
|
15
14
|
|
16
|
-
../lib/exec/perfmonger-player_linux_amd64: perfmonger-player.go $(GO_DEPS)
|
17
|
-
go build -o
|
15
|
+
../lib/exec/perfmonger-player_linux_amd64: cmd/perfmonger-player/perfmonger-player.go $(GO_DEPS)
|
16
|
+
cd cmd/perfmonger-player && go build -o ../../$@ perfmonger-player.go
|
18
17
|
|
19
18
|
|
20
|
-
../lib/exec/perfmonger-viewer_linux_amd64: perfmonger-viewer.go $(GO_DEPS)
|
21
|
-
go build -o
|
19
|
+
../lib/exec/perfmonger-viewer_linux_amd64: cmd/perfmonger-viewer/perfmonger-viewer.go $(GO_DEPS)
|
20
|
+
cd cmd/perfmonger-viewer && go build -o ../../$@ perfmonger-viewer.go
|
22
21
|
|
23
22
|
|
24
|
-
../lib/exec/perfmonger-summarizer_linux_amd64: perfmonger-summarizer.go $(GO_DEPS)
|
25
|
-
go build -o
|
23
|
+
../lib/exec/perfmonger-summarizer_linux_amd64: cmd/perfmonger-summarizer/perfmonger-summarizer.go $(GO_DEPS)
|
24
|
+
cd cmd/perfmonger-summarizer && go build -o ../../$@ perfmonger-summarizer.go
|
26
25
|
|
27
26
|
|
28
|
-
../lib/exec/perfmonger-plot-formatter_linux_amd64: perfmonger-plot-formatter.go $(GO_DEPS)
|
29
|
-
go build -o
|
27
|
+
../lib/exec/perfmonger-plot-formatter_linux_amd64: cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go $(GO_DEPS)
|
28
|
+
cd cmd/perfmonger-plot-formatter && go build -o ../../$@ perfmonger-plot-formatter.go
|
30
29
|
|
31
30
|
|
32
|
-
../lib/exec/perfmonger-recorder_darwin_amd64: perfmonger-recorder.go $(GO_DEPS)
|
33
|
-
go build -o
|
31
|
+
../lib/exec/perfmonger-recorder_darwin_amd64: cmd/perfmonger-recorder/perfmonger-recorder.go $(GO_DEPS)
|
32
|
+
cd cmd/perfmonger-recorder && go build -o ../../$@ perfmonger-recorder.go
|
34
33
|
|
35
34
|
|
36
|
-
../lib/exec/perfmonger-player_darwin_amd64: perfmonger-player.go $(GO_DEPS)
|
37
|
-
go build -o
|
35
|
+
../lib/exec/perfmonger-player_darwin_amd64: cmd/perfmonger-player/perfmonger-player.go $(GO_DEPS)
|
36
|
+
cd cmd/perfmonger-player && go build -o ../../$@ perfmonger-player.go
|
38
37
|
|
39
38
|
|
40
|
-
../lib/exec/perfmonger-viewer_darwin_amd64: perfmonger-viewer.go $(GO_DEPS)
|
41
|
-
go build -o
|
39
|
+
../lib/exec/perfmonger-viewer_darwin_amd64: cmd/perfmonger-viewer/perfmonger-viewer.go $(GO_DEPS)
|
40
|
+
cd cmd/perfmonger-viewer && go build -o ../../$@ perfmonger-viewer.go
|
42
41
|
|
43
42
|
|
44
|
-
../lib/exec/perfmonger-summarizer_darwin_amd64: perfmonger-summarizer.go $(GO_DEPS)
|
45
|
-
go build -o
|
43
|
+
../lib/exec/perfmonger-summarizer_darwin_amd64: cmd/perfmonger-summarizer/perfmonger-summarizer.go $(GO_DEPS)
|
44
|
+
cd cmd/perfmonger-summarizer && go build -o ../../$@ perfmonger-summarizer.go
|
46
45
|
|
47
46
|
|
48
|
-
../lib/exec/perfmonger-plot-formatter_darwin_amd64: perfmonger-plot-formatter.go $(GO_DEPS)
|
49
|
-
go build -o
|
47
|
+
../lib/exec/perfmonger-plot-formatter_darwin_amd64: cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go $(GO_DEPS)
|
48
|
+
cd cmd/perfmonger-plot-formatter && go build -o ../../$@ perfmonger-plot-formatter.go
|
50
49
|
|
51
50
|
|
52
51
|
build: ../lib/exec/perfmonger-recorder_linux_amd64 ../lib/exec/perfmonger-player_linux_amd64 ../lib/exec/perfmonger-viewer_linux_amd64 ../lib/exec/perfmonger-summarizer_linux_amd64 ../lib/exec/perfmonger-plot-formatter_linux_amd64 ../lib/exec/perfmonger-recorder_darwin_amd64 ../lib/exec/perfmonger-player_darwin_amd64 ../lib/exec/perfmonger-viewer_darwin_amd64 ../lib/exec/perfmonger-summarizer_darwin_amd64 ../lib/exec/perfmonger-plot-formatter_darwin_amd64
|
data/core/build.sh
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
-
|
4
|
-
cd $(dirname $($READLINK -f $0))
|
3
|
+
cd $(cd $(dirname $0); pwd)
|
5
4
|
|
6
5
|
if [[ $1 = "-" ]]; then
|
7
6
|
# do self build
|
@@ -33,7 +32,7 @@ fi
|
|
33
32
|
|
34
33
|
set -e
|
35
34
|
|
36
|
-
GO_DEPS=$(ls subsystem/*.go
|
35
|
+
GO_DEPS=$(ls subsystem/*.go utils.go)
|
37
36
|
|
38
37
|
makefile=`mktemp`
|
39
38
|
|
@@ -42,7 +41,6 @@ cat <<EOF > $makefile
|
|
42
41
|
# generated by build.sh
|
43
42
|
|
44
43
|
GO_DEPS := $(echo ${GO_DEPS})
|
45
|
-
GO_SRC := utils.go
|
46
44
|
|
47
45
|
.PHONY: all build clean
|
48
46
|
|
@@ -62,8 +60,8 @@ for idx in $(seq 0 $((${#TARGET[@]}-1))); do
|
|
62
60
|
|
63
61
|
cat <<EOF >> $makefile
|
64
62
|
|
65
|
-
../lib/exec/perfmonger-${subcmd}_${var_GOOS}_${var_GOARCH}: perfmonger-${subcmd}.go \$(GO_DEPS)
|
66
|
-
go build -o
|
63
|
+
../lib/exec/perfmonger-${subcmd}_${var_GOOS}_${var_GOARCH}: cmd/perfmonger-${subcmd}/perfmonger-${subcmd}.go \$(GO_DEPS)
|
64
|
+
cd cmd/perfmonger-${subcmd} && go build -o ../../\$@ perfmonger-$subcmd.go
|
67
65
|
|
68
66
|
EOF
|
69
67
|
done
|
@@ -9,15 +9,19 @@ import (
|
|
9
9
|
"fmt"
|
10
10
|
"io"
|
11
11
|
"os"
|
12
|
+
"regexp"
|
12
13
|
|
13
14
|
projson "github.com/hayamiz/go-projson"
|
15
|
+
core "github.com/hayamiz/perfmonger/core"
|
14
16
|
ss "github.com/hayamiz/perfmonger/core/subsystem"
|
15
17
|
)
|
16
18
|
|
17
19
|
type PlayerOption struct {
|
18
|
-
logfile
|
19
|
-
color
|
20
|
-
pretty
|
20
|
+
logfile string
|
21
|
+
color bool
|
22
|
+
pretty bool
|
23
|
+
disk_only string
|
24
|
+
disk_only_regex *regexp.Regexp
|
21
25
|
}
|
22
26
|
|
23
27
|
var option PlayerOption
|
@@ -49,10 +53,11 @@ func showInterruptStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cu
|
|
49
53
|
return nil
|
50
54
|
}
|
51
55
|
|
52
|
-
func showDiskStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
|
53
|
-
dusage, err := ss.
|
56
|
+
func showDiskStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord, disk_only_regex *regexp.Regexp) error {
|
57
|
+
dusage, err := ss.GetDiskUsage1(
|
54
58
|
prev_rec.Time, prev_rec.Disk,
|
55
|
-
cur_rec.Time, cur_rec.Disk
|
59
|
+
cur_rec.Time, cur_rec.Disk,
|
60
|
+
option.disk_only_regex)
|
56
61
|
if err != nil {
|
57
62
|
return err
|
58
63
|
}
|
@@ -93,7 +98,9 @@ func showMemStat(printer *projson.JsonPrinter, cur_rec *ss.StatRecord) error {
|
|
93
98
|
return nil
|
94
99
|
}
|
95
100
|
|
96
|
-
func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord
|
101
|
+
func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord,
|
102
|
+
disk_only_regex *regexp.Regexp) error {
|
103
|
+
|
97
104
|
printer.Reset()
|
98
105
|
if option.pretty {
|
99
106
|
printer.SetStyle(projson.SmartStyle)
|
@@ -101,6 +108,7 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
101
108
|
if option.color {
|
102
109
|
printer.SetColor(true)
|
103
110
|
}
|
111
|
+
|
104
112
|
printer.BeginObject()
|
105
113
|
printer.PutKey("time")
|
106
114
|
printer.PutFloatFmt(float64(cur_rec.Time.UnixNano())/1e9, "%.3f")
|
@@ -121,7 +129,7 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
121
129
|
}
|
122
130
|
}
|
123
131
|
if cur_rec.Disk != nil {
|
124
|
-
err := showDiskStat(printer, prev_rec, cur_rec)
|
132
|
+
err := showDiskStat(printer, prev_rec, cur_rec, disk_only_regex)
|
125
133
|
if err != nil {
|
126
134
|
return err
|
127
135
|
}
|
@@ -147,9 +155,25 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
147
155
|
func parseArgs() {
|
148
156
|
flag.BoolVar(&option.color, "color", false, "Use colored JSON output")
|
149
157
|
flag.BoolVar(&option.pretty, "pretty", false, "Use human readable JSON output")
|
158
|
+
flag.StringVar(&option.disk_only, "disk-only", "", "Select disk devices by regex")
|
150
159
|
|
151
160
|
flag.Parse()
|
152
161
|
|
162
|
+
if len(flag.Args()) < 1 {
|
163
|
+
fmt.Fprintln(os.Stderr, "Insufficient argument")
|
164
|
+
os.Exit(1)
|
165
|
+
}
|
166
|
+
|
167
|
+
option.disk_only_regex = nil
|
168
|
+
|
169
|
+
if option.disk_only != "" {
|
170
|
+
var err error
|
171
|
+
option.disk_only_regex, err = regexp.Compile(option.disk_only)
|
172
|
+
if err != nil {
|
173
|
+
panic(err)
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
153
177
|
option.logfile = flag.Arg(0)
|
154
178
|
}
|
155
179
|
|
@@ -169,7 +193,7 @@ func main() {
|
|
169
193
|
in = f
|
170
194
|
defer f.Close()
|
171
195
|
}
|
172
|
-
input_reader :=
|
196
|
+
input_reader := core.NewPerfmongerLogReader(in)
|
173
197
|
dec := gob.NewDecoder(input_reader)
|
174
198
|
|
175
199
|
out = bufio.NewWriter(os.Stdout)
|
@@ -218,7 +242,7 @@ func main() {
|
|
218
242
|
panic(err)
|
219
243
|
}
|
220
244
|
|
221
|
-
err = showStat(printer, prev_rec, cur_rec)
|
245
|
+
err = showStat(printer, prev_rec, cur_rec, option.disk_only_regex)
|
222
246
|
if err != nil {
|
223
247
|
printer.Reset()
|
224
248
|
fmt.Fprintln(os.Stderr, "skip by err")
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# perfmonger-plot-formatter
|
2
|
+
|
3
|
+
`perfmonger-plot-formatter` is a command to generate data files for plotting
|
4
|
+
various metrices recorded by `perfmonger-recorder`.
|
5
|
+
|
6
|
+
## Notes on memory usage records
|
7
|
+
|
8
|
+
### `free(1)` compatible summarization
|
9
|
+
|
10
|
+
- total: `MemStat.MemTotal`
|
11
|
+
- used: `if (memUsed < 0) { MemStat.MemTotal - MemStat.MemFree } else { memUsed }`
|
12
|
+
- memUsed := `MemStat.MemTotal - MemStat.MemFree - mainCached - MemStat.Buffers`
|
13
|
+
- mainCached := `MemStat.Cached + MemStat.SReclaimable`
|
14
|
+
- free: `MemStat.MemFree`
|
15
|
+
- shared: `MemStat.Shmem`
|
16
|
+
- buffers: `MemStat.Buffers`
|
17
|
+
- cache: `mainCached`
|
18
|
+
- mainCached := `MemStat.Cached + MemStat.SReclaimable`
|
19
|
+
- available: `MemStat.MemAvailable`
|
20
|
+
|
21
|
+
### Additional info
|
22
|
+
|
23
|
+
- hugeTotal: `MemStat.HugePages_Total`
|
24
|
+
- hugeUsed: `MemStat.HugePages_Total - MemStat.HugePages_Free`
|
@@ -13,13 +13,16 @@ import (
|
|
13
13
|
"os"
|
14
14
|
"regexp"
|
15
15
|
"sort"
|
16
|
+
"strings"
|
16
17
|
|
18
|
+
"github.com/hayamiz/perfmonger/core"
|
17
19
|
ss "github.com/hayamiz/perfmonger/core/subsystem"
|
18
20
|
)
|
19
21
|
|
20
22
|
type CmdOption struct {
|
21
23
|
DiskFile string
|
22
24
|
CpuFile string
|
25
|
+
MemFile string
|
23
26
|
PerfmongerFile string
|
24
27
|
disk_only string
|
25
28
|
disk_only_regex *regexp.Regexp
|
@@ -30,8 +33,9 @@ func parseArgs() *CmdOption {
|
|
30
33
|
|
31
34
|
opt := new(CmdOption)
|
32
35
|
|
33
|
-
flag.StringVar(&opt.DiskFile, "diskfile", "./disk.dat", "Disk
|
34
|
-
flag.StringVar(&opt.CpuFile, "cpufile", "./cpu.dat", "CPU
|
36
|
+
flag.StringVar(&opt.DiskFile, "diskfile", "./disk.dat", "Disk usage data file for gnuplot")
|
37
|
+
flag.StringVar(&opt.CpuFile, "cpufile", "./cpu.dat", "CPU usage data file for gnuplot")
|
38
|
+
flag.StringVar(&opt.MemFile, "memfile", "./mem.dat", "Memory usage data file for gnuplot")
|
35
39
|
flag.StringVar(&opt.PerfmongerFile, "perfmonger", "", "Perfmonger log file")
|
36
40
|
flag.StringVar(&opt.disk_only, "disk-only",
|
37
41
|
"", "Select disk devices by regex")
|
@@ -79,6 +83,13 @@ type DiskDatTmpFile struct {
|
|
79
83
|
Idx int
|
80
84
|
}
|
81
85
|
|
86
|
+
type MemDatTmpFile struct {
|
87
|
+
Name string
|
88
|
+
Path string
|
89
|
+
File *os.File
|
90
|
+
Writer *bufio.Writer
|
91
|
+
}
|
92
|
+
|
82
93
|
type CpuDatTmpFile struct {
|
83
94
|
CoreId int
|
84
95
|
Path string
|
@@ -117,6 +128,20 @@ func makeCpuDatTmpFile(coreid int) *CpuDatTmpFile {
|
|
117
128
|
return ret
|
118
129
|
}
|
119
130
|
|
131
|
+
func makeMemDatTmpFile() *MemDatTmpFile {
|
132
|
+
ret := new(MemDatTmpFile)
|
133
|
+
|
134
|
+
f, err := ioutil.TempFile("", "perfmonger-mem")
|
135
|
+
if err != nil {
|
136
|
+
panic(err)
|
137
|
+
}
|
138
|
+
ret.File = f
|
139
|
+
ret.Path = f.Name()
|
140
|
+
ret.Writer = bufio.NewWriter(f)
|
141
|
+
|
142
|
+
return ret
|
143
|
+
}
|
144
|
+
|
120
145
|
func printCoreUsage(writer *bufio.Writer, elapsed_time float64, coreusage *ss.CpuCoreUsage) {
|
121
146
|
writer.WriteString(
|
122
147
|
fmt.Sprintf("%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n",
|
@@ -132,6 +157,80 @@ func printCoreUsage(writer *bufio.Writer, elapsed_time float64, coreusage *ss.Cp
|
|
132
157
|
coreusage.Idle))
|
133
158
|
}
|
134
159
|
|
160
|
+
func printMemUsage(writer *bufio.Writer, elapsed_time float64, mem *ss.MemStat) {
|
161
|
+
if mem == nil {
|
162
|
+
writer.WriteString("#")
|
163
|
+
writer.WriteString(
|
164
|
+
strings.Join([]string{
|
165
|
+
"elapsed_time", // 1
|
166
|
+
"mem_total", // 2
|
167
|
+
"mem_used", // 3
|
168
|
+
"mem_free", // 4
|
169
|
+
"buffers", // 5
|
170
|
+
"cached", // 6
|
171
|
+
"swap_cached", // 7
|
172
|
+
"active", // 8
|
173
|
+
"inactive", // 9
|
174
|
+
"swap_total", // 10
|
175
|
+
"swap_free", // 11
|
176
|
+
"dirty", // 12
|
177
|
+
"writeback", // 13
|
178
|
+
"anon_pages", // 14
|
179
|
+
"mapped", // 15
|
180
|
+
"shmem", // 16
|
181
|
+
"slab", // 17
|
182
|
+
"s_reclaimable", // 18
|
183
|
+
"s_unreclaim", // 19
|
184
|
+
"kernel_stack", // 20
|
185
|
+
"page_tables", // 21
|
186
|
+
"nfs_unstable", // 22
|
187
|
+
"bounce", // 23
|
188
|
+
"commit_limit", // 24
|
189
|
+
"committed_as", // 25
|
190
|
+
"anon_huge_pages", // 26
|
191
|
+
"huge_pages_total", // 27
|
192
|
+
"huge_pages_free", // 28
|
193
|
+
"huge_pages_rsvd", // 29
|
194
|
+
"huge_pages_surp", // 30
|
195
|
+
"hugepagesize"}, // 31
|
196
|
+
"\t"))
|
197
|
+
writer.WriteString("\n")
|
198
|
+
} else {
|
199
|
+
writer.WriteString(fmt.Sprintf("%f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
|
200
|
+
elapsed_time,
|
201
|
+
mem.MemTotal,
|
202
|
+
mem.MemTotal-mem.MemFree-mem.Buffers-mem.Cached-mem.SReclaimable,
|
203
|
+
mem.MemFree,
|
204
|
+
mem.Buffers,
|
205
|
+
mem.Cached,
|
206
|
+
mem.SwapCached,
|
207
|
+
mem.Active,
|
208
|
+
mem.Inactive,
|
209
|
+
mem.SwapTotal,
|
210
|
+
mem.SwapFree,
|
211
|
+
mem.Dirty,
|
212
|
+
mem.Writeback,
|
213
|
+
mem.AnonPages,
|
214
|
+
mem.Mapped,
|
215
|
+
mem.Shmem,
|
216
|
+
mem.Slab,
|
217
|
+
mem.SReclaimable,
|
218
|
+
mem.SUnreclaim,
|
219
|
+
mem.KernelStack,
|
220
|
+
mem.PageTables,
|
221
|
+
mem.NFS_Unstable,
|
222
|
+
mem.Bounce,
|
223
|
+
mem.CommitLimit,
|
224
|
+
mem.Committed_AS,
|
225
|
+
mem.AnonHugePages,
|
226
|
+
mem.HugePages_Total,
|
227
|
+
mem.HugePages_Free,
|
228
|
+
mem.HugePages_Rsvd,
|
229
|
+
mem.HugePages_Surp,
|
230
|
+
mem.Hugepagesize))
|
231
|
+
}
|
232
|
+
}
|
233
|
+
|
135
234
|
func main() {
|
136
235
|
opt := parseArgs()
|
137
236
|
|
@@ -141,7 +240,7 @@ func main() {
|
|
141
240
|
}
|
142
241
|
defer f.Close()
|
143
242
|
|
144
|
-
input_reader :=
|
243
|
+
input_reader := core.NewPerfmongerLogReader(f)
|
145
244
|
dec := gob.NewDecoder(input_reader)
|
146
245
|
|
147
246
|
var cheader ss.CommonHeader
|
@@ -192,6 +291,13 @@ func main() {
|
|
192
291
|
cpu_writer.WriteString("# All cpu usage\n")
|
193
292
|
cpu_writer.WriteString("# elapsed_time %usr %nice %sys %iowait %hardirq %softirq %steal %guest %idle\n")
|
194
293
|
|
294
|
+
f, err = os.Create(opt.MemFile)
|
295
|
+
if err != nil {
|
296
|
+
panic(err)
|
297
|
+
}
|
298
|
+
defer f.Close()
|
299
|
+
mem_writer := bufio.NewWriter(f)
|
300
|
+
|
195
301
|
for {
|
196
302
|
prev_rec := &records[curr^1]
|
197
303
|
cur_rec := &records[curr]
|
@@ -283,6 +389,12 @@ func main() {
|
|
283
389
|
}
|
284
390
|
printCoreUsage(cpu_writer, prev_rec.Time.Sub(t0).Seconds(), cusage.All)
|
285
391
|
|
392
|
+
if !meta_set {
|
393
|
+
// print column labels
|
394
|
+
printMemUsage(mem_writer, prev_rec.Time.Sub(t0).Seconds(), nil)
|
395
|
+
}
|
396
|
+
printMemUsage(mem_writer, prev_rec.Time.Sub(t0).Seconds(), cur_rec.Mem)
|
397
|
+
|
286
398
|
curr ^= 1
|
287
399
|
meta_set = true
|
288
400
|
}
|
@@ -331,6 +443,7 @@ func main() {
|
|
331
443
|
os.Remove(cpu_dat.Path)
|
332
444
|
}
|
333
445
|
cpu_writer.Flush()
|
446
|
+
mem_writer.Flush()
|
334
447
|
|
335
448
|
json_enc := json.NewEncoder(os.Stdout)
|
336
449
|
json_enc.Encode(meta)
|
File without changes
|
@@ -12,6 +12,7 @@ import (
|
|
12
12
|
"sort"
|
13
13
|
|
14
14
|
projson "github.com/hayamiz/go-projson"
|
15
|
+
"github.com/hayamiz/perfmonger/core"
|
15
16
|
ss "github.com/hayamiz/perfmonger/core/subsystem"
|
16
17
|
)
|
17
18
|
|
@@ -38,6 +39,7 @@ func parseArgs() {
|
|
38
39
|
flag.Parse()
|
39
40
|
|
40
41
|
if len(flag.Args()) < 1 {
|
42
|
+
fmt.Fprintln(os.Stderr, "Insufficient argument")
|
41
43
|
os.Exit(1)
|
42
44
|
}
|
43
45
|
|
@@ -61,7 +63,7 @@ func main() {
|
|
61
63
|
}
|
62
64
|
defer f.Close()
|
63
65
|
|
64
|
-
input_reader :=
|
66
|
+
input_reader := core.NewPerfmongerLogReader(f)
|
65
67
|
dec := gob.NewDecoder(input_reader)
|
66
68
|
|
67
69
|
err = dec.Decode(&cheader)
|
File without changes
|
data/core/go.mod
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module github.com/hayamiz/perfmonger/core
|
2
|
+
|
3
|
+
go 1.15
|
4
|
+
|
5
|
+
require (
|
6
|
+
github.com/hayamiz/go-projson v0.0.0-20210510072849-3503bd24ae61
|
7
|
+
github.com/jroimartin/gocui v0.4.0
|
8
|
+
github.com/nsf/termbox-go v1.1.1
|
9
|
+
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
|
10
|
+
)
|
data/core/go.sum
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
github.com/hayamiz/go-projson v0.0.0-20210510072849-3503bd24ae61 h1:elFR/pEri9bFREP6YvJQDcFjncPBDhG+SwWJjYSvY8s=
|
2
|
+
github.com/hayamiz/go-projson v0.0.0-20210510072849-3503bd24ae61/go.mod h1:Zkuug8uJZoQ8V34UfDAFVmKLVHPhe+TJUAazUzh6s1k=
|
3
|
+
github.com/jroimartin/gocui v0.4.0 h1:52jnalstgmc25FmtGcWqa0tcbMEWS6RpFLsOIO+I+E8=
|
4
|
+
github.com/jroimartin/gocui v0.4.0/go.mod h1:7i7bbj99OgFHzo7kB2zPb8pXLqMBSQegY7azfqXMkyY=
|
5
|
+
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
6
|
+
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
7
|
+
github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY=
|
8
|
+
github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=
|
9
|
+
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
10
|
+
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
11
|
+
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
12
|
+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
13
|
+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
14
|
+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
15
|
+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
16
|
+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
17
|
+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
@@ -469,6 +469,8 @@ func ReadMemStat(record *StatRecord) error {
|
|
469
469
|
mem_stat.HugePages_Free = val
|
470
470
|
case "HugePages_Total:":
|
471
471
|
mem_stat.HugePages_Total = val
|
472
|
+
case "Hugepagesize:":
|
473
|
+
mem_stat.Hugepagesize = val
|
472
474
|
case "AnonHugePages:":
|
473
475
|
mem_stat.AnonHugePages = val
|
474
476
|
case "Committed_AS:":
|
data/core/subsystem/stat.go
CHANGED
@@ -132,6 +132,7 @@ type MemStat struct {
|
|
132
132
|
HugePages_Free int64
|
133
133
|
HugePages_Rsvd int64
|
134
134
|
HugePages_Surp int64
|
135
|
+
Hugepagesize int64
|
135
136
|
}
|
136
137
|
|
137
138
|
type StatRecord struct {
|
@@ -286,6 +287,7 @@ func (entry *MemStat) Clear() {
|
|
286
287
|
entry.HugePages_Free = 0
|
287
288
|
entry.HugePages_Rsvd = 0
|
288
289
|
entry.HugePages_Surp = 0
|
290
|
+
entry.Hugepagesize = 0
|
289
291
|
}
|
290
292
|
|
291
293
|
func NewStatRecord() *StatRecord {
|
data/core/utils.go
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
package
|
1
|
+
package core
|
2
2
|
|
3
3
|
import (
|
4
4
|
"bufio"
|
@@ -6,7 +6,7 @@ import (
|
|
6
6
|
"io"
|
7
7
|
)
|
8
8
|
|
9
|
-
func
|
9
|
+
func NewPerfmongerLogReader(source io.Reader) io.Reader {
|
10
10
|
var ret io.Reader
|
11
11
|
reader := bufio.NewReader(source)
|
12
12
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -26,6 +26,10 @@ EOS
|
|
26
26
|
@pretty = true
|
27
27
|
end
|
28
28
|
|
29
|
+
@disk_only_regex = nil
|
30
|
+
@parser.on('--disk-only REGEX', "Select disk devices that matches REGEX (Ex. 'sd[b-d]')") do |regex|
|
31
|
+
@disk_only_regex = regex
|
32
|
+
end
|
29
33
|
end
|
30
34
|
|
31
35
|
def parse_args(argv)
|
@@ -62,6 +66,12 @@ EOS
|
|
62
66
|
if @pretty
|
63
67
|
cmd << "-pretty"
|
64
68
|
end
|
69
|
+
|
70
|
+
if @disk_only_regex
|
71
|
+
cmd << "-disk-only"
|
72
|
+
cmd << @disk_only_regex
|
73
|
+
end
|
74
|
+
|
65
75
|
cmd << @logfile
|
66
76
|
|
67
77
|
Process.exec(*cmd)
|
@@ -145,10 +145,13 @@ EOS
|
|
145
145
|
|
146
146
|
@disk_dat = File.expand_path("disk.dat", @tmpdir)
|
147
147
|
@cpu_dat = File.expand_path("cpu.dat", @tmpdir)
|
148
|
+
@mem_dat = File.expand_path("mem.dat", @tmpdir)
|
148
149
|
|
149
150
|
meta_json = nil
|
150
|
-
cmd = [formatter_bin, "-perfmonger", @data_file,
|
151
|
-
|
151
|
+
cmd = [formatter_bin, "-perfmonger", @data_file,
|
152
|
+
"-cpufile", @cpu_dat,
|
153
|
+
"-diskfile", @disk_dat,
|
154
|
+
"-memfile", @mem_dat]
|
152
155
|
if @disk_only_regex
|
153
156
|
cmd << "-disk-only"
|
154
157
|
cmd << @disk_only
|
@@ -164,6 +167,7 @@ EOS
|
|
164
167
|
|
165
168
|
plot_disk(meta)
|
166
169
|
plot_cpu(meta)
|
170
|
+
plot_mem(meta)
|
167
171
|
|
168
172
|
FileUtils.rm_rf(@tmpdir)
|
169
173
|
|
@@ -508,6 +512,144 @@ EOS
|
|
508
512
|
end
|
509
513
|
end # def
|
510
514
|
|
515
|
+
def plot_mem(meta)
|
516
|
+
pdf_filename = @output_prefix + 'mem.pdf'
|
517
|
+
gp_filename = @output_prefix + 'mem.gp'
|
518
|
+
dat_filename = @output_prefix + 'mem.dat'
|
519
|
+
|
520
|
+
unless File.exists?(dat_filename)
|
521
|
+
$stderr.puts("WARN: memory usage info is not available.")
|
522
|
+
return
|
523
|
+
end
|
524
|
+
|
525
|
+
if @output_type != 'pdf'
|
526
|
+
img_filename = @output_prefix + 'cpu.' + @output_type
|
527
|
+
else
|
528
|
+
img_filename = nil
|
529
|
+
end
|
530
|
+
|
531
|
+
start_time = meta["start_time"]
|
532
|
+
end_time = meta["end_time"]
|
533
|
+
|
534
|
+
mem_scaling = 2.0**20 # KB -> GB
|
535
|
+
|
536
|
+
# "elapsed_time", // 1
|
537
|
+
# "mem_total", // 2
|
538
|
+
# "mem_used", // 3
|
539
|
+
# "mem_free", // 4
|
540
|
+
# "buffers", // 5
|
541
|
+
# "cached", // 6
|
542
|
+
# "swap_cached", // 7
|
543
|
+
# "active", // 8
|
544
|
+
# "inactive", // 9
|
545
|
+
# "swap_total", // 10
|
546
|
+
# "swap_free", // 11
|
547
|
+
# "dirty", // 12
|
548
|
+
# "writeback", // 13
|
549
|
+
# "anon_pages", // 14
|
550
|
+
# "mapped", // 15
|
551
|
+
# "shmem", // 16
|
552
|
+
# "slab", // 17
|
553
|
+
# "s_reclaimable", // 18
|
554
|
+
# "s_unreclaim", // 19
|
555
|
+
# "kernel_stack", // 20
|
556
|
+
# "page_tables", // 21
|
557
|
+
# "nfs_unstable", // 22
|
558
|
+
# "bounce", // 23
|
559
|
+
# "commit_limit", // 24
|
560
|
+
# "committed_as", // 25
|
561
|
+
# "anon_huge_pages", // 26
|
562
|
+
# "huge_pages_total", // 27
|
563
|
+
# "huge_pages_free", // 28
|
564
|
+
# "huge_pages_rsvd", // 29
|
565
|
+
# "huge_pages_surp"}, // 30
|
566
|
+
# "hugepagesize"}, // 31
|
567
|
+
|
568
|
+
Dir.chdir(@tmpdir) do
|
569
|
+
total = `tail -n+2 #{dat_filename}|head -n1`.split[1].to_f
|
570
|
+
if total == 0.0
|
571
|
+
raise RuntimeError.new("Failed to get MemTotal value from mem.dat file: #{dat_filename}")
|
572
|
+
end
|
573
|
+
|
574
|
+
gpfile = File.open(gp_filename, 'w')
|
575
|
+
|
576
|
+
pdf_file = File.join(@output_dir, "mem.pdf")
|
577
|
+
gpfile.puts <<EOS
|
578
|
+
set term pdfcairo enhanced color size 6in,2.5in
|
579
|
+
set title "Memory usage"
|
580
|
+
set output "#{pdf_filename}"
|
581
|
+
set key outside center bottom horizontal
|
582
|
+
set size 1.0, 1.0
|
583
|
+
|
584
|
+
set xlabel "elapsed time [sec]"
|
585
|
+
set ylabel "memory usage [GB]"
|
586
|
+
|
587
|
+
# scaling
|
588
|
+
s = #{mem_scaling}
|
589
|
+
|
590
|
+
set grid
|
591
|
+
set xrange [#{@offset_time}:#{end_time - start_time}]
|
592
|
+
set yrange [0:#{total * 1.2}/s]
|
593
|
+
|
594
|
+
# line styles
|
595
|
+
set style line 1 lt 1 lc rgb '#66C2A5' # teal
|
596
|
+
set style line 2 lt 1 lc rgb '#FC8D62' # orange
|
597
|
+
set style line 3 lt 1 lc rgb '#8DA0CB' # lilac
|
598
|
+
set style line 4 lt 1 lc rgb '#E78AC3' # magentat
|
599
|
+
set style line 5 lt 1 lc rgb '#A6D854' # lime green
|
600
|
+
set style line 6 lt 1 lc rgb '#FFD92F' # banana
|
601
|
+
set style line 7 lt 1 lc rgb '#E5C494' # tan
|
602
|
+
set style line 8 lt 1 lc rgb '#B3B3B3' # grey
|
603
|
+
|
604
|
+
# palette
|
605
|
+
set palette maxcolors 8
|
606
|
+
set palette defined ( 0 '#66C2A5',\
|
607
|
+
1 '#FC8D62',\
|
608
|
+
2 '#8DA0CB',\
|
609
|
+
3 '#E78AC3',\
|
610
|
+
4 '#A6D854',\
|
611
|
+
5 '#FFD92F',\
|
612
|
+
6 '#E5C494',\
|
613
|
+
7 '#B3B3B3' )
|
614
|
+
|
615
|
+
used(total, free, cached, buffers, srecl) = \\
|
616
|
+
( (total - free - cache(cached, srecl) - buffers < 0) ? \\
|
617
|
+
(total - free) : \\
|
618
|
+
(total - free - cache(cached, srecl) - buffers) )
|
619
|
+
|
620
|
+
cache(cached, srecl) = cached + srecl
|
621
|
+
|
622
|
+
plot "#{dat_filename}" usi 1:($4/s+$5/s+cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 8 ti "free", \\
|
623
|
+
"#{dat_filename}" usi 1:($5/s+cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 3 ti "buffers", \\
|
624
|
+
"#{dat_filename}" usi 1:(cache($6, $18)/s+$16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 5 ti "cached", \\
|
625
|
+
"#{dat_filename}" usi 1:($16/s+used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 6 ti "shared", \\
|
626
|
+
"#{dat_filename}" usi 1:(used($2, $4, $6, $5, $18)/s) wi filledcurves x1 ls 2 ti "used", \\
|
627
|
+
"#{dat_filename}" usi 1:(($27-$28)*$31/s) wi lines dt (4,4) lc rgb 'black' lw 2.5 ti 'used (hugepage)'
|
628
|
+
|
629
|
+
EOS
|
630
|
+
|
631
|
+
gpfile.close
|
632
|
+
system("gnuplot #{gpfile.path}")
|
633
|
+
|
634
|
+
if @output_type != 'pdf'
|
635
|
+
system("convert -density 150 -background white #{pdf_filename} #{img_filename}")
|
636
|
+
end
|
637
|
+
end # chdir
|
638
|
+
|
639
|
+
copy_targets = []
|
640
|
+
copy_targets << pdf_filename
|
641
|
+
copy_targets << img_filename if img_filename
|
642
|
+
|
643
|
+
if @save_gpfiles
|
644
|
+
copy_targets << gp_filename
|
645
|
+
copy_targets << dat_filename
|
646
|
+
end
|
647
|
+
|
648
|
+
copy_targets.each do |target|
|
649
|
+
FileUtils.copy(File.join(@tmpdir, target), @output_dir)
|
650
|
+
end
|
651
|
+
end # def
|
652
|
+
|
511
653
|
private
|
512
654
|
def factors(n)
|
513
655
|
(2..([n, n / 2].max).to_i).select do |x|
|
@@ -31,7 +31,8 @@ class RecordCommand < BaseCommand
|
|
31
31
|
if @option.kill
|
32
32
|
unless session_pid
|
33
33
|
# There is nothing to be killed
|
34
|
-
|
34
|
+
$stderr.puts("[ERROR] No perfmonger record session is running.")
|
35
|
+
return false
|
35
36
|
end
|
36
37
|
|
37
38
|
begin
|
@@ -44,12 +45,32 @@ class RecordCommand < BaseCommand
|
|
44
45
|
f.flock(File::LOCK_UN)
|
45
46
|
end
|
46
47
|
end
|
48
|
+
|
49
|
+
# wait until the process surely exits
|
50
|
+
sleeptime = 0.05
|
51
|
+
try = 0
|
52
|
+
while true
|
53
|
+
begin
|
54
|
+
Process.kill(:INT, session_pid)
|
55
|
+
rescue Errno::ESRCH
|
56
|
+
# no such process
|
57
|
+
break
|
58
|
+
end
|
59
|
+
sleep(sleeptime)
|
60
|
+
sleeptime *= 2
|
61
|
+
try += 1
|
62
|
+
if try >= 5
|
63
|
+
$stderr.puts("[ERROR] Cannot stop perfmonger record session correctly. PID=#{session_pid}")
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
47
68
|
return true
|
48
69
|
end
|
49
70
|
|
50
71
|
if @option.status
|
51
72
|
unless session_pid
|
52
|
-
puts "[ERROR] No perfmonger
|
73
|
+
puts "[ERROR] No perfmonger record session is running."
|
53
74
|
return false
|
54
75
|
end
|
55
76
|
|
data/lib/perfmonger/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perfmonger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuto HAYAMIZU
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,11 +101,14 @@ files:
|
|
101
101
|
- Rakefile
|
102
102
|
- core/Makefile
|
103
103
|
- core/build.sh
|
104
|
-
- core/perfmonger-player.go
|
105
|
-
- core/perfmonger-plot-formatter.
|
106
|
-
- core/perfmonger-
|
107
|
-
- core/perfmonger-
|
108
|
-
- core/perfmonger-
|
104
|
+
- core/cmd/perfmonger-player/perfmonger-player.go
|
105
|
+
- core/cmd/perfmonger-plot-formatter/README.md
|
106
|
+
- core/cmd/perfmonger-plot-formatter/perfmonger-plot-formatter.go
|
107
|
+
- core/cmd/perfmonger-recorder/perfmonger-recorder.go
|
108
|
+
- core/cmd/perfmonger-summarizer/perfmonger-summarizer.go
|
109
|
+
- core/cmd/perfmonger-viewer/perfmonger-viewer.go
|
110
|
+
- core/go.mod
|
111
|
+
- core/go.sum
|
109
112
|
- core/subsystem/Makefile
|
110
113
|
- core/subsystem/perfmonger.go
|
111
114
|
- core/subsystem/perfmonger_darwin.go
|