nutella_framework 0.4.18 → 0.4.19

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.
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
@@ -0,0 +1 @@
1
+ # monitoring-bot
@@ -0,0 +1,476 @@
1
+ require_relative '../../lib/config/runlist'
2
+ require_relative '../../lib/config/config'
3
+ require_relative '../../nutella_lib/framework_core'
4
+ require_relative '../../lib/commands/util/components_list'
5
+ require 'active_support/core_ext/object/deep_dup'
6
+ require 'mandrill'
7
+ require 'mongo'
8
+
9
+ # Framework bots can access all the parameters they need directly
10
+ # from the configuration file and the runlist,
11
+ # to which they have full access to.
12
+
13
+ # Access the config file like so:
14
+ # Nutella.config['broker']
15
+
16
+ # Access the runs list like so:
17
+ # Nutella.runlist.all_runs
18
+
19
+
20
+ # Initialize this bot as framework component
21
+ nutella.f.init(Nutella.config['broker'], 'monitoring_bot')
22
+
23
+ # Mandrill access key
24
+ $m = Mandrill::API.new 'i4frQYcTBMyZ6bYyLkEVOQ'
25
+
26
+ # Open the resources database
27
+ $messages = nutella.f.persist.get_json_object_store('messages')
28
+
29
+ # Application structure
30
+ $applications = {}
31
+
32
+ # MongoDB client
33
+ Mongo::Logger.logger.level = ::Logger::INFO
34
+ client = Mongo::Client.new([Nutella.config['broker']], :database => 'nutella')
35
+
36
+ puts 'Monitoring bot initialization'
37
+
38
+ def send_subscription_mail(mail, application, instance = nil, component = nil)
39
+ object = application
40
+
41
+ if instance != nil
42
+ object = object + ' > ' + instance
43
+ if rcomponent != nil
44
+ object = object + ' > ' + component
45
+ end
46
+ end
47
+
48
+ puts "Send mail to " + mail + "message: " + object
49
+
50
+
51
+ template_name = 'Nutella subscription'
52
+ template_content = [
53
+ {
54
+ :name=> 'main',
55
+ :content=> "Congratulation: subscription to component
56
+ <b>#{object}</b>
57
+ has been succeded."
58
+ }
59
+ ]
60
+ message = {
61
+ :subject=> "Subscription to #{object}",
62
+ :from_name=> 'Nutella Monitoring Interface',
63
+ :to=>[
64
+ {
65
+ :email=> mail,
66
+ # :name=> ""
67
+ }
68
+ ],
69
+ :from_email=>'nutellamonitoring@gmail.com'
70
+ }
71
+
72
+ sending = $m.messages.send_template template_name, template_content, message
73
+ end
74
+
75
+ def send_notification_mail(mail, application, instance = nil, component = nil)
76
+ object = application
77
+
78
+ if instance != nil
79
+ object = object + ' > ' + instance
80
+ if component != nil
81
+ object = object + ' > ' + component
82
+ end
83
+ end
84
+
85
+ puts "Send mail to " + mail + "message: " + object
86
+
87
+ template_name = 'Nutella alert'
88
+ template_content = [
89
+ {
90
+ :name=> 'main',
91
+ :content=> "Attention: component
92
+ <b>#{object}</b>
93
+ had a problem and went down."
94
+ }
95
+ ]
96
+ message = {
97
+ :subject=> "Alert: #{object} went down",
98
+ :from_name=> 'Nutella Monitoring Interface',
99
+ :to=>[
100
+ {
101
+ :email=> mail,
102
+ # :name=> ""
103
+ }
104
+ ],
105
+ :from_email=>'nutellamonitoring@gmail.com'
106
+ }
107
+
108
+ sending = $m.messages.send_template template_name, template_content, message
109
+ puts sending
110
+
111
+ end
112
+
113
+ # Add an alert on a specific application/instance/component
114
+ nutella.f.net.subscribe_to_all_runs('monitoring/alert/add', lambda do |message, appId, runId, from|
115
+ application = message['application']
116
+ instance = message['instance']
117
+ component = message['component']
118
+ mail = message['mail']
119
+
120
+ create_if_not_present(application, instance, component)
121
+
122
+ if application != nil
123
+ puts "Subscribed to #{application} with mail #{mail}";
124
+ end
125
+
126
+ if application != nil && instance != nil && component != nil
127
+ a = $applications[application]
128
+ if a['instances'][instance]['components'][component]['alert'] == nil
129
+ a['instances'][instance]['components'][component]['alert'] = []
130
+ end
131
+ if !a['instances'][instance]['components'][component]['alert'].include? mail
132
+ a['instances'][instance]['components'][component]['alert'].push(mail)
133
+ end
134
+ $applications[application] = a
135
+ elsif application != nil && instance != nil
136
+ a = $applications[application]
137
+ if a['instances'][instance]['alert'] == nil
138
+ a['instances'][instance]['alert'] = []
139
+ end
140
+ if !a['instances'][instance]['alert'].include? mail
141
+ a['instances'][instance]['alert'].push(mail)
142
+ end
143
+ $applications[application] = a
144
+ elsif application != nil
145
+ a = $applications[application]
146
+ if a['alert'] == nil
147
+ a['alert'] = []
148
+ end
149
+ emails = a['alert']
150
+ if !emails.include? mail
151
+ emails.push(mail)
152
+ send_subscription_mail(mail, application)
153
+ end
154
+ $applications[application] = a
155
+ end
156
+
157
+ end)
158
+
159
+ # Listen for published messages
160
+ =begin
161
+ nutella.net.subscribe('#', lambda do |message, channel, from|
162
+ puts message
163
+ puts channel
164
+ #application = from['app_id']
165
+ #instance = from['run_id']
166
+ #component = from['component_id']
167
+ puts from
168
+ #puts application, instance, component
169
+
170
+ #create_if_not_present(application, instance, component)
171
+
172
+ #if !($applications[application]['instances'][instance]['components'][component]['publish'].include? channel)
173
+ # $applications[application]['instances'][instance]['components'][component]['publish'].push(channel)
174
+ #end
175
+
176
+ end)
177
+ =end
178
+
179
+ # Add an alert on a specific application/instance/component
180
+ nutella.f.net.subscribe_to_all_runs('monitoring/alert/remove', lambda do |message, appId, runId, from|
181
+ puts "Delete alert"
182
+ puts message
183
+ application = message['application']
184
+ instance = message['instance']
185
+ component = message['component']
186
+ mail = message['mail']
187
+
188
+ if application != nil && instance != nil && component != nil
189
+ a = $applications[application]
190
+ a['instances'][instance]['components'][component]['alert'] -=[mail]
191
+ $applications[application] = a
192
+ elsif application != nil && instance != nil
193
+ a = $applications[application]
194
+ a['instances'][instance]['alert'] -= [mail]
195
+ $applications[application] = a
196
+ elsif application != nil
197
+ a = $applications[application]
198
+ a['alert'] -= [mail]
199
+ puts a['alert']
200
+ $applications[application] = a
201
+ end
202
+ end)
203
+
204
+ # Listen for subscribe
205
+ # Listen for request
206
+ # Listen for handle_request
207
+
208
+ # Request the list of alert for an application/instance/component
209
+ nutella.f.net.handle_requests_on_all_runs('monitoring/alert', lambda do |request, appId, runId, from|
210
+ puts 'Sending alert list'
211
+ application = request['application']
212
+ instance = request['instance']
213
+ component = request['component']
214
+
215
+ alert = nil
216
+
217
+ begin
218
+ if application != nil && instance != nil && component != nil
219
+ a = $applications[application]
220
+ alert = a['instances'][instance]['components'][component]['alert']
221
+ elsif application != nil && instance != nil
222
+ a = $applications[application]
223
+ alert = a['instances'][instance]['alert']
224
+ elsif application != nil
225
+ a = $applications[application]
226
+ alert = a['alert']
227
+ end
228
+ rescue
229
+ end
230
+
231
+ if alert == nil
232
+ alert = []
233
+ end
234
+
235
+ {:emails => alert}
236
+ end)
237
+
238
+ # Create the application structure if it is not present
239
+ def create_if_not_present(application, instance=nil, component=nil)
240
+
241
+ a = $applications[application]
242
+
243
+ if a == nil
244
+ a = {
245
+ 'name' => application,
246
+ 'instances' => {}
247
+ }
248
+ end
249
+
250
+ begin
251
+ if instance != nil && a['instances'][instance] == nil
252
+ a['instances'][instance] = {
253
+ 'name' => instance,
254
+ 'components' => {}
255
+ }
256
+ end
257
+ rescue
258
+ a['instances'][instance] = {
259
+ 'name' => instance,
260
+ 'components' => {}
261
+ }
262
+ end
263
+
264
+ begin
265
+ if component != nil && instance != nil && a['instances'][instance]['components'][component] == nil
266
+ a['instances'][instance]['components'][component] = {
267
+ 'name' => component,
268
+ 'publish' => [],
269
+ 'subscribe' => [],
270
+ 'request' => [],
271
+ 'handle_request' => []
272
+ }
273
+ end
274
+ rescue
275
+ a['instances'][instance]['components'][component] = {
276
+ 'name' => component,
277
+ 'publish' => [],
278
+ 'subscribe' => [],
279
+ 'request' => [],
280
+ 'handle_request' => []
281
+ }
282
+ end
283
+
284
+ $applications[application] = a
285
+
286
+ end
287
+
288
+ nutella.f.net.handle_requests_on_all_runs('monitoring/application', lambda do |request, appId, runId, from|
289
+ apps = []
290
+
291
+ $applications.each do |_, application|
292
+ app = application.deep_dup
293
+ app['instances'] = []
294
+ if application['instances'] != nil
295
+ application['instances'].each do |_, instance|
296
+ inst = instance.deep_dup
297
+
298
+ app['instances'].push(inst)
299
+
300
+ inst['components'] = []
301
+ if instance['components'] != nil
302
+ instance['components'].each do |_, component|
303
+ comp = component.deep_dup
304
+ inst['components'].push(comp)
305
+ end
306
+ end
307
+ end
308
+ end
309
+ apps.push(app)
310
+ end
311
+ {:applications => apps}
312
+ end)
313
+
314
+ nutella.f.net.handle_requests_on_all_runs('monitoring/message', lambda do |request, appId, runId, from|
315
+ application = request['application']
316
+ instance = request['instance']
317
+ channel = request['channel']
318
+
319
+ collection = client['dump']
320
+
321
+ messages = []
322
+
323
+ collection.find({'channel' => '/nutella/apps/crepe/runs/default/location/resources'}).sort({:_id => -1}).limit(5).each do |message|
324
+ messages.push(message)
325
+ end
326
+
327
+ {:messages => messages}
328
+ end)
329
+
330
+ # Catch publish messages
331
+ nutella.f.net.subscribe_to_all_runs("#", lambda do |channel, payload, app_id, run_id, from|
332
+
333
+ component_id = from['component_id']
334
+
335
+ if component_id != nil
336
+ create_if_not_present(app_id, run_id, component_id)
337
+
338
+ publish = $applications[app_id]['instances'][run_id]['components'][component_id]['publish']
339
+
340
+ if not publish.include? ({'channel' => channel})
341
+ publish.push({'channel' => channel})
342
+ end
343
+
344
+ $applications[app_id]['instances'][run_id]['components'][component_id]['publish'] = publish
345
+
346
+ end
347
+
348
+ end)
349
+
350
+ # Catch subscribe / handle_request messages
351
+ nutella.f.net.subscribe_to_all_runs("subscriptions", lambda do |payload, app_id, run_id, from|
352
+
353
+ component_id = from['component_id']
354
+ type = payload['type']
355
+ channel = nutella.net.un_pad_channel(payload['channel'], app_id, run_id)
356
+
357
+ if type == 'subscribe'
358
+ create_if_not_present(app_id, run_id, component_id)
359
+
360
+ subscribe = $applications[app_id]['instances'][run_id]['components'][component_id]['subscribe']
361
+
362
+ if not subscribe.include? ({'channel' => channel})
363
+ subscribe.push({'channel' => channel})
364
+ end
365
+
366
+ $applications[app_id]['instances'][run_id]['components'][component_id]['subscribe'] = subscribe
367
+
368
+ end
369
+
370
+ if type == 'handle_requests'
371
+ create_if_not_present(app_id, run_id, component_id)
372
+
373
+ handle_request = $applications[app_id]['instances'][run_id]['components'][component_id]['handle_request']
374
+
375
+ if not handle_request.include? ({'channel' => channel})
376
+ handle_request.push({'channel' => channel})
377
+ end
378
+
379
+ $applications[app_id]['instances'][run_id]['components'][component_id]['handle_request'] = handle_request
380
+
381
+ end
382
+
383
+ end)
384
+
385
+ # Catch requests
386
+ nutella.f.net.catch_requests_on_all_runs_wildcard(lambda do |channel, payload, app_id, run_id, from|
387
+
388
+ component_id = from['component_id']
389
+
390
+ if component_id != nil
391
+
392
+ create_if_not_present(app_id, run_id, component_id)
393
+
394
+ request = $applications[app_id]['instances'][run_id]['components'][component_id]['request']
395
+
396
+ unless request.include? ({'channel' => channel})
397
+ request.push({'channel' => channel})
398
+ end
399
+
400
+ $applications[app_id]['instances'][run_id]['components'][component_id]['request'] = request
401
+
402
+ end
403
+
404
+
405
+ end)
406
+
407
+
408
+ nutella.f.net.subscribe_to_all_runs("pings", lambda do |payload, app_id, run_id, from|
409
+
410
+ component_id = from['component_id']
411
+
412
+ create_if_not_present(app_id, run_id, component_id)
413
+
414
+ $applications[app_id]['instances'][run_id]['components'][component_id]['timestamp'] = Time.now.to_f
415
+
416
+ end)
417
+
418
+ # TODO implement framework pings
419
+
420
+ puts 'Initialization completed'
421
+
422
+ while sleep 0.25
423
+ n = Nutella.runlist.all_runs
424
+ Nutella.runlist.all_apps.each do |app_id, _|
425
+ Nutella.runlist.runs_for_app(app_id).each do |run_id|
426
+ pathBots = "#{Nutella.runlist.app_path(app_id)}/bots"
427
+ pathInterfaces = "#{Nutella.runlist.app_path(app_id)}/interfaces"
428
+
429
+ create_if_not_present(app_id, run_id)
430
+
431
+ ComponentsList.for_each_component_in_dir(pathBots) do |comp_name|
432
+ create_if_not_present(app_id, run_id, comp_name)
433
+ end
434
+
435
+ ComponentsList.for_each_component_in_dir(pathInterfaces) do |comp_name|
436
+ create_if_not_present(app_id, run_id, comp_name)
437
+ end
438
+ end
439
+ end
440
+
441
+ $applications.each do |_, application|
442
+ appProblems = 0
443
+ application['instances'].each do |_, instance|
444
+ instanceProblems = 0
445
+ instance['components'].each do |_, component|
446
+ if component['timestamp'] == nil || Time.now.to_f - component['timestamp'] > 16.0
447
+ appProblems += 1
448
+ instanceProblems += 1
449
+ if component['problem'] != true
450
+ component['problem'] = true
451
+ #puts "Set problem on #{application['name']} > #{instance['name']} > #{component['name']}}"
452
+ if component['alert'] != nil
453
+ component['alert'].each do |mail|
454
+ send_notification_mail(mail, application['name'], instance['name'], component['name'])
455
+ end
456
+ end
457
+ if instance['alert'] != nil
458
+ instance['alert'].each do |mail|
459
+ send_notification_mail(mail, application['name'], instance['name'], component['name'])
460
+ end
461
+ end
462
+ if application['alert'] != nil
463
+ application['alert'].each do |mail|
464
+ send_notification_mail(mail, application['name'], instance['name'], component['name'])
465
+ end
466
+ end
467
+ end
468
+ else
469
+ component['problem'] = false
470
+ end
471
+ instance['problems'] = instanceProblems
472
+ end
473
+ application['problems'] = appProblems
474
+ end
475
+ end
476
+ end