perfmonger 0.10.1 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.travis.yml +9 -8
- data/HOWTO.md +0 -1
- data/NEWS +47 -3
- data/README.md +77 -27
- data/Rakefile +20 -9
- data/core/Makefile +10 -18
- data/core/build.sh +2 -2
- data/core/perfmonger-player.go +90 -40
- data/core/perfmonger-plot-formatter.go +18 -4
- data/core/perfmonger-recorder.go +22 -2
- data/core/perfmonger-summarizer.go +20 -14
- data/core/perfmonger-viewer.go +164 -0
- data/core/subsystem/Makefile +4 -0
- data/core/subsystem/perfmonger_linux.go +95 -0
- data/core/subsystem/perfmonger_linux_test.go +40 -0
- data/core/subsystem/stat.go +70 -0
- data/core/subsystem/stat_test.go +9 -0
- data/core/subsystem/usage.go +223 -66
- data/core/subsystem/usage_test.go +62 -32
- data/{bin → exe}/perfmonger +0 -0
- data/lib/perfmonger/command/fingerprint.rb +26 -1
- data/lib/perfmonger/command/live.rb +19 -0
- data/lib/perfmonger/command/play.rb +16 -0
- data/lib/perfmonger/command/plot.rb +25 -9
- data/lib/perfmonger/command/record.rb +1 -1
- data/lib/perfmonger/command/record_option.rb +16 -0
- data/lib/perfmonger/command/server.rb +1 -1
- data/lib/perfmonger/version.rb +1 -1
- data/misc/werker-box/Dockerfile +34 -0
- data/misc/werker-box/build-push.sh +7 -0
- data/perfmonger.gemspec +2 -1
- data/spec/data/busy100.pgr.played +3 -3
- data/spec/fingerprint_spec.rb +1 -1
- data/spec/live_spec.rb +2 -3
- data/spec/perfmonger_spec.rb +1 -1
- data/spec/play_spec.rb +1 -1
- data/spec/plot_spec.rb +16 -1
- data/spec/record_spec.rb +10 -1
- data/spec/spec_helper.rb +28 -3
- data/spec/stat_spec.rb +2 -2
- data/spec/summary_spec.rb +1 -1
- data/wercker.yml +29 -16
- metadata +28 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d54380ef057091f9d6829d3a792c0c4a91789b56077ff7a59b4a1bf063ec883e
|
4
|
+
data.tar.gz: c01127d30de0978a88bf1481357d3e20cde8193dd16e6bde9e0f2030d6423710
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ae9ded1f5d4c5157902ccfa23a12910866834480f7b82e1464f4c2d5e767cbf2d5752118f1aa666f445d2f61a0e5cfbc7198c3ad9cf098539c0cd96a25b12f3
|
7
|
+
data.tar.gz: 3c507d05cec5b3b28e49367379846009b1848ac75d23227d22a019203190b9adeaf201a25805b3746d518d221a46399580d49899f6205f236980c70b3b73a7e5
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,24 +1,25 @@
|
|
1
|
-
|
2
1
|
language: ruby
|
3
2
|
install:
|
4
3
|
- sudo apt-get update
|
5
4
|
- sudo apt-get install gnuplot
|
6
5
|
- gnuplot -e "set terminal" < /dev/null 2>&1
|
7
6
|
- bundle install
|
8
|
-
- go_version="1.
|
7
|
+
- go_version="1.14.1"
|
9
8
|
- wget http://golang.org/dl/go${go_version}.linux-amd64.tar.gz
|
10
9
|
- sudo tar -C /usr/local -xzf go${go_version}.linux-amd64.tar.gz
|
11
10
|
- export PATH=$PATH:/usr/local/go/bin
|
12
11
|
- export GOPATH="$HOME/go"
|
13
12
|
- export PATH="$PATH:$GOPATH/bin"
|
14
13
|
- mkdir -p "$HOME/go/{src,pkg,bin}"
|
15
|
-
- go get -u golang.org/x/crypto/ssh/terminal
|
16
|
-
- go get -u github.com/hayamiz/perfmonger/core/subsystem
|
17
14
|
rvm:
|
18
|
-
-
|
19
|
-
- 2.
|
20
|
-
- 2.
|
21
|
-
- 2.
|
15
|
+
- 2.4.9
|
16
|
+
- 2.5.7
|
17
|
+
- 2.6.5
|
18
|
+
- 2.7.0
|
22
19
|
script:
|
20
|
+
- rake go_get
|
23
21
|
- rake spec
|
24
22
|
- rake test_core
|
23
|
+
notifications:
|
24
|
+
slack:
|
25
|
+
secure: fH8tRyxWHL60OV6QuJlzig9lCLbjfpHx8E6D2EzgQz7+/wqAxtoTUyiN7mbpEJa4hyQeZfpmMpDTnl2tHD6eI8yqjAsY4Q+jt21tCKyrKMegq9Pypd4eMP4o+DupT2mXm0K3cZ2Kgb+yP8AuJPoTy20j3kpmnDFWdqRnhgpBLC8=
|
data/HOWTO.md
CHANGED
data/NEWS
CHANGED
@@ -1,5 +1,49 @@
|
|
1
|
-
##
|
2
|
-
|
1
|
+
## 20XX-XX-XX: PerfMonger 0.13.0
|
2
|
+
|
3
|
+
## 2021-05-10: PerfMonger 0.12.0
|
4
|
+
* New features
|
5
|
+
* [record] subcommand:
|
6
|
+
* Add memory usage collection
|
7
|
+
|
8
|
+
## 2021-02-10: PerfMonger 0.11.3
|
9
|
+
* Bug fixes
|
10
|
+
* [plot] subcommand:
|
11
|
+
* Fall back to available gnuplot terminal
|
12
|
+
* Changes
|
13
|
+
* [plot] subcommand:
|
14
|
+
* Added --with-gnuplot option for specifying gnuplot binary
|
15
|
+
|
16
|
+
## 2020-03-31: PerfMonger 0.11.2
|
17
|
+
* Bug fixes
|
18
|
+
* [plot] subcommand:
|
19
|
+
* Remove temporary directory correctly
|
20
|
+
* Changes
|
21
|
+
* CI environment
|
22
|
+
* Changed golang version to 1.14
|
23
|
+
* Dropped support of ruby older than 2.4
|
24
|
+
* Added ruby 2.6 and 2.7
|
25
|
+
|
26
|
+
## 2018-05-15: PerfMonger 0.11.1
|
27
|
+
* Bug fixes
|
28
|
+
* [record] subcommand:
|
29
|
+
* Fixed session detection mechanism (did not worked for execution under sudo)
|
30
|
+
|
31
|
+
## 2018-05-15: PerfMonger 0.11.0
|
32
|
+
* New features
|
33
|
+
* [play] subcommand:
|
34
|
+
* Add --color, --pretty option for pretty JSON output
|
35
|
+
* [live] subcommand:
|
36
|
+
* Add --color, --pretty option for pretty JSON output
|
37
|
+
* [fingerprint] subcommand:
|
38
|
+
* Collect additional info: numactl, ec2-metadata
|
39
|
+
* Bug fixes
|
40
|
+
* [plot] subcommand:
|
41
|
+
* Correctly filter out disk usages by --disk-only option
|
42
|
+
* Changes
|
43
|
+
* Dropped support of i386
|
44
|
+
* Use go-projson for JSON output
|
45
|
+
* [plot] subcommand:
|
46
|
+
* Stacked graphs layout in allcpu.pdf
|
3
47
|
|
4
48
|
## 2017-06-19: PerfMonger 0.10.0
|
5
49
|
* New features
|
@@ -199,4 +243,4 @@ PerfMonger is available on yum repository from this release.
|
|
199
243
|
## 2011-12-09: PerfMonger 0.1.0 released
|
200
244
|
|
201
245
|
* New features
|
202
|
-
* I/O performance monitoring
|
246
|
+
* I/O performance monitoring
|
data/README.md
CHANGED
@@ -5,31 +5,97 @@
|
|
5
5
|
|
6
6
|
[![wercker status](https://app.wercker.com/status/44c3ade6a2406d337df6d93097a52fdf/m "wercker status")](https://app.wercker.com/project/bykey/44c3ade6a2406d337df6d93097a52fdf)
|
7
7
|
|
8
|
-
PerfMonger is
|
9
|
-
|
8
|
+
PerfMonger is a system performance monitor which enables high-resolution and holistic performance measurement with the programmer friendly interface.
|
9
|
+
|
10
|
+
* High-resolution: sub-second level monitoring is possible!
|
11
|
+
* Holistic performance measurement: monitoring CPU, Disk I/O, Network all at once.
|
12
|
+
* Programmer friendly: PerfMonger speaks monitoring results in JSON format, which makes later performance analysis much easier (ex. [jq](https://github.com/stedolan/jq)).
|
10
13
|
|
11
14
|
**CAUTION: PerfMonger is still in early stage, so there may be a drastic change in the future. Do not use it for critical jobs**
|
12
15
|
|
13
16
|
## Target platform
|
14
17
|
|
15
18
|
* GNU/Linux
|
19
|
+
* Mac OS X (experimental support)
|
16
20
|
|
17
|
-
##
|
18
|
-
|
19
|
-
* Ruby 1.9.3 or later
|
20
|
-
* gnuplot 4.6.0 or later (optional)
|
21
|
-
|
22
|
-
Note: You need Cutter unit testing framework for building/running tests.
|
23
|
-
|
24
|
-
## How to install
|
21
|
+
## How to installation
|
25
22
|
|
26
23
|
gem install perfmonger
|
27
24
|
|
25
|
+
You need gnuplot 4.6.0 or later build with cairo terminals for plotting measurement data with `perfmonger plot` command.
|
26
|
+
|
28
27
|
### Build from source
|
29
28
|
|
29
|
+
You need Ruby 2.2 or later, and Go 1.8 or later to build perfmonger.
|
30
|
+
|
31
|
+
bundle
|
30
32
|
rake build
|
31
33
|
|
32
|
-
##
|
34
|
+
## Getting started
|
35
|
+
|
36
|
+
Basic usage of PerfMonger is:
|
37
|
+
|
38
|
+
* Run `perfmonger record` to record performance information logs
|
39
|
+
* Run `perfmonger play` to show performance information logs in JSON format
|
40
|
+
|
41
|
+
`perfmonger play` repatedly prints records of system performance including CPU
|
42
|
+
usages, disk usages, and network usages. One line includes only one record, so
|
43
|
+
you can easily process output records with `jq`, or any scripting languages like
|
44
|
+
Ruby, Python, and etc.
|
45
|
+
|
46
|
+
Pretty-printed structure of a record is as follows:
|
47
|
+
|
48
|
+
```
|
49
|
+
{"time": 1500043743.504, # timestamp in unix epoch time
|
50
|
+
"cpu": { # CPU usages
|
51
|
+
"num_core": 2, # the number of cores
|
52
|
+
"all": { # aggregated CPU usage (max = num_core * 100%)
|
53
|
+
"usr": 50.0,
|
54
|
+
"sys": 50.0,
|
55
|
+
"idle": 100.0,
|
56
|
+
...
|
57
|
+
},
|
58
|
+
"cores": [ # Usage of each CPU core
|
59
|
+
{
|
60
|
+
"usr": 25.0,
|
61
|
+
"sys": 25.0,
|
62
|
+
"idle": 50.0,
|
63
|
+
...
|
64
|
+
},
|
65
|
+
{
|
66
|
+
"usr": 25.0,
|
67
|
+
"sys": 25.0,
|
68
|
+
"idle": 50.0,
|
69
|
+
...
|
70
|
+
}
|
71
|
+
]
|
72
|
+
},
|
73
|
+
"disk": { # Disk usages
|
74
|
+
"devices": ["sda"], # List of disk devices
|
75
|
+
"sda": { # Usage of device 'sda'
|
76
|
+
"riops": 10.0, # The number of read I/O per second
|
77
|
+
"wiops": 20.0, # The number of write I/O per second
|
78
|
+
"rkbyteps": 80.0, # Read transfer rate in KB/s
|
79
|
+
"wkbyteps": 160.0, # Write transfer rate in KB/s
|
80
|
+
...
|
81
|
+
}
|
82
|
+
"total": { # Aggregated usage of all devices
|
83
|
+
"riops": 10.0,
|
84
|
+
"wiops": 20.0,
|
85
|
+
"rkbyteps": 80.0,
|
86
|
+
"wkbyteps": 160.0,
|
87
|
+
...
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
```
|
92
|
+
|
93
|
+
|
94
|
+
## Typical use cases
|
95
|
+
|
96
|
+
### `perfmonger live`: live performance monitoring
|
97
|
+
|
98
|
+
$ perfmonger live
|
33
99
|
|
34
100
|
### Monitor IO performance of /dev/sda for each 0.1 second
|
35
101
|
|
@@ -42,19 +108,3 @@ Note: You need Cutter unit testing framework for building/running tests.
|
|
42
108
|
### Monitor CPU usage and IO performance of /dev/sda, sdb for each 0.1 second
|
43
109
|
|
44
110
|
$ perfmonger record -i 0.1 -d sda -d sdb
|
45
|
-
|
46
|
-
### Plot CPU and IOPS
|
47
|
-
|
48
|
-
$ perfmonger record -i 0.1 -C -d sda > /tmp/perfmonger.log & sleep 10; pkill perfmonger
|
49
|
-
$ perfmonger plot -o /path/to/output_dir/ -Tpng /tmp/perfmonger.log
|
50
|
-
$ display /path/to/output_dir/read-iops.png
|
51
|
-
$ display /path/to/output_dir/cpu.png
|
52
|
-
|
53
|
-
![Sample image of IOPS graph](https://raw.github.com/hayamiz/perfmonger/master/misc/sample-read-iops.png)
|
54
|
-
![Sample image of CPU usage graph](https://raw.github.com/hayamiz/perfmonger/master/misc/sample-cpu.png)
|
55
|
-
|
56
|
-
## Special Thanks
|
57
|
-
|
58
|
-
Large portion of PerfMonger comes from
|
59
|
-
[SYSSTAT](http://sebastien.godard.pagesperso-orange.fr/) codebase. Thanks for
|
60
|
-
their great work.
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ task :default => [:spec, :test_core]
|
|
7
7
|
desc "Run all specs in spec directory"
|
8
8
|
RSpec::Core::RakeTask.new(:spec)
|
9
9
|
|
10
|
-
task :spec => [:
|
10
|
+
task :spec => [:cross_build_core]
|
11
11
|
|
12
12
|
desc "Cross build core recorder/player"
|
13
13
|
task :cross_build_core do
|
@@ -18,20 +18,31 @@ task :cross_build_core do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
desc "Self build core recorder/player"
|
22
|
-
task :self_build_core do
|
23
|
-
Dir.chdir("./core") do
|
24
|
-
sh "./build.sh -"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
21
|
task :build => :cross_build_core
|
29
22
|
|
23
|
+
desc "Install Golang libraries"
|
24
|
+
task :go_get do
|
25
|
+
sh "go get -u github.com/hayamiz/go-projson"
|
26
|
+
sh "go get -u github.com/hayamiz/perfmonger/core/subsystem"
|
27
|
+
sh "go get -u golang.org/x/crypto/ssh/terminal"
|
28
|
+
sh "go get -u github.com/mattn/go-isatty"
|
29
|
+
sh "go get -u github.com/nsf/termbox-go"
|
30
|
+
sh "go get -u github.com/jroimartin/gocui"
|
31
|
+
end
|
32
|
+
|
30
33
|
desc "Run tests of core recorder/player"
|
31
|
-
task :test_core do
|
34
|
+
task :test_core => [:cross_build_core] do
|
32
35
|
Dir.chdir("./core/subsystem") do
|
33
36
|
sh "go test -v -cover"
|
37
|
+
|
38
|
+
# running static analysis
|
39
|
+
sh "go vet *.go"
|
34
40
|
end
|
41
|
+
|
42
|
+
Dir.chdir("./core") do
|
43
|
+
sh "go vet *.go"
|
44
|
+
end
|
45
|
+
|
35
46
|
end
|
36
47
|
|
37
48
|
desc "Removed generated files"
|
data/core/Makefile
CHANGED
@@ -9,22 +9,6 @@ GO_SRC := utils.go
|
|
9
9
|
all: build
|
10
10
|
|
11
11
|
|
12
|
-
../lib/exec/perfmonger-recorder_linux_386: perfmonger-recorder.go $(GO_DEPS)
|
13
|
-
go build -o $@ perfmonger-recorder.go $(GO_SRC)
|
14
|
-
|
15
|
-
|
16
|
-
../lib/exec/perfmonger-player_linux_386: perfmonger-player.go $(GO_DEPS)
|
17
|
-
go build -o $@ perfmonger-player.go $(GO_SRC)
|
18
|
-
|
19
|
-
|
20
|
-
../lib/exec/perfmonger-summarizer_linux_386: perfmonger-summarizer.go $(GO_DEPS)
|
21
|
-
go build -o $@ perfmonger-summarizer.go $(GO_SRC)
|
22
|
-
|
23
|
-
|
24
|
-
../lib/exec/perfmonger-plot-formatter_linux_386: perfmonger-plot-formatter.go $(GO_DEPS)
|
25
|
-
go build -o $@ perfmonger-plot-formatter.go $(GO_SRC)
|
26
|
-
|
27
|
-
|
28
12
|
../lib/exec/perfmonger-recorder_linux_amd64: perfmonger-recorder.go $(GO_DEPS)
|
29
13
|
go build -o $@ perfmonger-recorder.go $(GO_SRC)
|
30
14
|
|
@@ -33,6 +17,10 @@ all: build
|
|
33
17
|
go build -o $@ perfmonger-player.go $(GO_SRC)
|
34
18
|
|
35
19
|
|
20
|
+
../lib/exec/perfmonger-viewer_linux_amd64: perfmonger-viewer.go $(GO_DEPS)
|
21
|
+
go build -o $@ perfmonger-viewer.go $(GO_SRC)
|
22
|
+
|
23
|
+
|
36
24
|
../lib/exec/perfmonger-summarizer_linux_amd64: perfmonger-summarizer.go $(GO_DEPS)
|
37
25
|
go build -o $@ perfmonger-summarizer.go $(GO_SRC)
|
38
26
|
|
@@ -49,6 +37,10 @@ all: build
|
|
49
37
|
go build -o $@ perfmonger-player.go $(GO_SRC)
|
50
38
|
|
51
39
|
|
40
|
+
../lib/exec/perfmonger-viewer_darwin_amd64: perfmonger-viewer.go $(GO_DEPS)
|
41
|
+
go build -o $@ perfmonger-viewer.go $(GO_SRC)
|
42
|
+
|
43
|
+
|
52
44
|
../lib/exec/perfmonger-summarizer_darwin_amd64: perfmonger-summarizer.go $(GO_DEPS)
|
53
45
|
go build -o $@ perfmonger-summarizer.go $(GO_SRC)
|
54
46
|
|
@@ -57,8 +49,8 @@ all: build
|
|
57
49
|
go build -o $@ perfmonger-plot-formatter.go $(GO_SRC)
|
58
50
|
|
59
51
|
|
60
|
-
build: ../lib/exec/perfmonger-
|
52
|
+
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
|
61
53
|
|
62
54
|
clean:
|
63
|
-
rm -f ../lib/exec/perfmonger-
|
55
|
+
rm -f ../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
|
64
56
|
|
data/core/build.sh
CHANGED
@@ -28,7 +28,7 @@ if [[ $1 = "-" ]]; then
|
|
28
28
|
TARGET=("${os} ${arch}")
|
29
29
|
else
|
30
30
|
# cross build
|
31
|
-
TARGET=("linux
|
31
|
+
TARGET=("linux amd64" "darwin amd64")
|
32
32
|
fi
|
33
33
|
|
34
34
|
set -e
|
@@ -57,7 +57,7 @@ for idx in $(seq 0 $((${#TARGET[@]}-1))); do
|
|
57
57
|
export var_GOOS=$1
|
58
58
|
export var_GOARCH=$2
|
59
59
|
|
60
|
-
for subcmd in recorder player summarizer plot-formatter; do
|
60
|
+
for subcmd in recorder player viewer summarizer plot-formatter; do
|
61
61
|
TARGETS+=(../lib/exec/perfmonger-${subcmd}_${var_GOOS}_${var_GOARCH})
|
62
62
|
|
63
63
|
cat <<EOF >> $makefile
|
data/core/perfmonger-player.go
CHANGED
@@ -4,39 +4,38 @@ package main
|
|
4
4
|
|
5
5
|
import (
|
6
6
|
"bufio"
|
7
|
-
"bytes"
|
8
7
|
"encoding/gob"
|
8
|
+
"flag"
|
9
9
|
"fmt"
|
10
10
|
"io"
|
11
11
|
"os"
|
12
12
|
|
13
|
+
projson "github.com/hayamiz/go-projson"
|
13
14
|
ss "github.com/hayamiz/perfmonger/core/subsystem"
|
14
15
|
)
|
15
16
|
|
16
|
-
|
17
|
+
type PlayerOption struct {
|
18
|
+
logfile string
|
19
|
+
color bool
|
20
|
+
pretty bool
|
21
|
+
}
|
22
|
+
|
23
|
+
var option PlayerOption
|
24
|
+
var init_rec ss.StatRecord
|
25
|
+
|
26
|
+
func showCpuStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
|
17
27
|
cusage, err := ss.GetCpuUsage(prev_rec.Cpu, cur_rec.Cpu)
|
18
28
|
if err != nil {
|
19
29
|
return err
|
20
30
|
}
|
21
|
-
|
22
|
-
|
31
|
+
|
32
|
+
printer.PutKey("cpu")
|
33
|
+
cusage.WriteJsonTo(printer)
|
23
34
|
|
24
35
|
return nil
|
25
36
|
}
|
26
37
|
|
27
|
-
func showInterruptStat(
|
28
|
-
// intr_usage, err := ss.GetInterruptUsage(
|
29
|
-
// prev_rec.Time, prev_rec.Interrupt,
|
30
|
-
// cur_rec.Time, cur_rec.Interrupt)
|
31
|
-
// if err != nil {
|
32
|
-
// return err
|
33
|
-
// }
|
34
|
-
//
|
35
|
-
// buffer.WriteString(`,"intr":`)
|
36
|
-
// intr_usage.WriteJsonTo(buffer)
|
37
|
-
//
|
38
|
-
// return nil
|
39
|
-
|
38
|
+
func showInterruptStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
|
40
39
|
intr_usage, err := ss.GetInterruptUsage(
|
41
40
|
prev_rec.Time, prev_rec.Interrupt,
|
42
41
|
cur_rec.Time, cur_rec.Interrupt)
|
@@ -44,13 +43,13 @@ func showInterruptStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *s
|
|
44
43
|
return err
|
45
44
|
}
|
46
45
|
|
47
|
-
|
48
|
-
intr_usage.WriteJsonTo(
|
46
|
+
printer.PutKey("intr")
|
47
|
+
intr_usage.WriteJsonTo(printer)
|
49
48
|
|
50
49
|
return nil
|
51
50
|
}
|
52
51
|
|
53
|
-
func showDiskStat(
|
52
|
+
func showDiskStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
|
54
53
|
dusage, err := ss.GetDiskUsage(
|
55
54
|
prev_rec.Time, prev_rec.Disk,
|
56
55
|
cur_rec.Time, cur_rec.Disk)
|
@@ -58,13 +57,14 @@ func showDiskStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.Sta
|
|
58
57
|
return err
|
59
58
|
}
|
60
59
|
|
61
|
-
|
62
|
-
|
60
|
+
printer.PutKey("disk")
|
61
|
+
|
62
|
+
dusage.WriteJsonTo(printer)
|
63
63
|
|
64
64
|
return nil
|
65
65
|
}
|
66
66
|
|
67
|
-
func showNetStat(
|
67
|
+
func showNetStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
|
68
68
|
dusage, err := ss.GetNetUsage(
|
69
69
|
prev_rec.Time, prev_rec.Net,
|
70
70
|
cur_rec.Time, cur_rec.Net,
|
@@ -73,52 +73,96 @@ func showNetStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.Stat
|
|
73
73
|
return err
|
74
74
|
}
|
75
75
|
|
76
|
-
|
77
|
-
|
76
|
+
printer.PutKey("net")
|
77
|
+
|
78
|
+
dusage.WriteJsonTo(printer)
|
79
|
+
|
80
|
+
return nil
|
81
|
+
}
|
82
|
+
|
83
|
+
func showMemStat(printer *projson.JsonPrinter, cur_rec *ss.StatRecord) error {
|
84
|
+
musage, err := ss.GetMemUsage(cur_rec.Mem)
|
85
|
+
if err != nil {
|
86
|
+
return err
|
87
|
+
}
|
88
|
+
|
89
|
+
printer.PutKey("mem")
|
90
|
+
|
91
|
+
musage.WriteJsonTo(printer)
|
78
92
|
|
79
93
|
return nil
|
80
94
|
}
|
81
95
|
|
82
|
-
func showStat(
|
83
|
-
|
96
|
+
func showStat(printer *projson.JsonPrinter, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
|
97
|
+
printer.Reset()
|
98
|
+
if option.pretty {
|
99
|
+
printer.SetStyle(projson.SmartStyle)
|
100
|
+
}
|
101
|
+
if option.color {
|
102
|
+
printer.SetColor(true)
|
103
|
+
}
|
104
|
+
printer.BeginObject()
|
105
|
+
printer.PutKey("time")
|
106
|
+
printer.PutFloatFmt(float64(cur_rec.Time.UnixNano())/1e9, "%.3f")
|
107
|
+
printer.PutKey("elapsed_time")
|
108
|
+
printer.PutFloatFmt((float64(cur_rec.Time.UnixNano())-float64(init_rec.Time.UnixNano()))/1e9,
|
109
|
+
"%.3f")
|
110
|
+
|
84
111
|
if cur_rec.Cpu != nil {
|
85
|
-
err := showCpuStat(
|
112
|
+
err := showCpuStat(printer, prev_rec, cur_rec)
|
86
113
|
if err != nil {
|
87
114
|
return err
|
88
115
|
}
|
89
116
|
}
|
90
117
|
if cur_rec.Interrupt != nil {
|
91
|
-
err := showInterruptStat(
|
118
|
+
err := showInterruptStat(printer, prev_rec, cur_rec)
|
92
119
|
if err != nil {
|
93
120
|
return err
|
94
121
|
}
|
95
122
|
}
|
96
123
|
if cur_rec.Disk != nil {
|
97
|
-
err := showDiskStat(
|
124
|
+
err := showDiskStat(printer, prev_rec, cur_rec)
|
98
125
|
if err != nil {
|
99
126
|
return err
|
100
127
|
}
|
101
128
|
}
|
102
129
|
if cur_rec.Net != nil {
|
103
|
-
err := showNetStat(
|
130
|
+
err := showNetStat(printer, prev_rec, cur_rec)
|
131
|
+
if err != nil {
|
132
|
+
return err
|
133
|
+
}
|
134
|
+
}
|
135
|
+
if cur_rec.Mem != nil {
|
136
|
+
err := showMemStat(printer, cur_rec)
|
104
137
|
if err != nil {
|
105
138
|
return err
|
106
139
|
}
|
107
140
|
}
|
108
|
-
|
141
|
+
|
142
|
+
printer.FinishObject()
|
109
143
|
|
110
144
|
return nil
|
111
145
|
}
|
112
146
|
|
147
|
+
func parseArgs() {
|
148
|
+
flag.BoolVar(&option.color, "color", false, "Use colored JSON output")
|
149
|
+
flag.BoolVar(&option.pretty, "pretty", false, "Use human readable JSON output")
|
150
|
+
|
151
|
+
flag.Parse()
|
152
|
+
|
153
|
+
option.logfile = flag.Arg(0)
|
154
|
+
}
|
155
|
+
|
113
156
|
func main() {
|
114
|
-
args := os.Args
|
115
157
|
var in *os.File
|
116
158
|
var out *bufio.Writer
|
117
159
|
|
118
|
-
|
160
|
+
parseArgs()
|
161
|
+
|
162
|
+
if option.logfile == "" {
|
119
163
|
in = os.Stdin
|
120
164
|
} else {
|
121
|
-
f, err := os.Open(
|
165
|
+
f, err := os.Open(option.logfile)
|
122
166
|
if err != nil {
|
123
167
|
panic(err)
|
124
168
|
}
|
@@ -159,9 +203,10 @@ func main() {
|
|
159
203
|
} else if err != nil {
|
160
204
|
panic(err)
|
161
205
|
}
|
206
|
+
init_rec = records[curr]
|
162
207
|
curr ^= 1
|
163
208
|
|
164
|
-
|
209
|
+
printer := projson.NewPrinter()
|
165
210
|
for {
|
166
211
|
prev_rec := &records[curr^1]
|
167
212
|
cur_rec := &records[curr]
|
@@ -173,21 +218,26 @@ func main() {
|
|
173
218
|
panic(err)
|
174
219
|
}
|
175
220
|
|
176
|
-
err = showStat(
|
221
|
+
err = showStat(printer, prev_rec, cur_rec)
|
177
222
|
if err != nil {
|
178
|
-
|
223
|
+
printer.Reset()
|
179
224
|
fmt.Fprintln(os.Stderr, "skip by err")
|
180
225
|
continue
|
181
226
|
}
|
182
227
|
|
183
|
-
|
228
|
+
if str, err := printer.String(); err != nil {
|
229
|
+
fmt.Println("error", err)
|
230
|
+
fmt.Println(str)
|
231
|
+
} else {
|
232
|
+
_, err = out.WriteString(str + "\n")
|
233
|
+
}
|
184
234
|
err = out.Flush()
|
185
235
|
if err != nil {
|
186
236
|
// stdout is closed
|
187
237
|
break
|
188
238
|
}
|
189
239
|
|
190
|
-
|
240
|
+
printer.Reset()
|
191
241
|
|
192
242
|
curr ^= 1
|
193
243
|
}
|