perfmonger 0.9.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
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
  }