perfmonger 0.11.2 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|