langrove 0.0.5.3 → 0.0.5.4

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.
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