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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/cellumon.gemspec +1 -1
  3. data/lib/cellumon.rb +101 -54
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 393429643d51ab62509e289d26e26b6ff9525392
4
- data.tar.gz: 317bf1a9f1481c17ff687e0d3fabb08e6e3a2776
3
+ metadata.gz: f2e3b257f2c4f10d56674d661d5e534c572c6755
4
+ data.tar.gz: 3c533c0a6582739f4c50fe96bce8b477abf2549c
5
5
  SHA512:
6
- metadata.gz: 2e46df51abd66e48a5835ab8af203edf580f9a82a93f0bc857bc341dc113d24f21119aa942a76aa29510eb3ddb0e75f8a6dd585345674e7d42fce354e0bbf216
7
- data.tar.gz: 9703a1b0387a1a90ecf06175bdb691f2ddea703aa88aa22e02e54a655185283716224f8528f75e7b02bab76252fa0dcfe9128a79b5699597f32b37ffbdf1aef6
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.3.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!(name=:cellumon)
10
- Cellumon.supervise(as: name)
11
- Celluloid[:cellumon]
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: 1,
19
- memory_count: 13
23
+ thread_summary: 3,
24
+ memory_count: 13,
25
+ threads_and_memory: 45
20
26
  }
21
27
 
22
- def initialize(mark=false)
28
+ def initialize(options={})
23
29
  @semaphor = {}
24
30
  @status = {}
25
31
  @timers = {}
26
- @mark = mark
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 mark
31
- @mark ? "Cellumon > " : ""
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
- if ready? :memory_count
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
- if ready? :thread_survey
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
- if ready? :thread_summary
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
- if ready? :thread_report
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 console(message)
99
- puts "*, [#{Time.now.strftime('%FT%T.%L')}] #{mark}#{message}"
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 ready! monitor
105
- @semaphor[monitor].synchronize { @status[monitor] = :ready }
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 running! monitor
109
- @semaphor[monitor].synchronize { @status[monitor] = :running }
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 stopped! monitor
113
- @semaphor[monitor].synchronize { @status[monitor] = :stopped }
119
+ def debug(message)
120
+ console(message, level: :debug)
114
121
  end
115
122
 
116
- def ready? monitor
117
- @semaphor[monitor].synchronize { @status[monitor] == :ready }
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 output object
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.3.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-19 00:00:00.000000000 Z
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: