perfmonger 0.11.2 → 0.14.0
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/.travis.yml +5 -5
- data/NEWS +38 -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} +53 -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} +6 -0
- data/core/{perfmonger-summarizer.go → cmd/perfmonger-summarizer/perfmonger-summarizer.go} +4 -2
- 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/Makefile +4 -0
- data/core/subsystem/perfmonger_linux.go +97 -0
- data/core/subsystem/perfmonger_linux_test.go +40 -0
- data/core/subsystem/stat.go +72 -0
- data/core/subsystem/stat_test.go +9 -0
- data/core/subsystem/usage.go +80 -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 +146 -3
- data/lib/perfmonger/command/record.rb +23 -2
- data/lib/perfmonger/command/record_option.rb +16 -0
- data/lib/perfmonger/version.rb +1 -1
- data/misc/werker-box/Dockerfile +10 -9
- data/misc/werker-box/build-push.sh +2 -2
- data/wercker.yml +10 -10
- metadata +12 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cafa0eb63dce619c0f5cf2f23042db020e435905eb7d00e2338d3c499495d02
|
4
|
+
data.tar.gz: ab6875fdfe16bd70461db8569b4c5572bbd261e931a6efa98c2bede6660e9d1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17bb023ddebbde5fda03b2ed90411274a335e34ac5ddc83e4df7821454e40484957688ed7dfe72b9245190006fee0c2e1e39aa375fe17c12f95bba9838f2d767
|
7
|
+
data.tar.gz: 259636bb0f5049e404ec752edf0e659b23b8bc1adcaea69ef2f0db4cc3bfccac028793fd48920d9e4a54e5cda86a3a52581eb2dc250abd0b5f8476dec815772f
|
data/.travis.yml
CHANGED
@@ -4,7 +4,7 @@ install:
|
|
4
4
|
- sudo apt-get install gnuplot
|
5
5
|
- gnuplot -e "set terminal" < /dev/null 2>&1
|
6
6
|
- bundle install
|
7
|
-
- go_version="1.
|
7
|
+
- go_version="1.14.1"
|
8
8
|
- wget http://golang.org/dl/go${go_version}.linux-amd64.tar.gz
|
9
9
|
- sudo tar -C /usr/local -xzf go${go_version}.linux-amd64.tar.gz
|
10
10
|
- export PATH=$PATH:/usr/local/go/bin
|
@@ -12,10 +12,10 @@ install:
|
|
12
12
|
- export PATH="$PATH:$GOPATH/bin"
|
13
13
|
- mkdir -p "$HOME/go/{src,pkg,bin}"
|
14
14
|
rvm:
|
15
|
-
- 2.
|
16
|
-
- 2.
|
17
|
-
- 2.
|
18
|
-
- 2.
|
15
|
+
- 2.4.9
|
16
|
+
- 2.5.7
|
17
|
+
- 2.6.5
|
18
|
+
- 2.7.0
|
19
19
|
script:
|
20
20
|
- rake go_get
|
21
21
|
- rake spec
|
data/NEWS
CHANGED
@@ -1,9 +1,46 @@
|
|
1
|
-
##
|
1
|
+
## 2021-XX-XX: PerfMonger 0.15.0
|
2
|
+
|
3
|
+
## 2021-07-27: PerfMonger 0.14.0
|
4
|
+
* New features
|
5
|
+
* [plot] subcommand:
|
6
|
+
* Added memory usage plot
|
7
|
+
* Changes
|
8
|
+
* [record] subcommand:
|
9
|
+
* Additionaly record 'Hugepagesize' in memory usage
|
10
|
+
|
11
|
+
## 2021-07-26: PerfMonger 0.13.1
|
12
|
+
* New features
|
13
|
+
* [play] subcommand:
|
14
|
+
* Added --disk-only option to filter results of not interesting disks
|
15
|
+
* Note: v0.13.0 is yanked from rubygems.org
|
16
|
+
|
17
|
+
## 2021-07-08: PerfMonger 0.12.1
|
18
|
+
* Bug fixes
|
19
|
+
* [record] subcommand:
|
20
|
+
* --kill waits until a recorder process surely exits
|
21
|
+
|
22
|
+
## 2021-05-10: PerfMonger 0.12.0
|
23
|
+
* New features
|
24
|
+
* [record] subcommand:
|
25
|
+
* Add memory usage collection
|
26
|
+
|
27
|
+
## 2021-02-10: PerfMonger 0.11.3
|
28
|
+
* Bug fixes
|
29
|
+
* [plot] subcommand:
|
30
|
+
* Fall back to available gnuplot terminal
|
31
|
+
* Changes
|
32
|
+
* [plot] subcommand:
|
33
|
+
* Added --with-gnuplot option for specifying gnuplot binary
|
2
34
|
|
3
35
|
## 2020-03-31: PerfMonger 0.11.2
|
4
36
|
* Bug fixes
|
5
37
|
* [plot] subcommand:
|
6
38
|
* Remove temporary directory correctly
|
39
|
+
* Changes
|
40
|
+
* CI environment
|
41
|
+
* Changed golang version to 1.14
|
42
|
+
* Dropped support of ruby older than 2.4
|
43
|
+
* Added ruby 2.6 and 2.7
|
7
44
|
|
8
45
|
## 2018-05-15: PerfMonger 0.11.1
|
9
46
|
* Bug fixes
|
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
|
}
|
@@ -80,7 +85,22 @@ func showNetStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec
|
|
80
85
|
return nil
|
81
86
|
}
|
82
87
|
|
83
|
-
func
|
88
|
+
func showMemStat(printer *projson.JsonPrinter, cur_rec *ss.StatRecord) error {
|
89
|
+
musage, err := ss.GetMemUsage(cur_rec.Mem)
|
90
|
+
if err != nil {
|
91
|
+
return err
|
92
|
+
}
|
93
|
+
|
94
|
+
printer.PutKey("mem")
|
95
|
+
|
96
|
+
musage.WriteJsonTo(printer)
|
97
|
+
|
98
|
+
return nil
|
99
|
+
}
|
100
|
+
|
101
|
+
func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord,
|
102
|
+
disk_only_regex *regexp.Regexp) error {
|
103
|
+
|
84
104
|
printer.Reset()
|
85
105
|
if option.pretty {
|
86
106
|
printer.SetStyle(projson.SmartStyle)
|
@@ -88,6 +108,7 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
88
108
|
if option.color {
|
89
109
|
printer.SetColor(true)
|
90
110
|
}
|
111
|
+
|
91
112
|
printer.BeginObject()
|
92
113
|
printer.PutKey("time")
|
93
114
|
printer.PutFloatFmt(float64(cur_rec.Time.UnixNano())/1e9, "%.3f")
|
@@ -108,7 +129,7 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
108
129
|
}
|
109
130
|
}
|
110
131
|
if cur_rec.Disk != nil {
|
111
|
-
err := showDiskStat(printer, prev_rec, cur_rec)
|
132
|
+
err := showDiskStat(printer, prev_rec, cur_rec, disk_only_regex)
|
112
133
|
if err != nil {
|
113
134
|
return err
|
114
135
|
}
|
@@ -119,6 +140,12 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
119
140
|
return err
|
120
141
|
}
|
121
142
|
}
|
143
|
+
if cur_rec.Mem != nil {
|
144
|
+
err := showMemStat(printer, cur_rec)
|
145
|
+
if err != nil {
|
146
|
+
return err
|
147
|
+
}
|
148
|
+
}
|
122
149
|
|
123
150
|
printer.FinishObject()
|
124
151
|
|
@@ -128,9 +155,25 @@ func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss
|
|
128
155
|
func parseArgs() {
|
129
156
|
flag.BoolVar(&option.color, "color", false, "Use colored JSON output")
|
130
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")
|
131
159
|
|
132
160
|
flag.Parse()
|
133
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
|
+
|
134
177
|
option.logfile = flag.Arg(0)
|
135
178
|
}
|
136
179
|
|
@@ -150,7 +193,7 @@ func main() {
|
|
150
193
|
in = f
|
151
194
|
defer f.Close()
|
152
195
|
}
|
153
|
-
input_reader :=
|
196
|
+
input_reader := core.NewPerfmongerLogReader(in)
|
154
197
|
dec := gob.NewDecoder(input_reader)
|
155
198
|
|
156
199
|
out = bufio.NewWriter(os.Stdout)
|
@@ -199,7 +242,7 @@ func main() {
|
|
199
242
|
panic(err)
|
200
243
|
}
|
201
244
|
|
202
|
-
err = showStat(printer, prev_rec, cur_rec)
|
245
|
+
err = showStat(printer, prev_rec, cur_rec, option.disk_only_regex)
|
203
246
|
if err != nil {
|
204
247
|
printer.Reset()
|
205
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)
|