cellumon 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/cellumon.gemspec +1 -1
- data/lib/cellumon.rb +101 -54
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2e3b257f2c4f10d56674d661d5e534c572c6755
|
4
|
+
data.tar.gz: 3c533c0a6582739f4c50fe96bce8b477abf2549c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea2715476ada07a49f5448994981cd792c62df2bad7a053c22bbd37ab2cb90f5892eedda38b97ab9af600325d5d52dd8f5e6aafd71db5fe7c4a42fd5a940a9d8
|
7
|
+
data.tar.gz: 24b3c12802773a090a17f64e66736ea4732d1a2cb00bdcca7fdda983c1d558319049cd5e3669da65536756d4f545e211bef0bdf25e7d0f1c752f435bc0139127
|
data/cellumon.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "cellumon"
|
5
|
-
gem.version = "0.
|
5
|
+
gem.version = "0.4.0"
|
6
6
|
gem.platform = Gem::Platform::RUBY
|
7
7
|
gem.summary = "Monitor threads, processes, and states of Celluloid and its Actor System."
|
8
8
|
gem.description = "Thread summary and reporting actor, utility for finding leaks and monitoring."
|
data/lib/cellumon.rb
CHANGED
@@ -6,29 +6,47 @@ class Cellumon
|
|
6
6
|
include Celluloid
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def start!(
|
10
|
-
|
11
|
-
|
9
|
+
def start!(options={})
|
10
|
+
name = options.delete(:name) || :cellumon
|
11
|
+
unless options.fetch(:monitors, nil).is_a? Array
|
12
|
+
puts "Cellumon > No monitors specified"
|
13
|
+
return
|
14
|
+
end
|
15
|
+
Cellumon.supervise(as: name, args: [options])
|
16
|
+
Celluloid[name]
|
12
17
|
end
|
13
18
|
end
|
14
19
|
|
15
20
|
MONITORS = {
|
16
21
|
thread_survey: 30,
|
17
22
|
thread_report: 15,
|
18
|
-
thread_summary:
|
19
|
-
memory_count: 13
|
23
|
+
thread_summary: 3,
|
24
|
+
memory_count: 13,
|
25
|
+
threads_and_memory: 45
|
20
26
|
}
|
21
27
|
|
22
|
-
def initialize(
|
28
|
+
def initialize(options={})
|
23
29
|
@semaphor = {}
|
24
30
|
@status = {}
|
25
31
|
@timers = {}
|
26
|
-
@
|
32
|
+
@debug = options.fetch(:debug, false)
|
33
|
+
@logger = options.fetch(:logger, nil)
|
34
|
+
@mark = options.fetch(:mark, false)
|
27
35
|
@intervals = MONITORS.dup
|
36
|
+
@options = options
|
37
|
+
async.start
|
28
38
|
end
|
29
39
|
|
30
|
-
def
|
31
|
-
@
|
40
|
+
def start
|
41
|
+
if @options[:monitors].is_a?(Array)
|
42
|
+
debug("Monitors:") if @debug
|
43
|
+
@options[:monitors].each { |monitor|
|
44
|
+
debug("* #{monitor} every #{MONITORS[monitor]} seconds.") if @debug
|
45
|
+
send("start_#{monitor}!")
|
46
|
+
}
|
47
|
+
else
|
48
|
+
debug("No preconfigured monitors.") if @debug
|
49
|
+
end
|
32
50
|
end
|
33
51
|
|
34
52
|
MONITORS.each { |m,i|
|
@@ -50,74 +68,103 @@ class Cellumon
|
|
50
68
|
}
|
51
69
|
|
52
70
|
def memory_count!
|
53
|
-
|
54
|
-
total = `pmap #{Process.pid} | tail -1`[10,40].strip[0..-1]
|
55
|
-
console("Memory usage: #{memory(total)}")
|
56
|
-
ready! :memory_count
|
57
|
-
end
|
58
|
-
@timers[:memory_count] = after(@intervals[:memory_count]) { memory_count! }
|
59
|
-
end
|
60
|
-
|
61
|
-
def memory(total)
|
62
|
-
total = total.to_i
|
63
|
-
gb = (total / (1024 * 1024)).to_i
|
64
|
-
mb = total % gb
|
65
|
-
"#{'%0.2f' % "#{gb}.#{mb}"}gb" #de Very fuzzy math but fine for now.
|
71
|
+
trigger!(:memory_count) { console memory }
|
66
72
|
end
|
67
73
|
|
68
74
|
def thread_survey!
|
69
|
-
|
70
|
-
Celluloid.stack_summary
|
71
|
-
ready! :thread_survey
|
72
|
-
end
|
73
|
-
@timers[:thread_survey] = after(@intervals[:thread_survey]) { thread_survey! }
|
75
|
+
trigger!(:thread_survey) { Celluloid.stack_summary }
|
74
76
|
end
|
75
77
|
|
76
78
|
def thread_summary!
|
77
|
-
|
78
|
-
print " #{Thread.list.count} "
|
79
|
-
ready! :thread_summary
|
80
|
-
end
|
81
|
-
@timers[:thread_summary] = after(@intervals[:thread_summary]) { thread_summary! }
|
79
|
+
trigger!(:thread_summary) { print " #{Thread.list.count} " }
|
82
80
|
end
|
83
81
|
|
84
82
|
def thread_report!
|
85
|
-
|
86
|
-
threads = Thread.list.inject({}) { |l,t| l[t.object_id] = t.status; l }
|
87
|
-
r = threads.select { |id,status| status == 'run' }.count
|
88
|
-
s = threads.select { |id,status| status == 'sleep' }.count
|
89
|
-
a = threads.select { |id,status| status == 'aborting' }.count
|
90
|
-
nt = threads.select { |id,status| status === false }.count
|
91
|
-
te = threads.select { |id,status| status.nil? }.count
|
92
|
-
console "Threads #{threads.count}: #{r}r #{s}s #{a}a #{nt}nt #{te}te"
|
93
|
-
ready! :thread_report
|
94
|
-
end
|
95
|
-
@timers[:thread_report] = after(@intervals[:thread_report]) { thread_report! }
|
83
|
+
trigger!(:thread_report) { console threads }
|
96
84
|
end
|
97
85
|
|
98
|
-
def
|
99
|
-
|
86
|
+
def threads_and_memory!
|
87
|
+
trigger!(:threads_and_memory) { console "#{threads}; #{memory}" }
|
100
88
|
end
|
101
89
|
|
102
90
|
private
|
103
91
|
|
104
|
-
def
|
105
|
-
|
92
|
+
def threads
|
93
|
+
threads = Thread.list.inject({}) { |l,t| l[t.object_id] = t.status; l }
|
94
|
+
r = threads.select { |id,status| status == 'run' }.count
|
95
|
+
s = threads.select { |id,status| status == 'sleep' }.count
|
96
|
+
a = threads.select { |id,status| status == 'aborting' }.count
|
97
|
+
nt = threads.select { |id,status| status === false }.count
|
98
|
+
te = threads.select { |id,status| status.nil? }.count
|
99
|
+
"Threads #{threads.count}: #{r}r #{s}s #{a}a #{nt}nt #{te}te"
|
106
100
|
end
|
107
101
|
|
108
|
-
def
|
109
|
-
|
102
|
+
def memory
|
103
|
+
total = `pmap #{Process.pid} | tail -1`[10,40].strip[0..-1].to_i
|
104
|
+
gb = (total / (1024 * 1024)).to_i
|
105
|
+
mb = total % gb
|
106
|
+
"Memory: #{'%0.2f' % "#{gb}.#{mb}"}gb" #de Very fuzzy math but fine for now.
|
107
|
+
end
|
108
|
+
|
109
|
+
def console(message, options={})
|
110
|
+
if @logger
|
111
|
+
@logger.console(message, options.merge(reporter: "Cellumon"))
|
112
|
+
else
|
113
|
+
plain_output("#{mark}#{message}")
|
114
|
+
end
|
115
|
+
rescue
|
116
|
+
plain_output("#{mark}#{message}")
|
110
117
|
end
|
111
118
|
|
112
|
-
def
|
113
|
-
|
119
|
+
def debug(message)
|
120
|
+
console(message, level: :debug)
|
114
121
|
end
|
115
122
|
|
116
|
-
def
|
117
|
-
|
123
|
+
def exception(ex, message)
|
124
|
+
if @logger
|
125
|
+
@logger.exception(ex, message)
|
126
|
+
else
|
127
|
+
plain_output("(#{ex.class}) #{ex.message}: #{message}")
|
128
|
+
end
|
129
|
+
rescue
|
130
|
+
plain_output("(#{ex.class}) #{ex.message}: #{message}")
|
131
|
+
ensure
|
132
|
+
plain_output("(#{ex.class}) #{ex.message}: #{message}")
|
133
|
+
end
|
134
|
+
|
135
|
+
def trigger!(monitor)
|
136
|
+
puts "trigger: #{monitor}" if @debug
|
137
|
+
if ready?(monitor)
|
138
|
+
result = yield
|
139
|
+
ready! monitor
|
140
|
+
end
|
141
|
+
@timers[monitor].cancel rescue nil
|
142
|
+
@timers[monitor] = after(@intervals[monitor]) { send("#{monitor}!") }
|
143
|
+
result
|
144
|
+
rescue => ex
|
145
|
+
exception(ex, "Cellumon > Failure to trigger: #{monitor}")
|
146
|
+
end
|
147
|
+
|
148
|
+
def mark
|
149
|
+
@mark ? "Cellumon > " : ""
|
150
|
+
end
|
151
|
+
|
152
|
+
[:ready, :running, :stopped].each { |state|
|
153
|
+
define_method("#{state}!") { |monitor|
|
154
|
+
@semaphor[monitor].synchronize { @status[monitor] = state }
|
155
|
+
}
|
156
|
+
define_method("#{state}?") { |monitor|
|
157
|
+
@semaphor[monitor].synchronize { @status[monitor] == state }
|
158
|
+
}
|
159
|
+
}
|
160
|
+
|
161
|
+
def plain_output(message)
|
162
|
+
message = "*, [#{Time.now.strftime('%FT%T.%L')}] #{mark}#{message}"
|
163
|
+
STDERR.puts message
|
164
|
+
STDOUT.puts message
|
118
165
|
end
|
119
166
|
|
120
|
-
def
|
167
|
+
def pretty_output object
|
121
168
|
puts JSON.pretty_generate(object)
|
122
169
|
end
|
123
170
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cellumon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- digitalextremist //
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Thread summary and reporting actor, utility for finding leaks and monitoring.
|
14
14
|
email:
|