langrove 0.0.5.3 → 0.0.5.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,9 +3,18 @@ LanGrove
3
3
 
4
4
  [LanGrove](http://www.google.com/search?hl=en&safe=off&biw=1065&bih=884&tbm=isch&sa=1&q=mangrove&btnG=) levarages [EventMachine](http://eventmachine.rubyforge.org/EventMachine.html) and [DaemonKit](https://github.com/kennethkalmer/daemon-kit/) to provide a framework for quick to implement network aware systems by providing an easily configurable transport and session layer and exposing generic interfaces into the application layer.
5
5
 
6
- ### Getting started quickly with [Scaffold and Configuration](https://github.com/cluetechnologies/langrove-enterprise/tree/master/bin)
6
+ ### Getting started quickly with [Scaffold and Configuration](https://github.com/cluetechnologies/langrove/tree/master/bin)
7
+
8
+ ### Understanding the [Framework Components](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove)
9
+
10
+
11
+ Note to Developers
12
+ ------------------
13
+
14
+ * Uses [Guard](https://github.com/guard/guard/) to watch for changes in `lib` or `spec` directories
15
+ * Runs specs accordingly.
16
+ * `bundle exec guard`
7
17
 
8
- ### Understanding the [Framework Components](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove)
9
18
 
10
19
  Change Log
11
20
  ----------
@@ -13,22 +22,15 @@ Change Log
13
22
  ### 2012-08-08
14
23
 
15
24
  * v0.0.5.3
25
+ * Started on `Metrix` (introspection subsystem)
16
26
 
27
+ ### 2012-08-09
17
28
 
18
- Todo
19
- ----
20
-
21
- * Rename this to `langrove`
22
- * Rename the original to `langrove-enterprise`
23
- * Swing all document links
24
- * Publish this repo
25
- * Start on the Enterprise Extensions
26
-
29
+ * Create metrix daemon component sampler infrastructure
30
+ * v0.0.5.4
27
31
 
28
- Note to Developers
29
- ------------------
30
32
 
31
- * Uses [Guard](https://github.com/guard/guard/) to watch for changes in `lib` or `spec` directories
32
- * Runs specs accordingly.
33
- * `bundle exec guard`
33
+ TODO
34
+ ----
34
35
 
36
+ * Pass all config queries through single interface
data/langrove.gemspec CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_runtime_dependency 'awesome_print'
30
30
 
31
31
  spec.files = `git ls-files`.strip.split("\n")
32
+ spec.files.delete_if {|file| file[0] == '.' }
32
33
 
33
34
  end
34
35
 
@@ -1,11 +1,11 @@
1
1
  Foundation
2
2
  ==========
3
3
 
4
- ### [Langrove::Root::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/root)
4
+ ### [Langrove::Root::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/root)
5
5
 
6
6
  Provides the `Config` and `Logger`.
7
7
 
8
- ### [LanGrove::Daemon::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/daemon)
8
+ ### [LanGrove::Daemon::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/daemon)
9
9
 
10
10
  Defines the `Container` that houses the Primary Daemon Components
11
11
 
@@ -14,22 +14,22 @@ Primary Components
14
14
  ==================
15
15
 
16
16
 
17
- ### [LanGrove::Adaptor::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/adaptor)
17
+ ### [LanGrove::Adaptor::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/adaptor)
18
18
 
19
19
  Defines the `Object` to which remote processes attach.
20
20
 
21
21
 
22
- ### [LanGrove::Handler::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler)
22
+ ### [LanGrove::Handler::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler)
23
23
 
24
24
  Defines the `Object` that is spawned to handle each attached remote process.
25
25
 
26
26
 
27
- ### [LanGrove::Protocol::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/protocol)
27
+ ### [LanGrove::Protocol::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol)
28
28
 
29
29
  Defines the `Object` that encapsulates the method of communication.
30
30
 
31
31
 
32
- ### [LanGrove::Server::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/server)
32
+ ### [LanGrove::Server::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server)
33
33
 
34
34
  Defines the `Object` that houses the collection of all presently connected remote processes.
35
35
 
@@ -64,12 +64,12 @@ Secondary Components
64
64
  ====================
65
65
 
66
66
 
67
- ### [LanGrove::Behaviour::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour)
67
+ ### [LanGrove::Behaviour::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour)
68
68
 
69
69
  Defines a set of Behaviours that can be applied to Primary Daemon Components
70
70
 
71
71
 
72
- ### [LanGrove::Plugin::Base](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin)
72
+ ### [LanGrove::Plugin::Base](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin)
73
73
 
74
74
  Defines the `Interface Base` to implement Behaviour actions.
75
75
 
@@ -78,5 +78,5 @@ Defines the `Interface Base` to implement Behaviour actions.
78
78
  Tools and Things
79
79
  ================
80
80
 
81
- ### [LanGrove::Ext](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/ext)
81
+ ### [LanGrove::Ext](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/ext)
82
82
 
@@ -5,7 +5,7 @@
5
5
  LanGrove::Adaptor::Base
6
6
  ========================
7
7
 
8
- Defines the extendable `Interface` for spawning [Handler](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler)s into the [Server](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/server) process.
8
+ Defines the extendable `Interface` for spawning [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler)s into the [Server](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server) process.
9
9
 
10
10
 
11
11
  EventMachineAdaptor
@@ -15,20 +15,20 @@
15
15
  LanGrove::Behaviour::Base
16
16
  =========================
17
17
 
18
- Defines the interface between the Daemon's [Primary Components](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove#primary-components) and the [Plugins](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin) that perform the Behaviour specified actions upon them.
18
+ Defines the interface between the Daemon's [Primary Components](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove#primary-components) and the [Plugins](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin) that perform the Behaviour specified actions upon them.
19
19
 
20
20
  Behaviour Triggers
21
21
  ------------------
22
22
 
23
23
  Behaviours are assigned to action at configurable trigger points in each Daemon module's life cycle.
24
24
 
25
- ### [Server](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/server) Triggers
25
+ ### [Server](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server) Triggers
26
26
 
27
27
  * :server_start
28
28
  * :server_stop
29
29
  * :server_reload
30
30
 
31
- ### [Handler](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler) Triggers
31
+ ### [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler) Triggers
32
32
 
33
33
  * :handler_start
34
34
  * :handler_stop
@@ -42,11 +42,11 @@ Behaviours are assigned to action at configurable trigger points in each Daemon
42
42
  * :handler_after_receive
43
43
  * :handler_error
44
44
 
45
- ### [Adaptor](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/adaptor) Triggers
45
+ ### [Adaptor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/adaptor) Triggers
46
46
 
47
47
  * none
48
48
 
49
- ### [Protocol](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/protocol) Triggers
49
+ ### [Protocol](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol) Triggers
50
50
 
51
51
  * none
52
52
 
@@ -54,17 +54,17 @@ Behaviours are assigned to action at configurable trigger points in each Daemon
54
54
  Function
55
55
  --------
56
56
 
57
- * Behaviour triggers fire via the [Daemon Root](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/root) module.
57
+ * Behaviour triggers fire via the [Daemon Root](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/root) module.
58
58
  * The triggers are called by the Module undergoing the associated event.
59
59
  * The call carries reference to the Module
60
- * The listening behaviour passes the Module reference onward to the [Plugin](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin) configured to perform the action.
60
+ * The listening behaviour passes the Module reference onward to the [Plugin](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin) configured to perform the action.
61
61
 
62
62
 
63
63
  Configuration
64
64
  =============
65
65
 
66
66
  * Behaviours are assigned to triggers in the :server: subconfig branch.
67
- * Behaviours are assigned a [Plugin](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin)
67
+ * Behaviours are assigned a [Plugin](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin)
68
68
 
69
69
 
70
70
  Behaviours
@@ -72,9 +72,9 @@ Behaviours
72
72
 
73
73
  ### Persistable
74
74
 
75
- Requires a [Persistor](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin#persistor) Plugin
75
+ Requires a [Persistor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin#persistor) Plugin
76
76
 
77
- Creates the ability to store and fetch the contents of the [Handler's Capsule](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler#the-capsule)
77
+ Creates the ability to store and fetch the contents of the [Handler's Capsule](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#the-capsule)
78
78
 
79
79
  <pre>
80
80
 
@@ -103,11 +103,11 @@ Creates the ability to store and fetch the contents of the [Handler's Capsule](h
103
103
 
104
104
  ### Preloadable
105
105
 
106
- Requires a [Persistor](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin#persistor) Plugin
106
+ Requires a [Persistor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin#persistor) Plugin
107
107
 
108
- Currently only works with a [Multiplexing Socket Handler](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler#socket-multiplexer)
108
+ Currently only works with a [Multiplexing Socket Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#socket-multiplexer)
109
109
 
110
- Creates the ability to fetch all previously persisted [Handler Capsules](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler#the-capsule) ahead of goind to listen on the socket.
110
+ Creates the ability to fetch all previously persisted [Handler Capsules](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#the-capsule) ahead of goind to listen on the socket.
111
111
 
112
112
  <pre>
113
113
 
@@ -157,9 +157,9 @@ Creates the ability to fetch all previously persisted [Handler Capsules](https:/
157
157
  ### Enqueueable
158
158
 
159
159
 
160
- Requires an [Enqueuer](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/plugin#enqueuer) Plugin
160
+ Requires an [Enqueuer](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/plugin#enqueuer) Plugin
161
161
 
162
- Enqueues a Job onto a specified Queue with the [Handler's Capsule](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler#the-capsule) as payload.
162
+ Enqueues a Job onto a specified Queue with the [Handler's Capsule](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler#the-capsule) as payload.
163
163
 
164
164
 
165
165
 
@@ -16,6 +16,9 @@ module LanGrove
16
16
 
17
17
  @@type = :daemon
18
18
 
19
+ attr_reader :server
20
+ attr_reader :adaptor
21
+
19
22
  def connect
20
23
 
21
24
  #
@@ -162,6 +165,11 @@ module LanGrove
162
165
  def start
163
166
 
164
167
  schedule_behaviours unless @server.nil?
168
+
169
+ #
170
+ # Start the introspector
171
+ #
172
+ @root.metrix.start( self )
165
173
 
166
174
  #
167
175
  # TODO: The client
@@ -179,7 +187,6 @@ module LanGrove
179
187
  @config = config_hash
180
188
  @daemon_name = daemon_name
181
189
 
182
-
183
190
  #
184
191
  # TODO: The client
185
192
  #
@@ -8,6 +8,7 @@ module LanGrove
8
8
 
9
9
  attr_accessor :logger
10
10
  attr_accessor :config
11
+ attr_accessor :metrix
11
12
 
12
13
  def initialize( config = {
13
14
 
@@ -22,6 +23,7 @@ module LanGrove
22
23
 
23
24
  @logger = logger
24
25
  @config = LanGrove::Config::Base.new( self, config, logger )
26
+ @metrix = LanGrove::Metrix::Base.new( self )
25
27
 
26
28
  end
27
29
 
@@ -1,8 +1,234 @@
1
1
  module LanGrove
2
+
3
+ module LogMonitor
4
+
5
+ module Sampler
6
+
7
+ class << self
8
+
9
+ def init( root )
10
+
11
+ return if @initialized
12
+
13
+ @root = root
14
+
15
+ @root.logger.debug "#{self}.init( #{root} )"
16
+
17
+ @root.metrix.register_sampler(
18
+
19
+ :type => :handler,
20
+ :sampler => self,
21
+ :accumulator => proc { |component_type, component, state_doc|
22
+
23
+ #
24
+ # The component will only be sampled
25
+ # if it is a LogMonitor
26
+ #
27
+
28
+ self.sample_accumulate(
29
+
30
+ component_type, component, state_doc
31
+
32
+ ) if component.respond_to?( :log_monitor_event )
33
+
34
+ }
35
+
36
+ )
37
+
38
+ @initialized = true
39
+
40
+ reset
41
+
42
+ return self
43
+
44
+ end
45
+
46
+ def sample_accumulate( component_type, component, state_doc )
47
+
48
+ #@root.logger.debug "#{self}.sample_accumulate( #{component_type}, #{component}, #{state_doc} )"
49
+
50
+ @name = component.class.to_s.split(' ')[0]
51
+
52
+ @counters[:count] += 1
53
+
54
+ if component_type == :handler
55
+
56
+ if component.capsule['success']
57
+
58
+ @counters[:current_success] += 1
59
+
60
+ else
61
+
62
+ @counters[:current_fail] += 1
63
+
64
+ end
65
+
66
+ now = Time.now.to_i
67
+
68
+ if component.capsule['success_at']
69
+
70
+ @counters[:success_ever] += 1
71
+
72
+ at = component.capsule['success_at'].strftime( '%s' )
73
+
74
+ @counters[:success_age] << now - at.to_i
75
+
76
+ else
77
+
78
+ @counters[:success_never] += 1
79
+
80
+ end
81
+
82
+ if component.capsule['last_ran_at']
83
+
84
+ at = component.capsule['last_ran_at'].strftime( '%s' )
85
+
86
+ @counters[:last_run_age] << now - at.to_i
87
+
88
+ end
89
+
90
+ if component.capsule['known_errors']
91
+
92
+ component.capsule['known_errors'].each do |k,v|
93
+
94
+ if @counters[:known_errors][k].nil?
95
+
96
+ @counters[:known_errors][k] = 1
97
+
98
+ else
99
+
100
+ @counters[:known_errors][k] += 1
101
+
102
+ end
103
+
104
+ @counters[:known_errors_instance] += 1
105
+ @counters[:known_errors_total] += v
106
+
107
+ end
108
+
109
+ end
110
+
111
+ if component.capsule['unknown_errors']
112
+
113
+ component.capsule['unknown_errors'].each do |k,v|
114
+
115
+ if @counters[:unknown_errors][k].nil?
116
+
117
+ @counters[:unknown_errors][k] = 1
118
+
119
+ else
120
+
121
+ @counters[:unknown_errors][k] += 1
122
+
123
+ end
124
+
125
+ @counters[:unknown_errors_instance] += 1
126
+ @counters[:unknown_errors_total] += v
127
+
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+ def sample_collate( component_type, state_doc )
137
+
138
+ #@root.logger.debug "#{self}.sample_collate( #{component_type}, #{state_doc} )"
139
+
140
+ success_age = 0.0
141
+ @counters[:success_age].each { |v| success_age += v }
142
+
143
+ last_run_age = 0.0
144
+ @counters[:last_run_age].each { |v| last_run_age += v }
145
+
146
+ state_doc[ @name ] = {
147
+
148
+ :count => @counters[:count],
149
+
150
+ :current_success => @counters[:current_success],
151
+ :current_fail => @counters[:current_fail],
152
+
153
+ :success_ever => @counters[:success_ever],
154
+ :success_never => @counters[:success_never],
155
+
156
+ :avg_success_age => success_age / @counters[:success_age].length,
157
+ :age_last_run_age => last_run_age / @counters[:last_run_age].length,
158
+
159
+ :known_errors_instance => @counters[:known_errors_instance],
160
+ :known_errors_total => @counters[:known_errors_total],
161
+
162
+ :unknown_errors_instance => @counters[:unknown_errors_instance],
163
+ :unknown_errors_total => @counters[:unknown_errors_total],
164
+
165
+ :known_errors => @counters[:known_errors],
166
+ :unknown_errors => @counters[:unknown_errors],
167
+
168
+ }
169
+
170
+ reset
171
+
172
+ end
173
+
174
+ def reset
175
+
176
+ #
177
+ # This may be quite nasty to the garbage collector...
178
+ #
179
+
180
+ @counters = {
181
+
182
+ :count => 0,
183
+
184
+ #
185
+ # current state
186
+ #
187
+ :current_success => 0,
188
+ :current_fail => 0,
189
+
190
+ #
191
+ # ever succeeded
192
+ #
193
+ :success_ever => 0,
194
+ :success_never => 0,
195
+
196
+ #
197
+ # age in seconds of each success
198
+ #
199
+ :success_age => [],
200
+ :last_run_age => [],
201
+
202
+ #
203
+ # known errors
204
+ #
205
+ :known_errors => {},
206
+ :known_errors_instance => 0,
207
+ :known_errors_total => 0, # includes repeat count
208
+
209
+ #
210
+ # unknown errors
211
+ #
212
+ :unknown_errors => {},
213
+ :unknown_errors_instance => 0,
214
+ :unknown_errors_total => 0
215
+
216
+
217
+ }
218
+
219
+ end
220
+
221
+ end
222
+
223
+ end
224
+
225
+ end
2
226
 
3
227
  module LogMonitor
4
228
 
5
- def log_monitor_config( config, hash = nil )
229
+ def log_monitor_config( root, hash )
230
+
231
+ @@sampler = Sampler.init( root )
6
232
 
7
233
  #
8
234
  # <hash> as the state storage (capsule)
@@ -11,9 +11,9 @@ Defines the `Object` that interacts with remote processes.
11
11
  Function
12
12
  --------
13
13
 
14
- * A handler is spawned to handle each connection being made through the [Adaptor](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/adaptor).
14
+ * A handler is spawned to handle each connection being made through the [Adaptor](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/adaptor).
15
15
  * The handler remains connected to it's assigned remote process.
16
- * Handlers are registered with the [Server](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/server) collection.
16
+ * Handlers are registered with the [Server](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/server) collection.
17
17
  * Handlers run idle in [EventMachine](http://eventmachine.rubyforge.org/EventMachine.html)'s event loop.
18
18
 
19
19
  The Capsule
@@ -27,12 +27,12 @@ Event Callbacks
27
27
  ---------------
28
28
 
29
29
  * The event loop fires callbacks into the Handler.
30
- * Each callback also has associated [Behaviour](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour) triggers.
30
+ * Each callback also has associated [Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour) triggers.
31
31
 
32
32
 
33
33
  ### start()
34
34
 
35
- This callback will fire into each connecting Handler after loading the [Protocol](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/protocol) and Config.
35
+ This callback will fire into each connecting Handler after loading the [Protocol](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol) and Config.
36
36
 
37
37
 
38
38
  ### stop()
@@ -47,7 +47,7 @@ Informs each Handler that the Daemon received a sigHUP. The Config may have chan
47
47
 
48
48
  ### receive( decoded )
49
49
 
50
- Data arrived at the socket and was decoded by the configured [Prococol](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/protocol)
50
+ Data arrived at the socket and was decoded by the configured [Prococol](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/protocol)
51
51
 
52
52
 
53
53
  ### TODO - connect()
@@ -24,8 +24,8 @@ Plugin Types
24
24
  Persistor
25
25
  ---------
26
26
 
27
- * Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour#persistable)
28
- * Supports the [Preloadable Behaviour](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour#preloadable)
27
+ * Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#persistable)
28
+ * Supports the [Preloadable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#preloadable)
29
29
 
30
30
  ### `store( hander )`
31
31
 
@@ -35,7 +35,7 @@ Persistor
35
35
 
36
36
  ### Implementations
37
37
 
38
- * [YamlFile](https://github.com/cluetechnologies/langrove-enterprise/blob/master/lib/langrove/plugin/yaml_file.md)
38
+ * [YamlFile](https://github.com/cluetechnologies/langrove/blob/master/lib/langrove/plugin/yaml_file.md)
39
39
  * [langrove-plugin-mongodb.gem](https://github.com/cluetechnologies/langrove-plugin-mongodb)
40
40
 
41
41
 
@@ -46,7 +46,7 @@ Functionally identical to Persistor except it accumulates calls to store to enab
46
46
  All updates are performed at the configured `:interval:`
47
47
 
48
48
  * Only compatable with Eventmachine enabled daemons.
49
- * Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour#persistable)
49
+ * Supports the [Persistable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#persistable)
50
50
 
51
51
  ### Implementations
52
52
 
@@ -56,7 +56,7 @@ All updates are performed at the configured `:interval:`
56
56
  Enqueuer
57
57
  --------
58
58
 
59
- * Supports the [Enqueueable Behaviour](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/behaviour#enqueueable)
59
+ * Supports the [Enqueueable Behaviour](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/behaviour#enqueueable)
60
60
 
61
61
 
62
62
  ### `enqueue_key( handler )`
@@ -171,7 +171,7 @@ module LanGrove
171
171
  # Use the pending capsule to assemble the
172
172
  # persistance key.
173
173
  #
174
- data_hash = handler.pending_capsule
174
+ data_hash = handler.pending_capsule if handler.respond_to?( :pending_capsule )
175
175
 
176
176
  #
177
177
  # Fall back to using the actual capsule
@@ -181,7 +181,7 @@ module LanGrove
181
181
  def store( handler )
182
182
 
183
183
  filename = nil
184
-
184
+
185
185
  begin
186
186
 
187
187
  data_hash = handler.capsule
@@ -17,13 +17,13 @@
17
17
  LanGrove::Protocol::Base
18
18
  ========================
19
19
 
20
- Defines the `Interface` that is employed to decode and encode data passing between the [Handler](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler) and the remote process to which it is attached.
20
+ Defines the `Interface` that is employed to decode and encode data passing between the [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler) and the remote process to which it is attached.
21
21
 
22
22
 
23
23
  Function
24
24
  --------
25
25
 
26
- Each spawned [Handler](https://github.com/cluetechnologies/langrove-enterprise/tree/master/lib/langrove/handler) is assigned an instance of the protocol and its configuration.
26
+ Each spawned [Handler](https://github.com/cluetechnologies/langrove/tree/master/lib/langrove/handler) is assigned an instance of the protocol and its configuration.
27
27
 
28
28
 
29
29
  Configuration
@@ -1,5 +1,38 @@
1
1
  <pre>
2
2
 
3
+ #
4
+ # root |noun| ~ The force that through the green fuse drives the flower
5
+ # Drives my green age; that blasts the roots of trees
6
+ # Is my destroyer.
7
+ #
8
+ # And I am dumb to tell the crooked rose
9
+ # My youth is bent by the same wintry fever.
10
+ # The force that drives the water through the rocks
11
+ # Drives my red blood; that dries the mouthing streams
12
+ # Turns mine to wax.
13
+ #
14
+ # And I am dumb to mouth unto my veins
15
+ # How at the mountain spring the same mouth sucks.
16
+ # The hand that whirls the water in the pool
17
+ # Stirs the quicksand; that ropes the blowing wind
18
+ # Hauls my shroud sail.
19
+ #
20
+ # And I am dumb to tell the hanging man
21
+ # How of my clay is made the hangman’s lime.
22
+ # The lips of time leech to the fountain head;
23
+ # Love drips and gathers, but the fallen blood
24
+ # Shall calm her sores.
25
+ #
26
+ # And I am dumb to tell a weather’s wind
27
+ # How time has ticked a heaven round the stars.
28
+ #
29
+ # And I am dumb to tell the lover’s tomb
30
+ # How at my sheet goes the same crooked worm.
31
+ #
32
+ #
33
+ # - Dylan Thomas (1914–1953)
34
+ #
35
+
3
36
  </pre>
4
37
 
5
38
  LanGrove::Root::Base
@@ -9,9 +42,15 @@ LanGrove::Root::Base
9
42
  * Provides the `config` and `logger` to all daemon modules.
10
43
  * Provides an event trigger interface into `Behaviour` and associated `Plugin` modules.
11
44
 
45
+ Metrix
46
+ ------
47
+
48
+ pending...
49
+
50
+
51
+
12
52
  Todo
13
53
  ----
14
54
 
15
- * Provides an introspection interface into `Metrix` module.
16
55
  * Provides a notification interface into `Alerter` module.
17
56
 
@@ -8,4 +8,5 @@ module LanGrove
8
8
 
9
9
  end
10
10
  require 'langrove/root/root_base'
11
+ require 'langrove/root/metrix'
11
12
  require 'langrove/root/config'
@@ -66,6 +66,41 @@ module LanGrove
66
66
 
67
67
  end
68
68
 
69
+ def get_daemon_config( name, component = nil )
70
+
71
+ #
72
+ I.show "TODO: All config collection should pass through here"
73
+ #
74
+
75
+ @logger.debug "get_daemon_config( #{name}, #{component} )"
76
+
77
+ raise LanGrove::DaemonConfigException.new(
78
+
79
+ "No :daemons: named #{name}"
80
+
81
+ ) if @config[:daemons][name].nil?
82
+
83
+ return @config[:daemons][name] if component == nil?
84
+
85
+ if @config[:daemons][name][component].nil?
86
+
87
+ @logger.error "No #{component} defined for :daemons: named #{name}"
88
+ return {}
89
+
90
+ end
91
+
92
+ return @config[:daemons][name][component]
93
+
94
+ end
95
+
96
+ def get_daemon( name, component = nil, instance = true )
97
+
98
+ #
99
+ # Get instance[ ?.new ]
100
+ #
101
+
102
+ end
103
+
69
104
  def get_plugin_config( name )
70
105
 
71
106
  @config[:plugins][name]
@@ -0,0 +1,204 @@
1
+ require 'socket'
2
+
3
+ module LanGrove
4
+
5
+ module Metrix
6
+
7
+ class Base < LanGrove::Base
8
+
9
+ #
10
+ # Maintains a capsule 'image' of runtime state
11
+ #
12
+ attr_reader :capsule
13
+
14
+ #
15
+ # Persists the capsule
16
+ #
17
+ attr_accessor :key
18
+ attr_reader :persistor
19
+
20
+ def initialize( root )
21
+
22
+ super( root )
23
+
24
+ @config = root.config.get_daemon_config( DAEMON_NAME, :metrix )
25
+
26
+ I.show @config
27
+
28
+ @capsule = {
29
+
30
+ :id => "#{DAEMON_NAME}@#{Socket.gethostname}"
31
+
32
+ }
33
+
34
+ @persistor = nil
35
+
36
+ #
37
+ # register_sampler() informs this with sampler objects
38
+ # to process the daemon components
39
+ #
40
+ @samplers = {}
41
+
42
+ @interval = @config[:interval].nil? ? 60 * 5 : @config[:interval]
43
+
44
+ if @config[:persistor].nil?
45
+
46
+ #
47
+ # Defaults to persist runtime state 'image'
48
+ # to a yaml file at:
49
+ #
50
+ # daemon_root//log/daemon_name@hostname
51
+ #
52
+
53
+ @persistor = LanGrove::ClassLoader.create( {
54
+
55
+ :module => 'Plugin',
56
+ :class => 'YamlFile'
57
+
58
+ } ).new( root, {
59
+
60
+ :basedir => DAEMON_ROOT,
61
+ :database => '',
62
+ :table => 'log',
63
+ :key => {
64
+ :filename => :id
65
+ }
66
+
67
+ }, nil )
68
+
69
+ else
70
+
71
+ #
72
+ # But can use any configured persistor plugin
73
+ #
74
+
75
+ @persistor = root.config.get_plugin( @config[:persistor] )
76
+
77
+ end
78
+
79
+ raise config_exception(
80
+
81
+ "#{self.class} requires :persistor: to specify a configured persistor plugin."
82
+
83
+ ) unless @persistor.is_a?( LanGrove::Plugin::Persistor )
84
+
85
+ end
86
+
87
+ def register_sampler( spec )
88
+
89
+ type = :handler
90
+ filter = '*'
91
+ accumulator = nil
92
+ sampler = nil
93
+
94
+ spec.each do |key, value|
95
+
96
+ case key
97
+
98
+ when :type
99
+
100
+ type = value
101
+
102
+ when :sampler
103
+
104
+ sampler = value
105
+
106
+ when :filter
107
+
108
+ filter = value
109
+
110
+ when :accumulator
111
+
112
+ #
113
+ # Allows for an alternative accumulator callback
114
+ #
115
+ accumulator = value
116
+
117
+ end
118
+
119
+ end
120
+
121
+ @samplers[type] = {} if @samplers[type].nil?
122
+ @samplers[type][filter] = [] if @samplers[type][filter].nil?
123
+ @samplers[type][filter] << [accumulator, sampler]
124
+
125
+ end
126
+
127
+ def start( daemon )
128
+
129
+ @logger.debug "#{self.class}.start( #{daemon} )"
130
+
131
+ #
132
+ # Start the sample event loop
133
+ #
134
+
135
+ @daemon = daemon
136
+
137
+ if defined?( EM ) and EM::reactor_running?
138
+
139
+ EM::add_periodic_timer(@interval) do
140
+
141
+ sample
142
+
143
+ end
144
+
145
+ end
146
+
147
+ end
148
+
149
+ def sample
150
+
151
+ sample_handlers
152
+
153
+ sample_adaptors
154
+
155
+ I.show @capsule
156
+
157
+ @persistor.store( self )
158
+
159
+ end
160
+
161
+ def sample_handlers
162
+
163
+ @samplers[:handler]['*'].each do |sampler|
164
+
165
+ #
166
+ # sampler[0] contains the alternative accumulator callback proc
167
+ # sampler[1] contains the sampler object
168
+ #
169
+
170
+ @daemon.server.each_handler do |handler|
171
+
172
+ if sampler[0].nil?
173
+
174
+ sampler[1].sample_accumulate( :handler, handler, @capsule )
175
+
176
+ else
177
+
178
+ sampler[0].yield( :handler, handler, @capsule )
179
+
180
+ end
181
+
182
+ end
183
+
184
+ sampler[1].sample_collate( :handler, @capsule )
185
+
186
+ end unless @samplers[:handler].nil?
187
+
188
+ end
189
+
190
+ def sample_adaptors
191
+
192
+ @samplers[:adaptor]['*'].each do |sampler|
193
+
194
+ sampler[1].sample_accumulate( :adaptor, @daemon.adaptor, @capsule )
195
+
196
+ end unless @samplers[:adaptor].nil?
197
+
198
+ end
199
+
200
+ end
201
+
202
+ end
203
+
204
+ end
@@ -37,19 +37,6 @@ module LanGrove
37
37
 
38
38
  end
39
39
 
40
- module Metrix
41
-
42
- class Base
43
-
44
- #
45
- # Collect internal runtime metrix from
46
- # all local daemons
47
- #
48
-
49
- end
50
-
51
- end
52
-
53
40
  module Alerter
54
41
 
55
42
  class Base
@@ -135,7 +122,8 @@ module LanGrove
135
122
 
136
123
  config_instance
137
124
 
138
-
125
+ @config.instance_variable_set( :@logger, logger )
126
+
139
127
  #
140
128
  # Behaviours are configured to run at
141
129
  # key points in the Daemon life cycle.
@@ -248,7 +236,7 @@ module LanGrove
248
236
  # LAter...
249
237
  #
250
238
  @alerter = LanGrove::Alerter::Base.new
251
- @metrix = LanGrove::Metrix::Base.new
239
+ @metrix = LanGrove::Metrix::Base.new( self )
252
240
 
253
241
  end
254
242
 
@@ -1,5 +1,5 @@
1
1
  module LanGrove
2
2
 
3
- Version = VERSION = '0.0.5.3'
3
+ Version = VERSION = '0.0.5.4'
4
4
 
5
5
  end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+ require 'em-rspec'
3
+
4
+ describe LanGrove::Metrix::Base do
5
+
6
+ before :each do
7
+
8
+ CONFIG.flush
9
+
10
+ end
11
+
12
+ subject {
13
+
14
+ LanGrove::Metrix::Base.new( ROOT )
15
+
16
+ }
17
+
18
+ pending 'default to persisting runtime metrix as a yaml file' do
19
+
20
+ LOG.on
21
+
22
+ subject.persistor.should be_a( LanGrove::Plugin::YamlFile )
23
+
24
+ end
25
+
26
+ pending 'defaults to a 5 minute sample frequency' do
27
+
28
+ EM.should_receive( :add_periodic_timer ).with( 5 * 60 )
29
+
30
+ subject.start
31
+
32
+ end
33
+
34
+ it 'allows registering functions as samplers' do
35
+
36
+ sampler1 = mock( 'A sampler for handlers' )
37
+ sampler2 = mock( 'A sampler for adaptors' )
38
+
39
+ CONFIG.create( 'daemon', :handler, 'Base' )
40
+ CONFIG.create( 'daemon', :adaptor, 'Base' )
41
+ CONFIG.create( 'daemon', :metrix, 'Base' )
42
+
43
+ @daemon, @server, @adaptor, @handler, @protocol =
44
+ LanGrove::SpecHelper::create_daemon_with_connected_handler( 'daemon', anything )
45
+
46
+ subject.instance_variable_set( :@daemon, @daemon )
47
+
48
+ sampler1.should_receive( :sample ).with( :handler, @handler, anything )
49
+ sampler2.should_receive( :sample ).with( :adaptor, @adaptor, anything )
50
+
51
+ subject.register_sampler( :type => :handler, :sampler => sampler1 )
52
+ subject.register_sampler( :type => :adaptor, :sampler => sampler2 )
53
+
54
+ subject.sample
55
+
56
+ end
57
+
58
+ pending 'can specify to sample only handlers of a specific type'
59
+
60
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'langrove'
2
2
 
3
- NAME = 'daemon'
3
+ DAEMON_ROOT = File.expand_path('../../', __FILE__)
4
+
5
+ DAEMON_NAME = NAME = 'daemon'
4
6
 
5
7
  LOG = LanGrove::FakeLogger
6
8
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langrove
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5.3
4
+ version: 0.0.5.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-08-08 00:00:00.000000000 Z
15
+ date: 2012-08-09 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: eventmachine
@@ -117,8 +117,6 @@ executables:
117
117
  extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
- - .rspec
121
- - .rvmrc
122
120
  - Gemfile
123
121
  - Gemfile.lock
124
122
  - Guardfile
@@ -190,6 +188,7 @@ files:
190
188
  - lib/langrove/root/README.md
191
189
  - lib/langrove/root/base.rb
192
190
  - lib/langrove/root/config.rb
191
+ - lib/langrove/root/metrix.rb
193
192
  - lib/langrove/root/root_base.rb
194
193
  - lib/langrove/server/README.md
195
194
  - lib/langrove/server/base.rb
@@ -236,6 +235,7 @@ files:
236
235
  - spec/langrove/protocol/protocol_base_spec.rb
237
236
  - spec/langrove/protocol/syslog_spec.rb
238
237
  - spec/langrove/root/config_spec.rb
238
+ - spec/langrove/root/metrix_spec.rb
239
239
  - spec/langrove/root/root_base_spec.rb
240
240
  - spec/langrove/server/server_base_spec.rb
241
241
  - spec/spec_helper.rb
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
data/.rvmrc DELETED
@@ -1,53 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
- # development environment upon cd'ing into the directory
5
-
6
- # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
7
- # Only full ruby name is supported here, for short names use:
8
- # echo "rvm use 1.9.2" > .rvmrc
9
- environment_id="ruby-1.9.2-p318@langrove"
10
-
11
- # Uncomment the following lines if you want to verify rvm version per project
12
- # rvmrc_rvm_version="1.12.3 (master)" # 1.10.1 seams as a safe start
13
- # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
- # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
- # return 1
16
- # }
17
-
18
- # First we attempt to load the desired environment directly from the environment
19
- # file. This is very fast and efficient compared to running through the entire
20
- # CLI and selector. If you want feedback on which environment was used then
21
- # insert the word 'use' after --create as this triggers verbose mode.
22
- if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
23
- && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
24
- then
25
- \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
26
- [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
27
- \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
28
- if [[ $- == *i* ]] # check for interactive shells
29
- then echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
30
- else echo "Using: $GEM_HOME" # don't use colors in non-interactive shells
31
- fi
32
- else
33
- # If the environment file has not yet been created, use the RVM CLI to select.
34
- rvm --create use "$environment_id" || {
35
- echo "Failed to create RVM environment '${environment_id}'."
36
- return 1
37
- }
38
- fi
39
-
40
-
41
- # If you use bundler, this might be useful to you:
42
- # if [[ -s Gemfile ]] && {
43
- # ! builtin command -v bundle >/dev/null ||
44
- # builtin command -v bundle | grep $rvm_path/bin/bundle >/dev/null
45
- # }
46
- # then
47
- # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
48
- # gem install bundler
49
- # fi
50
- # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null
51
- # then
52
- # bundle install | grep -vE '^Using|Your bundle is complete'
53
- # fi