perfmonger 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6c4a036c08d2f75fc25b25da1b773e025461880
4
- data.tar.gz: 87182b819268cdcd289ea1cfb89f8672cc307947
3
+ metadata.gz: 72618bf530f76c6135a455979b3a1c19ae3cda6d
4
+ data.tar.gz: af7dc56800edacccc3ee3821c011694a1f801bb3
5
5
  SHA512:
6
- metadata.gz: dcb1dd5f6086bff622f66dc7eb15a835604d0ce63fb2ea7b3d6ab022d3b5724384ca54ec38525c31984bc06dc08c87ca89cb21da7a62696bfaf665df6474d8a8
7
- data.tar.gz: cb33cd2fe403d279687a6ad680fbda8af96c778b65b485f6f4b6024eac8e80c8fc6efd79e4e225f1a02fcbfa2f79cfe5061857716ff62fc3b7c4a1a828ca2568
6
+ metadata.gz: 0beb12d9c14f4749076dcc27378bd9835f5447687e22ba7e0905dea390fc48b2177a7470204ebbbbf1284adf7a0207b02dd04573897687faa2f0ba52b0f923cb
7
+ data.tar.gz: 1a3d334f6c02ee779bd498004f09f4f92ff217f7231adea71aee3c42c01e667939547e74c0c0acd33b29c9b5ddf60d0f9fa6f9857032465c6e71c337df15833d
data/NEWS CHANGED
@@ -1,3 +1,29 @@
1
+ ## 2017-09-08: PerfMonger 0.10.1
2
+ * Yanked wrongly shipped v0.10.0 and pushed up-to-date code
3
+
4
+ ## 2017-06-19: PerfMonger 0.10.0
5
+ * New features
6
+ * [record] subcommand:
7
+ * Record /proc/interrupts information (experimental)
8
+ * Support gzipped output format
9
+ * Enabled by default
10
+ * Disabled with --no-gzip option
11
+ * [play] subcommand:
12
+ * Play /proc/interrupts information by cpu cores (experimental)
13
+ * Support gzipped input
14
+ * [summary] subcommand:
15
+ * Summarize /proc/interrupts information (experimental, currently outputs only in JSON mode)
16
+ * Support gzipped input
17
+ * [fingerprint] subcommand:
18
+ * Additionally log biosdecode and nvme info
19
+ * Improved shell completion
20
+ * Bug fixes
21
+ * [record] subcommand:
22
+ * Get CPU count by nproc(1) in linux subsystem
23
+ * Create a session only in background mode, and an existing session do not prevent launching perfmonger-record in foreground mode
24
+ * [fingerprint] subcommand:
25
+ * Surpress accessing non-readable sysfs files
26
+
1
27
  ## 2016-12-12: PerfMonger 0.9.0
2
28
  * New features
3
29
  * [init-shell] subcommand: Added for loading shell completion function from rcfile
@@ -7,7 +33,8 @@
7
33
  * log LVM, fdisk, and lsblk info
8
34
  * [plot]
9
35
  * Fast plot data formatting with new core implementation
10
- * Improved shell completion
36
+ * Add --disk-only, --disk-read-only, --disk-write-only to filter disks for plot
37
+ * Add --plot-iops-max to limit Y-axis range
11
38
 
12
39
  ## 2016-11-22: PerfMonger 0.8.2
13
40
  * Bug fixes
@@ -172,4 +199,4 @@ PerfMonger is available on yum repository from this release.
172
199
  ## 2011-12-09: PerfMonger 0.1.0 released
173
200
 
174
201
  * New features
175
- * I/O performance monitoring
202
+ * I/O performance monitoring
@@ -1,59 +1,60 @@
1
1
  # DO NOT EDIT MANUALLY
2
2
  # generated by build.sh
3
3
 
4
- GOSRC := 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
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
5
6
 
6
7
  .PHONY: all build clean
7
8
 
8
9
  all: build
9
10
 
10
11
 
11
- ../lib/exec/perfmonger-recorder_linux_386: perfmonger-recorder.go $(GOSRC)
12
- go build -o $@ perfmonger-recorder.go
12
+ ../lib/exec/perfmonger-recorder_linux_386: perfmonger-recorder.go $(GO_DEPS)
13
+ go build -o $@ perfmonger-recorder.go $(GO_SRC)
13
14
 
14
15
 
15
- ../lib/exec/perfmonger-player_linux_386: perfmonger-player.go $(GOSRC)
16
- go build -o $@ perfmonger-player.go
16
+ ../lib/exec/perfmonger-player_linux_386: perfmonger-player.go $(GO_DEPS)
17
+ go build -o $@ perfmonger-player.go $(GO_SRC)
17
18
 
18
19
 
19
- ../lib/exec/perfmonger-summarizer_linux_386: perfmonger-summarizer.go $(GOSRC)
20
- go build -o $@ perfmonger-summarizer.go
20
+ ../lib/exec/perfmonger-summarizer_linux_386: perfmonger-summarizer.go $(GO_DEPS)
21
+ go build -o $@ perfmonger-summarizer.go $(GO_SRC)
21
22
 
22
23
 
23
- ../lib/exec/perfmonger-plot-formatter_linux_386: perfmonger-plot-formatter.go $(GOSRC)
24
- go build -o $@ perfmonger-plot-formatter.go
24
+ ../lib/exec/perfmonger-plot-formatter_linux_386: perfmonger-plot-formatter.go $(GO_DEPS)
25
+ go build -o $@ perfmonger-plot-formatter.go $(GO_SRC)
25
26
 
26
27
 
27
- ../lib/exec/perfmonger-recorder_linux_amd64: perfmonger-recorder.go $(GOSRC)
28
- go build -o $@ perfmonger-recorder.go
28
+ ../lib/exec/perfmonger-recorder_linux_amd64: perfmonger-recorder.go $(GO_DEPS)
29
+ go build -o $@ perfmonger-recorder.go $(GO_SRC)
29
30
 
30
31
 
31
- ../lib/exec/perfmonger-player_linux_amd64: perfmonger-player.go $(GOSRC)
32
- go build -o $@ perfmonger-player.go
32
+ ../lib/exec/perfmonger-player_linux_amd64: perfmonger-player.go $(GO_DEPS)
33
+ go build -o $@ perfmonger-player.go $(GO_SRC)
33
34
 
34
35
 
35
- ../lib/exec/perfmonger-summarizer_linux_amd64: perfmonger-summarizer.go $(GOSRC)
36
- go build -o $@ perfmonger-summarizer.go
36
+ ../lib/exec/perfmonger-summarizer_linux_amd64: perfmonger-summarizer.go $(GO_DEPS)
37
+ go build -o $@ perfmonger-summarizer.go $(GO_SRC)
37
38
 
38
39
 
39
- ../lib/exec/perfmonger-plot-formatter_linux_amd64: perfmonger-plot-formatter.go $(GOSRC)
40
- go build -o $@ perfmonger-plot-formatter.go
40
+ ../lib/exec/perfmonger-plot-formatter_linux_amd64: perfmonger-plot-formatter.go $(GO_DEPS)
41
+ go build -o $@ perfmonger-plot-formatter.go $(GO_SRC)
41
42
 
42
43
 
43
- ../lib/exec/perfmonger-recorder_darwin_amd64: perfmonger-recorder.go $(GOSRC)
44
- go build -o $@ perfmonger-recorder.go
44
+ ../lib/exec/perfmonger-recorder_darwin_amd64: perfmonger-recorder.go $(GO_DEPS)
45
+ go build -o $@ perfmonger-recorder.go $(GO_SRC)
45
46
 
46
47
 
47
- ../lib/exec/perfmonger-player_darwin_amd64: perfmonger-player.go $(GOSRC)
48
- go build -o $@ perfmonger-player.go
48
+ ../lib/exec/perfmonger-player_darwin_amd64: perfmonger-player.go $(GO_DEPS)
49
+ go build -o $@ perfmonger-player.go $(GO_SRC)
49
50
 
50
51
 
51
- ../lib/exec/perfmonger-summarizer_darwin_amd64: perfmonger-summarizer.go $(GOSRC)
52
- go build -o $@ perfmonger-summarizer.go
52
+ ../lib/exec/perfmonger-summarizer_darwin_amd64: perfmonger-summarizer.go $(GO_DEPS)
53
+ go build -o $@ perfmonger-summarizer.go $(GO_SRC)
53
54
 
54
55
 
55
- ../lib/exec/perfmonger-plot-formatter_darwin_amd64: perfmonger-plot-formatter.go $(GOSRC)
56
- go build -o $@ perfmonger-plot-formatter.go
56
+ ../lib/exec/perfmonger-plot-formatter_darwin_amd64: perfmonger-plot-formatter.go $(GO_DEPS)
57
+ go build -o $@ perfmonger-plot-formatter.go $(GO_SRC)
57
58
 
58
59
 
59
60
  build: ../lib/exec/perfmonger-recorder_linux_386 ../lib/exec/perfmonger-player_linux_386 ../lib/exec/perfmonger-summarizer_linux_386 ../lib/exec/perfmonger-plot-formatter_linux_386 ../lib/exec/perfmonger-recorder_linux_amd64 ../lib/exec/perfmonger-player_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-summarizer_darwin_amd64 ../lib/exec/perfmonger-plot-formatter_darwin_amd64
@@ -33,13 +33,16 @@ fi
33
33
 
34
34
  set -e
35
35
 
36
- GO_FILES=$(ls subsystem/*.go)
36
+ GO_DEPS=$(ls subsystem/*.go; ls utils.go)
37
37
 
38
- cat <<EOF > Makefile
38
+ makefile=`mktemp`
39
+
40
+ cat <<EOF > $makefile
39
41
  # DO NOT EDIT MANUALLY
40
42
  # generated by build.sh
41
43
 
42
- GOSRC := $(echo ${GO_FILES})
44
+ GO_DEPS := $(echo ${GO_DEPS})
45
+ GO_SRC := utils.go
43
46
 
44
47
  .PHONY: all build clean
45
48
 
@@ -51,30 +54,30 @@ TARGETS=()
51
54
 
52
55
  for idx in $(seq 0 $((${#TARGET[@]}-1))); do
53
56
  set -- ${TARGET[$idx]}
54
- export GOOS=$1
55
- export GOARCH=$2
57
+ export var_GOOS=$1
58
+ export var_GOARCH=$2
56
59
 
57
60
  for subcmd in recorder player summarizer plot-formatter; do
58
- TARGETS+=(../lib/exec/perfmonger-${subcmd}_${GOOS}_${GOARCH})
61
+ TARGETS+=(../lib/exec/perfmonger-${subcmd}_${var_GOOS}_${var_GOARCH})
59
62
 
60
- cat <<EOF >> Makefile
63
+ cat <<EOF >> $makefile
61
64
 
62
- ../lib/exec/perfmonger-${subcmd}_${GOOS}_${GOARCH}: perfmonger-${subcmd}.go \$(GOSRC)
63
- go build -o \$@ perfmonger-$subcmd.go
65
+ ../lib/exec/perfmonger-${subcmd}_${var_GOOS}_${var_GOARCH}: perfmonger-${subcmd}.go \$(GO_DEPS)
66
+ go build -o \$@ perfmonger-$subcmd.go \$(GO_SRC)
64
67
 
65
68
  EOF
66
69
  done
67
70
 
68
- # go build -o ../lib/exec/perfmonger-recorder_${GOOS}_${GOARCH} \
71
+ # go build -o ../lib/exec/perfmonger-recorder_${var_GOOS}_${var_GOARCH} \
69
72
  # perfmonger-recorder.go &
70
- # go build -o ../lib/exec/perfmonger-player_${GOOS}_${GOARCH} \
73
+ # go build -o ../lib/exec/perfmonger-player_${var_GOOS}_${var_GOARCH} \
71
74
  # perfmonger-player.go &
72
- # go build -o ../lib/exec/perfmonger-summarizer_${GOOS}_${GOARCH} \
75
+ # go build -o ../lib/exec/perfmonger-summarizer_${var_GOOS}_${var_GOARCH} \
73
76
  # perfmonger-summarizer.go &
74
77
 
75
78
  done
76
79
 
77
- cat <<EOF >> Makefile
80
+ cat <<EOF >> $makefile
78
81
 
79
82
  build: ${TARGETS[*]}
80
83
 
@@ -82,3 +85,7 @@ clean:
82
85
  rm -f ${TARGETS[*]}
83
86
 
84
87
  EOF
88
+
89
+ mv $makefile ./Makefile
90
+
91
+ make
@@ -24,6 +24,32 @@ func showCpuStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.Stat
24
24
  return nil
25
25
  }
26
26
 
27
+ func showInterruptStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
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
+
40
+ intr_usage, err := ss.GetInterruptUsage(
41
+ prev_rec.Time, prev_rec.Interrupt,
42
+ cur_rec.Time, cur_rec.Interrupt)
43
+ if err != nil {
44
+ return err
45
+ }
46
+
47
+ buffer.WriteString(`,"intr":`)
48
+ intr_usage.WriteJsonTo(buffer)
49
+
50
+ return nil
51
+ }
52
+
27
53
  func showDiskStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.StatRecord) error {
28
54
  dusage, err := ss.GetDiskUsage(
29
55
  prev_rec.Time, prev_rec.Disk,
@@ -61,6 +87,12 @@ func showStat(buffer *bytes.Buffer, prev_rec *ss.StatRecord, cur_rec *ss.StatRec
61
87
  return err
62
88
  }
63
89
  }
90
+ if cur_rec.Interrupt != nil {
91
+ err := showInterruptStat(buffer, prev_rec, cur_rec)
92
+ if err != nil {
93
+ return err
94
+ }
95
+ }
64
96
  if cur_rec.Disk != nil {
65
97
  err := showDiskStat(buffer, prev_rec, cur_rec)
66
98
  if err != nil {
@@ -93,11 +125,11 @@ func main() {
93
125
  in = f
94
126
  defer f.Close()
95
127
  }
128
+ input_reader := newPerfmongerLogReader(in)
129
+ dec := gob.NewDecoder(input_reader)
96
130
 
97
131
  out = bufio.NewWriter(os.Stdout)
98
132
 
99
- dec := gob.NewDecoder(in)
100
-
101
133
  var cheader ss.CommonHeader
102
134
  var pheader ss.PlatformHeader
103
135
  var records = make([]ss.StatRecord, 2)
@@ -123,16 +123,14 @@ func printCoreUsage(writer *bufio.Writer, elapsed_time float64, coreusage *ss.Cp
123
123
  func main() {
124
124
  opt := parseArgs()
125
125
 
126
- var in *os.File
127
-
128
126
  f, err := os.Open(opt.PerfmongerFile)
129
127
  if err != nil {
130
128
  panic(err)
131
129
  }
132
- in = f
133
130
  defer f.Close()
134
131
 
135
- dec := gob.NewDecoder(bufio.NewReader(in))
132
+ input_reader := newPerfmongerLogReader(f)
133
+ dec := gob.NewDecoder(input_reader)
136
134
 
137
135
  var cheader ss.CommonHeader
138
136
  var pheader ss.PlatformHeader
@@ -4,6 +4,7 @@ package main
4
4
 
5
5
  import (
6
6
  "bufio"
7
+ "compress/gzip"
7
8
  "encoding/gob"
8
9
  "flag"
9
10
  "fmt"
@@ -32,6 +33,7 @@ type RecorderOption struct {
32
33
  devsParts []string
33
34
  output string
34
35
  no_cpu bool
36
+ no_intr bool
35
37
  no_disk bool
36
38
  no_net bool
37
39
  debug bool
@@ -39,6 +41,8 @@ type RecorderOption struct {
39
41
  player_bin string
40
42
  disks string
41
43
  targetDisks *map[string]bool
44
+ background bool
45
+ gzip bool
42
46
  }
43
47
 
44
48
  var option RecorderOption
@@ -64,6 +68,8 @@ func parseArgs() {
64
68
  "-", "Output file name")
65
69
  flag.BoolVar(&option.no_cpu, "no-cpu",
66
70
  false, "Do not record CPU usage")
71
+ flag.BoolVar(&option.no_intr, "no-intr",
72
+ false, "Do not record interrupts count")
67
73
  flag.BoolVar(&option.no_disk, "no-disk",
68
74
  false, "Do not record disk usage")
69
75
  flag.BoolVar(&option.no_net, "no-net",
@@ -72,10 +78,14 @@ func parseArgs() {
72
78
  false, "Enable debug mode")
73
79
  flag.BoolVar(&option.listDevices, "list-devices",
74
80
  false, "List devices and exits")
81
+ flag.BoolVar(&option.background, "background",
82
+ false, "Run in background mode")
75
83
  flag.StringVar(&option.disks, "disks",
76
84
  "", "Disk devices to be monitored")
77
85
  flag.StringVar(&option.player_bin, "player-bin",
78
86
  "", "Run perfmonger-player to show JSON output")
87
+ flag.BoolVar(&option.gzip, "gzip",
88
+ false, "Save a logfile in gzipped format")
79
89
 
80
90
  flag.Parse()
81
91
 
@@ -116,55 +126,65 @@ func main() {
116
126
  var out *bufio.Writer
117
127
  var err error
118
128
 
119
- // Find existing session, or create new one
120
- user, err := user.Current()
121
- if err != nil {
122
- panic(err)
129
+ // Need to check '-background' before parsing args
130
+ is_background := false
131
+ for _, arg := range os.Args {
132
+ if arg == "-background" {
133
+ is_background = true
134
+ }
123
135
  }
124
- session_file := path.Join(os.TempDir(),
125
- fmt.Sprintf("perfmonger-%s-session.pid", user.Username))
126
136
 
127
- lockfile := path.Join(os.TempDir(), ".perfmonger.lock")
137
+ if is_background {
138
+ // Find existing session, or create new one
139
+ user, err := user.Current()
140
+ if err != nil {
141
+ panic(err)
142
+ }
143
+ session_file := path.Join(os.TempDir(),
144
+ fmt.Sprintf("perfmonger-%s-session.pid", user.Username))
128
145
 
129
- // make lock file if not exists
130
- session_exists := false
146
+ lockfile := path.Join(os.TempDir(), ".perfmonger.lock")
131
147
 
132
- if _, err := os.Stat(lockfile); err != nil {
133
- ioutil.WriteFile(lockfile, []byte(""), 0644)
134
- }
135
- fd, _ := syscall.Open(lockfile, syscall.O_RDONLY, 0000)
136
- syscall.Flock(fd, syscall.LOCK_EX)
148
+ // make lock file if not exists
149
+ session_exists := false
137
150
 
138
- if _, err := os.Stat(session_file); err == nil {
139
- pidstr, err := ioutil.ReadFile(session_file)
140
- pid, err := strconv.Atoi(string(pidstr))
141
- if err != nil {
142
- goto MakeNewSession
151
+ if _, err := os.Stat(lockfile); err != nil {
152
+ ioutil.WriteFile(lockfile, []byte(""), 0644)
143
153
  }
154
+ fd, _ := syscall.Open(lockfile, syscall.O_RDONLY, 0000)
155
+ syscall.Flock(fd, syscall.LOCK_EX)
156
+
157
+ if _, err := os.Stat(session_file); err == nil {
158
+ pidstr, err := ioutil.ReadFile(session_file)
159
+ pid, err := strconv.Atoi(string(pidstr))
160
+ if err != nil {
161
+ goto MakeNewSession
162
+ }
144
163
 
145
- // check if PID in session file is valid
146
- proc, err := os.FindProcess(pid)
147
- err = proc.Signal(syscall.Signal(0))
164
+ // check if PID in session file is valid
165
+ proc, err := os.FindProcess(pid)
166
+ err = proc.Signal(syscall.Signal(0))
148
167
 
149
- if err == nil {
150
- session_exists = true
151
- goto Unlock
168
+ if err == nil {
169
+ session_exists = true
170
+ goto Unlock
171
+ }
152
172
  }
153
- }
154
- MakeNewSession:
155
- err = ioutil.WriteFile(session_file, []byte(strconv.Itoa(os.Getpid())), 0644)
156
- if err != nil {
157
- panic(err)
158
- }
159
- defer os.Remove(session_file)
173
+ MakeNewSession:
174
+ err = ioutil.WriteFile(session_file, []byte(strconv.Itoa(os.Getpid())), 0644)
175
+ if err != nil {
176
+ panic(err)
177
+ }
178
+ defer os.Remove(session_file)
160
179
 
161
- Unlock:
162
- syscall.Flock(fd, syscall.LOCK_UN)
163
- syscall.Close(fd)
180
+ Unlock:
181
+ syscall.Flock(fd, syscall.LOCK_UN)
182
+ syscall.Close(fd)
164
183
 
165
- if session_exists {
166
- fmt.Fprintf(os.Stderr, "[ERROR] another perfmonger is already running.\n")
167
- return
184
+ if session_exists {
185
+ fmt.Fprintf(os.Stderr, "[ERROR] another perfmonger is already running in background mode\n")
186
+ return
187
+ }
168
188
  }
169
189
 
170
190
  parseArgs()
@@ -243,7 +263,14 @@ Unlock:
243
263
  if player_stdin != nil {
244
264
  out = bufio.NewWriter(io.MultiWriter(file, player_stdin))
245
265
  } else {
246
- out = bufio.NewWriter(file)
266
+ if option.gzip {
267
+ gzwriter := gzip.NewWriter(file)
268
+ defer gzwriter.Close()
269
+
270
+ out = bufio.NewWriter(gzwriter)
271
+ } else {
272
+ out = bufio.NewWriter(file)
273
+ }
247
274
  }
248
275
  }
249
276
 
@@ -290,6 +317,9 @@ Unlock:
290
317
  if !option.no_cpu {
291
318
  ss.ReadCpuStat(record)
292
319
  }
320
+ if !option.no_intr {
321
+ ss.ReadInterruptStat(record)
322
+ }
293
323
  if !option.no_disk {
294
324
  ss.ReadDiskStats(record, option.targetDisks)
295
325
  }