cellumon 0.3.0 → 0.4.0

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