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