sunburst 0.3.0 → 0.4.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/exe/sunburst +32 -7
- data/ext/stats/stats.c +13 -5
- data/lib/sunburst/sunburst.rb +77 -2
- data/lib/sunburst/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 327a6ef07e1800b7edc89af0dc6ad0696ff2aef5656c9b908b0bb274c344638b
|
4
|
+
data.tar.gz: fe11501674b83a4dc0372585ad9f0e3dcf2ab834c781ea30d81936d958f026fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12a106e06a0f15348d9c71db9ffcc6dd56a71541bf316a1de6e8d3bdf842966b12a437d21777705e3e7f707dba6397f54b86ca3d79a3ca81b76f4570d091d2f0
|
7
|
+
data.tar.gz: 4b840b941a94bb1be01d351e7e61e1130a1e8c59c377fad3475740a9229541ca8dd149c6b970a8aeefe53dbd96cfd1b781cb634b85cc05debf108a71cf68ff9e
|
data/exe/sunburst
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Frozen_String_Literal: true
|
3
3
|
|
4
|
-
$-v =
|
4
|
+
$-v = true
|
5
5
|
STDOUT.sync = STDIN.sync = true
|
6
6
|
require 'sunburst'
|
7
7
|
|
@@ -82,22 +82,24 @@ begin
|
|
82
82
|
|
83
83
|
data = if progress
|
84
84
|
if human_readable
|
85
|
-
Sunburst.measure(command: command, time: time, sleep_time: 0.0001) { |exec_t, cpu_t, mem, threads, state|
|
86
|
-
print "\e[2K:: "\
|
85
|
+
Sunburst.measure(command: command, time: time, sleep_time: 0.0001) { |exec_t, cpu_t, mem, threads, state, cpu_u|
|
86
|
+
print "\e[2K\r:: "\
|
87
87
|
"Exec T: #{"%05.2f" % exec_t}s | "\
|
88
88
|
"CPU T: #{"%05.2f" % cpu_t}s | "\
|
89
89
|
"Mem: #{convert_bytes(mem)} | "\
|
90
90
|
"Threads: #{threads} | "\
|
91
|
-
"State: #{state}\
|
91
|
+
"State: #{state} | "\
|
92
|
+
"CPU U: #{cpu_u}\e[s\r\e[u"
|
92
93
|
}
|
93
94
|
else
|
94
|
-
Sunburst.measure(command: command, time: time, sleep_time: 0.0001) { |exec_t, cpu_t, mem, threads, state|
|
95
|
-
print "\e[2K:: "\
|
95
|
+
Sunburst.measure(command: command, time: time, sleep_time: 0.0001) { |exec_t, cpu_t, mem, threads, state, cpu_u|
|
96
|
+
print "\e[2K\r:: "\
|
96
97
|
"Exec T: #{"%05.2f" % exec_t} | "\
|
97
98
|
"CPU T: #{"%05.2f" % cpu_t} | "\
|
98
99
|
"Mem: #{"%2d" % mem} | "\
|
99
100
|
"Threads: #{threads} | "\
|
100
|
-
"State: #{state}\
|
101
|
+
"State: #{state} | "\
|
102
|
+
"CPU U: #{cpu_u}\e[s\r\e[u"
|
101
103
|
}
|
102
104
|
end
|
103
105
|
else
|
@@ -152,6 +154,13 @@ begin
|
|
152
154
|
puts ":: The memory Usage Can't be Logged."
|
153
155
|
end
|
154
156
|
|
157
|
+
avg_mem = data[:avg_mem]
|
158
|
+
if avg_mem
|
159
|
+
puts ":: Avg. Memory Usage: #{style}#{convert_bytes(avg_mem)}\e[0m (#{percent_mem.round(3)}% system mem)"
|
160
|
+
else
|
161
|
+
puts ":: The Average Memory Usage can't be Logged."
|
162
|
+
end
|
163
|
+
|
155
164
|
max_mem = data[:max_memory]
|
156
165
|
if max_mem
|
157
166
|
percent_mem = max_mem.*(100).fdiv(Sunburst.total_ram)
|
@@ -178,6 +187,20 @@ begin
|
|
178
187
|
puts ":: The max memory Usage can't be logged."
|
179
188
|
end
|
180
189
|
|
190
|
+
avg_cpu_usage = data[:avg_cpu_usage]
|
191
|
+
if avg_cpu_usage
|
192
|
+
puts ":: Avg. CPU Usage: #{style}#{avg_cpu_usage}\e[0m"
|
193
|
+
else
|
194
|
+
puts ":: The Avg. CPU Usage Can't be Logged"
|
195
|
+
end
|
196
|
+
|
197
|
+
max_cpu_usage = data[:max_cpu_usage]
|
198
|
+
if max_cpu_usage
|
199
|
+
puts ":: Max CPU Usage: #{style}#{max_cpu_usage}\e[0m"
|
200
|
+
else
|
201
|
+
puts ":: The Max CPU Usage Can't be Logged"
|
202
|
+
end
|
203
|
+
|
181
204
|
max_threads = data[:max_threads]
|
182
205
|
style = +"\e[1;"
|
183
206
|
style << if max_threads > 16
|
@@ -195,6 +218,8 @@ begin
|
|
195
218
|
rescue Errno::ENOENT
|
196
219
|
puts "sunburst: #{command}: command not found"
|
197
220
|
puts ?\n, ?- * Sunburst.win_width
|
221
|
+
rescue Interrupt
|
222
|
+
puts "\n\e[2KInterrupt Received"
|
198
223
|
rescue StandardError
|
199
224
|
puts $!.full_message
|
200
225
|
end
|
data/ext/stats/stats.c
CHANGED
@@ -44,28 +44,35 @@ VALUE ps_stat(volatile VALUE obj, volatile VALUE pid) {
|
|
44
44
|
int ppid, processor ;
|
45
45
|
long unsigned utime, stime ;
|
46
46
|
long num_threads ;
|
47
|
+
long long unsigned starttime ;
|
47
48
|
|
48
49
|
char status = fscanf(
|
49
50
|
f, "%*llu (%*[^)]%*[)] %1s "
|
50
51
|
"%d %*d %*d %*d %*d %*u "
|
51
52
|
"%*lu %*lu %*lu %*lu %lu %lu "
|
52
|
-
"%*ld %*ld %*ld %*ld %ld",
|
53
|
-
&state, &ppid, &utime, &stime, &num_threads
|
53
|
+
"%*ld %*ld %*ld %*ld %ld %*ld %ld",
|
54
|
+
&state, &ppid, &utime, &stime, &num_threads, &starttime
|
54
55
|
) ;
|
55
56
|
|
56
57
|
fclose(f) ;
|
57
58
|
|
58
|
-
if (status !=
|
59
|
+
if (status != 6) return rb_ary_new() ;
|
59
60
|
|
60
|
-
return rb_ary_new_from_args(
|
61
|
+
return rb_ary_new_from_args(6,
|
61
62
|
INT2NUM(ppid),
|
62
63
|
ULONG2NUM(utime),
|
63
64
|
ULONG2NUM(stime),
|
64
65
|
LONG2NUM(num_threads),
|
65
|
-
rb_str_new(state, 1)
|
66
|
+
rb_str_new(state, 1),
|
67
|
+
ULL2NUM(starttime)
|
66
68
|
) ;
|
67
69
|
}
|
68
70
|
|
71
|
+
VALUE nProcessors(volatile VALUE obj) {
|
72
|
+
int coreCount = sysconf(_SC_NPROCESSORS_CONF) ;
|
73
|
+
return (coreCount == -1) ? Qnil : INT2NUM(coreCount) ;
|
74
|
+
}
|
75
|
+
|
69
76
|
VALUE clock_monotonic(volatile VALUE obj) {
|
70
77
|
struct timespec tv ;
|
71
78
|
clock_gettime(CLOCK_MONOTONIC, &tv) ;
|
@@ -109,4 +116,5 @@ void Init_stats() {
|
|
109
116
|
rb_define_module_function(sunburst, "ps_stat", ps_stat, 1) ;
|
110
117
|
|
111
118
|
rb_define_module_function(sunburst, "total_ram", totalRAM, 0) ;
|
119
|
+
rb_define_module_function(sunburst, "nprocessors", nProcessors, 0) ;
|
112
120
|
}
|
data/lib/sunburst/sunburst.rb
CHANGED
@@ -10,13 +10,55 @@ module Sunburst
|
|
10
10
|
stats
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.calculate_cpu_usage(pid, sleep_time)
|
14
|
+
uptime_file = '/proc/uptime'.freeze
|
15
|
+
|
16
|
+
unless File.readable?(uptime_file)
|
17
|
+
sleep(sleep_time)
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
|
21
|
+
ticks = Sunburst::TICKS
|
22
|
+
stat = Sunburst.ps_stat(pid)
|
23
|
+
uptime = IO.read('/proc/uptime').to_f
|
24
|
+
|
25
|
+
if stat.empty?
|
26
|
+
sleep(sleep_time)
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
utime, stime, starttime = *stat.values_at(1, 2, 5).map(&:to_f)
|
31
|
+
uptime *= ticks
|
32
|
+
|
33
|
+
total_time = utime + stime
|
34
|
+
idle1 = uptime - starttime - total_time
|
35
|
+
|
36
|
+
sleep(sleep_time)
|
37
|
+
|
38
|
+
stat = Sunburst.ps_stat(pid)
|
39
|
+
uptime = IO.read('/proc/uptime').to_f
|
40
|
+
return nil if stat.empty?
|
41
|
+
|
42
|
+
utime2, stime2, starttime2 = *stat.values_at(1, 2, 5).map(&:to_f)
|
43
|
+
uptime *= ticks
|
44
|
+
|
45
|
+
total_time2 = utime2 + stime2
|
46
|
+
idle2 = uptime - starttime2 - total_time2
|
47
|
+
|
48
|
+
totald = idle2.+(total_time2).-(idle1 + total_time)
|
49
|
+
cpu_u = totald.-(idle2 - idle1).fdiv(totald).abs.*(100)./(Sunburst.nprocessors)
|
50
|
+
|
51
|
+
cpu_u > 100 ? 100.0 : cpu_u
|
52
|
+
end
|
53
|
+
|
13
54
|
def self.measure(command:, time: nil, sleep_time: 0.001)
|
14
55
|
progress = block_given?
|
15
56
|
|
16
57
|
r = {
|
17
58
|
execution_time: nil, cpu_time: nil,
|
18
59
|
memory: nil, max_threads: nil,
|
19
|
-
max_memory: nil, state: nil, last_state: nil
|
60
|
+
avg_mem: nil, max_memory: nil, state: nil, last_state: nil,
|
61
|
+
avg_cpu_usage: nil, max_cpu_usage: nil
|
20
62
|
}
|
21
63
|
|
22
64
|
IO.popen(command) { |x|
|
@@ -29,11 +71,36 @@ module Sunburst
|
|
29
71
|
Thread.new { print x.readpartial(4096) until x.eof? }
|
30
72
|
end
|
31
73
|
|
74
|
+
cpu_usage = 0
|
75
|
+
max_cpu_usage = 0
|
76
|
+
cpu_usage_sum = 0
|
77
|
+
cpu_usage_measure_count = 0
|
78
|
+
|
79
|
+
Thread.new {
|
80
|
+
while true
|
81
|
+
_cpu_usage = calculate_cpu_usage(pid, 0.25)
|
82
|
+
|
83
|
+
if _cpu_usage
|
84
|
+
cpu_usage = "%05.2f%%".freeze % _cpu_usage
|
85
|
+
cpu_usage_sum += _cpu_usage
|
86
|
+
cpu_usage_measure_count += 1
|
87
|
+
|
88
|
+
max_cpu_usage = _cpu_usage if _cpu_usage > max_cpu_usage
|
89
|
+
else
|
90
|
+
cpu_usage = ?X.freeze
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
}
|
95
|
+
|
32
96
|
last_mem = 0
|
33
97
|
max_threads = 0
|
34
98
|
max_mem = 0
|
35
99
|
last_state = nil
|
36
100
|
|
101
|
+
avg_mem = 0
|
102
|
+
mem_measure_count = 0
|
103
|
+
|
37
104
|
while true
|
38
105
|
_last_mem = Sunburst.get_mem(pid)
|
39
106
|
|
@@ -41,6 +108,9 @@ module Sunburst
|
|
41
108
|
last_mem = _last_mem
|
42
109
|
max_mem = last_mem if max_mem < _last_mem
|
43
110
|
|
111
|
+
avg_mem += _last_mem
|
112
|
+
mem_measure_count += 1
|
113
|
+
|
44
114
|
# Get stats
|
45
115
|
stats = get_stats(pid)
|
46
116
|
_threads = stats[3]
|
@@ -55,7 +125,8 @@ module Sunburst
|
|
55
125
|
stats[1].+(stats[2]).fdiv(Sunburst::TICKS),
|
56
126
|
_last_mem * Sunburst::PAGESIZE,
|
57
127
|
_threads,
|
58
|
-
last_state
|
128
|
+
last_state,
|
129
|
+
cpu_usage
|
59
130
|
)
|
60
131
|
end
|
61
132
|
|
@@ -84,10 +155,14 @@ module Sunburst
|
|
84
155
|
r[:max_threads] = max_threads unless max_threads == 0
|
85
156
|
r[:memory] = last_mem * Sunburst::PAGESIZE if last_mem > 0
|
86
157
|
r[:max_memory] = max_mem * Sunburst::PAGESIZE if last_mem > 0
|
158
|
+
r[:avg_mem] = (avg_mem * Sunburst::PAGESIZE) / mem_measure_count if mem_measure_count > 0
|
87
159
|
|
88
160
|
r[:execution_time] = time2.-(time1).truncate(5)
|
89
161
|
r[:state] = state
|
90
162
|
r[:last_state] = last_state
|
163
|
+
|
164
|
+
r[:avg_cpu_usage] = sprintf("%05.2f%%", cpu_usage_sum / cpu_usage_measure_count) if cpu_usage_measure_count > 0
|
165
|
+
r[:max_cpu_usage] = sprintf("%05.2f%%", max_cpu_usage) if max_cpu_usage > 0
|
91
166
|
}
|
92
167
|
|
93
168
|
r
|
data/lib/sunburst/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sunburst
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sourav Goswami
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Run a process for a given time, kill it with SIGKILL, report CPU time
|
14
14
|
and memory usage
|
@@ -47,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: '0'
|
49
49
|
requirements: []
|
50
|
-
rubygems_version: 3.2.
|
50
|
+
rubygems_version: 3.2.21
|
51
51
|
signing_key:
|
52
52
|
specification_version: 4
|
53
53
|
summary: Run a process for a given time, kill it with SIGKILL, report CPU time and
|