gaddygaddy 0.1.78
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/gaddygaddy-client +10 -0
- data/bin/interval +8 -0
- data/conf/development.yml +0 -0
- data/conf/gaddy.yml +2 -0
- data/conf/log4r.yml +47 -0
- data/conf/test.yml +1 -0
- data/lib/device_info/device_info.rb +60 -0
- data/lib/gaddygaddy-client/chef_files.rb +98 -0
- data/lib/gaddygaddy-client/device_config.rb +0 -0
- data/lib/gaddygaddy-client/espeak.rb +26 -0
- data/lib/gaddygaddy-client/log_data.rb +42 -0
- data/lib/gaddygaddy-client/notification/espeak.rb +32 -0
- data/lib/gaddygaddy-client/notification/file_notification.rb +43 -0
- data/lib/gaddygaddy-client/notification/file_notification.rb~ +36 -0
- data/lib/gaddygaddy-client/notification/sensu.rb +40 -0
- data/lib/gaddygaddy-client/notification/wall.rb +25 -0
- data/lib/gaddygaddy-client/notification.rb +73 -0
- data/lib/gaddygaddy-client/svn-commit.tmp~ +4 -0
- data/lib/gaddygaddy-client.rb +396 -0
- data/lib/gaddygaddy-client.rb~ +425 -0
- data/lib/gg_config/gg_config.rb +162 -0
- data/lib/interval.rb +280 -0
- data/lib/logging/logging.rb +62 -0
- data/lib/utils/hash_monkeypatch.rb +34 -0
- data/lib/utils/request.rb +52 -0
- data/lib/utils/retriable.rb +63 -0
- data/lib/utils/run.rb +20 -0
- data/locales/en.yml +24 -0
- data/locales/sv.yml +11 -0
- metadata +160 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6179815ad86f1edb1a7571347aecf67360b39176
|
4
|
+
data.tar.gz: a9fbac4944dcd4a58676f6cf866c1f687b1fa935
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4cb37474da862c7cfe4900f4148469f3368d72e64d6eea01201e4200025bf9c688c04d6744a9efc6320ea617f467e8968fa5b87d8bf549e7e2681ad156879327
|
7
|
+
data.tar.gz: b5b47bc9e70fe9608ec09fb0aa5a0857cb3d0741ecdf019eb14fe8e375f5b59b0baacdb4f105a9d713b56cd065ad5c558a047633bc3a6208b9768c8658040fbc
|
data/bin/interval
ADDED
File without changes
|
data/conf/gaddy.yml
ADDED
data/conf/log4r.yml
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
log4r_config:
|
2
|
+
# define all loggers ...
|
3
|
+
loggers:
|
4
|
+
- name : gaddygaddy-client
|
5
|
+
level : DEBUG
|
6
|
+
trace : 'false'
|
7
|
+
outputters:
|
8
|
+
- stderr
|
9
|
+
- stdout
|
10
|
+
- name : default
|
11
|
+
level : DEBUG
|
12
|
+
trace : 'false'
|
13
|
+
outputters:
|
14
|
+
- stderr
|
15
|
+
- stdout
|
16
|
+
- name : interval
|
17
|
+
level : DEBUG
|
18
|
+
trace : 'false'
|
19
|
+
outputters:
|
20
|
+
- stderr
|
21
|
+
- stdout
|
22
|
+
outputters:
|
23
|
+
- type : StderrOutputter
|
24
|
+
name : stderr
|
25
|
+
level : WARN
|
26
|
+
formatter:
|
27
|
+
date_pattern: '%y%m%d %H:%M:%S'
|
28
|
+
pattern : "[%5l] %d :: %m"
|
29
|
+
type : PatternFormatter
|
30
|
+
|
31
|
+
- type : StdoutOutputter
|
32
|
+
name : stdout
|
33
|
+
level : DEBUG
|
34
|
+
formatter:
|
35
|
+
date_pattern: '%y%m%d %H:%M:%S'
|
36
|
+
pattern : "[%5l] %d :: %m"
|
37
|
+
type : PatternFormatter
|
38
|
+
|
39
|
+
- type : StderrOutputter
|
40
|
+
name : stderr_test
|
41
|
+
level : ERROR
|
42
|
+
formatter:
|
43
|
+
date_pattern: '%y%m%d %H:%M:%S'
|
44
|
+
# Added 'M' and 't' here - they are slow, but we're not calling unless we need to
|
45
|
+
pattern : "[%5l] %d :: %M :: %t"
|
46
|
+
type : PatternFormatter
|
47
|
+
|
data/conf/test.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
file_dir: ../../tmp/
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# device_data.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
# Will handle data about the client like node info from Ohai that will tell everything like ip-address, macaddress,
|
10
|
+
# hw config etc. The data will be sent to the GaddyGaddy service
|
11
|
+
#
|
12
|
+
# Copyright (c) 2013 GaddyGaddy
|
13
|
+
#
|
14
|
+
# All rights reserved.
|
15
|
+
#
|
16
|
+
|
17
|
+
require_relative '../logging/logging'
|
18
|
+
require 'ohai'
|
19
|
+
|
20
|
+
class DeviceInfo
|
21
|
+
include Logging
|
22
|
+
extend Logging
|
23
|
+
|
24
|
+
def initialize(host, gg_config)
|
25
|
+
@host = host
|
26
|
+
@gg_config = gg_config
|
27
|
+
end
|
28
|
+
|
29
|
+
# Give the host name set previous
|
30
|
+
def host
|
31
|
+
@host
|
32
|
+
end
|
33
|
+
|
34
|
+
def gg_config
|
35
|
+
@gg_config
|
36
|
+
end
|
37
|
+
|
38
|
+
# Get data about the client by using the Ohai component developed by Opscode
|
39
|
+
def get_ohai_data
|
40
|
+
Ohai::Config[:plugin_path] << '/etc/chef/ohai_plugins'
|
41
|
+
ohai_system = Ohai::System.new
|
42
|
+
ohai_system.all_plugins
|
43
|
+
ohai_system.data
|
44
|
+
end
|
45
|
+
|
46
|
+
# Get the device data, if the data does not exist get it from Ohai
|
47
|
+
def data
|
48
|
+
@data||=get_ohai_data
|
49
|
+
end
|
50
|
+
|
51
|
+
# Will post the device data to the client service
|
52
|
+
def post
|
53
|
+
url = Request.get_base_url(host) + "/device/set_device_data/1/#{gg_config.config[:user_id_salt]}/#{gg_config.config[:device_id]}/#{gg_config.config[:token]}"
|
54
|
+
logger.debug "Will post this ohai data:\n #{data}"
|
55
|
+
response = Request.client_service_post url, :ohai_data => data
|
56
|
+
logger.debug "The response for the request is #{response} #{response.class}"
|
57
|
+
raise JCouldNotPostClientDataException.new({:message=> "Could not post data to the gaddygaddy service, error code is #{response.body}"}) unless response[:status].to_i == 0
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# chef_files.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
|
12
|
+
|
13
|
+
DEFAULT_FILE_HOST_PORT = 80
|
14
|
+
|
15
|
+
require_relative '../utils/run'
|
16
|
+
|
17
|
+
class ChefFiles
|
18
|
+
|
19
|
+
include Logging
|
20
|
+
|
21
|
+
def initialize(config, ap_host, chef_dir)
|
22
|
+
@config = config
|
23
|
+
@ap_host = ap_host
|
24
|
+
@chef_dir = chef_dir
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get the version of cookbook installed at the system
|
28
|
+
|
29
|
+
def installed_cookbook_version
|
30
|
+
installed_versions = Dir.glob(File.join(@chef_dir, 'cookbooks_version_[0-9]*'))
|
31
|
+
installed_versions.size > 0 ? installed_versions.map{|file| File.basename(file.split('_')[2])}.max : 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_version_file(version)
|
35
|
+
File.open(File.join(@chef_dir,'cookbooks_version_' + version.to_s), "w") do |f|
|
36
|
+
f.puts "Version: #{version}"
|
37
|
+
f.puts "Created at #{Time.now}"
|
38
|
+
f.close
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_cookbook_version
|
43
|
+
response = Request.client_service_get @ap_host, "/chef/cookbooks_version/1/#{@config.user_id_salt}/#{@config.device_id}/#{@config.token}"
|
44
|
+
raise "Could not get cookbook version" unless response['cookbooks_version']
|
45
|
+
logger.debug "Got cookbook version: #{response}"
|
46
|
+
response['cookbooks_version']
|
47
|
+
end
|
48
|
+
|
49
|
+
# Will return cookbook_uri depending on cookbook version
|
50
|
+
# -1 is not supported in production
|
51
|
+
def cookbook_path(prod_version, version)
|
52
|
+
if prod_version
|
53
|
+
'/' + URI.encode("pkg/gg_chef_#{version}.tar.gz")
|
54
|
+
else
|
55
|
+
'/chef/latest_cookbook'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Will check version of installed cookbooks and update if it's old
|
61
|
+
#
|
62
|
+
def get_cookbooks(file_host, cookbooks_version)
|
63
|
+
version = cookbooks_version ? cookbooks_version : get_cookbook_version.to_s
|
64
|
+
installed_version = installed_cookbook_version.to_s
|
65
|
+
prod_version = version.split('_')[0].to_s != '0'
|
66
|
+
return if installed_version.size > 0 && (installed_version.to_s == version.to_s) && prod_version
|
67
|
+
tmp_file = "/tmp/cookbooks-#{version}.tar.gz"
|
68
|
+
port = DEFAULT_FILE_HOST_PORT
|
69
|
+
file_host = prod_version ? file_host : @ap_host
|
70
|
+
# The file host should be without http or port
|
71
|
+
file_host = file_host.split("://")[1] if file_host.index("://")
|
72
|
+
file_host,port = file_host.split(":") if file_host.index(":")
|
73
|
+
Net::HTTP.start(file_host, port) do |http|
|
74
|
+
begin
|
75
|
+
http.read_timeout = 500
|
76
|
+
file = open(tmp_file, 'wb')
|
77
|
+
logger.debug "Will request the cookbooks files from http://#{file_host}:#{port}#{cookbook_path(prod_version, version)}"
|
78
|
+
result = http.request_get(cookbook_path(prod_version, version)) do |response|
|
79
|
+
response.read_body do |segment|
|
80
|
+
file.write(segment)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
logger.debug "The tar cookbook request response was #{result.inspect}"
|
84
|
+
ensure
|
85
|
+
file.close
|
86
|
+
end
|
87
|
+
end
|
88
|
+
logger.debug "Will untar the file to #{@chef_dir} and then remove file #{tmp_file}"
|
89
|
+
FileUtils.mkdir_p @chef_dir
|
90
|
+
# Check that the tar file is valid first
|
91
|
+
cmd = "tar --test-label -zvf #{tmp_file} && rm -rf #{@chef_dir}/* && tar -C #{@chef_dir} -zxvf #{tmp_file}"
|
92
|
+
run_cmd cmd
|
93
|
+
create_version_file version
|
94
|
+
cmd_remove = "rm #{tmp_file}"
|
95
|
+
run_cmd cmd_remove
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# espeak.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
# Will manage espeak
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
require 'stringex'
|
17
|
+
|
18
|
+
class ESpeak
|
19
|
+
|
20
|
+
def self.speak to_speak
|
21
|
+
file_name = to_speak.to_ascii.replace_whitespace('-').gsub('/','-')
|
22
|
+
wav_file = "/tmp/#{file_name}.wav"
|
23
|
+
`/usr/bin/espeak -w #{wav_file} "#{to_speak}"` unless File.exist?(wav_file)
|
24
|
+
`/usr/bin/aplay #{wav_file}`
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# log_data.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
# Will get log_data from a log file
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
class LogData
|
17
|
+
|
18
|
+
#
|
19
|
+
# Get a specific number of lines from a log file
|
20
|
+
#
|
21
|
+
def self.get_log_data(log_file_name, lines)
|
22
|
+
unless log_file_name.index('/')
|
23
|
+
log_file_name = log_file_name + '.log' unless log_file_name[-4..-1] == '.log'
|
24
|
+
log_file_name = "/opt/log/#{log_file_name[0..-5]}/#{log_file_name}"
|
25
|
+
end
|
26
|
+
raise "File #{log_file_name} does not exist" unless File.exist?(log_file_name)
|
27
|
+
cmd = "tail -n #{lines} #{log_file_name}"
|
28
|
+
exit_code, stdout = systemu cmd
|
29
|
+
if exit_code.success?
|
30
|
+
stdout
|
31
|
+
else
|
32
|
+
'Could not read log_data from ' + log_file_name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Get the time when the log file was last modified
|
38
|
+
#
|
39
|
+
def self.get_log_file_time(log_file_name)
|
40
|
+
File.mtime(log_file_name).to_s
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# espeak.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
# Will notify via the speakers
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
require_relative '../espeak'
|
17
|
+
|
18
|
+
module Notification
|
19
|
+
class ESpeakNotification
|
20
|
+
|
21
|
+
def self.espeak?
|
22
|
+
`whereis espeak`.index('bin')
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.notify(event, message_text)
|
26
|
+
if espeak?
|
27
|
+
ESpeak.speak message_text
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# file.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
# Will write the notification to a file
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
module Notification
|
17
|
+
|
18
|
+
class FileNotification
|
19
|
+
|
20
|
+
def self.file_dir= file_dir
|
21
|
+
@file_dir = file_dir
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.file_dir
|
25
|
+
@file_dir
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.notify(event, message_text)
|
29
|
+
f=File.open(File.join(file_dir,'gaddy_notification.log'), 'a')
|
30
|
+
f.write "#{event['event_time'].strftime('%Y-%m-%d %H:%M')} #{event['type']} #{message_text}\n"
|
31
|
+
f.fsync
|
32
|
+
f.close
|
33
|
+
end
|
34
|
+
|
35
|
+
# This will check if the text is already in the log file
|
36
|
+
def self.text_in_log_file message
|
37
|
+
log_file=File.join(file_dir,'gaddy_notification.log')
|
38
|
+
`/bin/grep '#{message}' #{log_file} `.strip.length > 0
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# file.rb
|
4
|
+
#
|
5
|
+
# Created by: mansson
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
# Will write the notification to a file
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
module Notification
|
17
|
+
|
18
|
+
class FileNotification
|
19
|
+
|
20
|
+
def self.file_dir= file_dir
|
21
|
+
@file_dir = file_dir
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.file_dir
|
25
|
+
@file_dir
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.notify(event, message_text)
|
29
|
+
f=File.open(File.join(file_dir,'gaddy_notification.log'), 'w')
|
30
|
+
f.write "#{event['event_time'].strftime('%Y-%m-%d %H:%M')} #{event['type']} #{message_text}\n"
|
31
|
+
f.close
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# sensu.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
module Notification
|
17
|
+
|
18
|
+
SENSU_HOST = 'localhost'
|
19
|
+
SENSU_PORT = 3030
|
20
|
+
|
21
|
+
class Sensu
|
22
|
+
# To change this template use File | Settings | File Templates.
|
23
|
+
def self.notify(event, message_text)
|
24
|
+
report = {
|
25
|
+
:name => "gaddy_notification",
|
26
|
+
:output => event.to_json,
|
27
|
+
:status => 2,
|
28
|
+
:handler => 'send_event'
|
29
|
+
}
|
30
|
+
|
31
|
+
begin
|
32
|
+
s = TCPSocket.open(SENSU_HOST, SENSU_PORT)
|
33
|
+
s.print JSON.generate(report)
|
34
|
+
s.close
|
35
|
+
rescue Exception => e
|
36
|
+
puts e.message
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# wall.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
|
11
|
+
module Notification
|
12
|
+
class Wall
|
13
|
+
|
14
|
+
def self.wall?
|
15
|
+
`whereis wall`.index('bin')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.notify(event, message_text)
|
19
|
+
if wall?
|
20
|
+
systemu("echo 'Gaddy says: #{message_text}'|wall")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Name:
|
3
|
+
# notification.rb
|
4
|
+
#
|
5
|
+
# Created by: GaddyGaddy
|
6
|
+
#
|
7
|
+
# Description:
|
8
|
+
#
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Copyright (c) 2013 GaddyGaddy
|
12
|
+
#
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
|
16
|
+
require_relative '../logging/logging'
|
17
|
+
require_relative 'notification/file_notification'
|
18
|
+
require_relative 'notification/espeak'
|
19
|
+
require_relative 'notification/sensu'
|
20
|
+
require_relative 'notification/wall'
|
21
|
+
require 'i18n'
|
22
|
+
|
23
|
+
module Notification
|
24
|
+
class Send
|
25
|
+
include Logging
|
26
|
+
|
27
|
+
def initialize(options = {})
|
28
|
+
I18n.load_path += Dir[File.join(File.dirname(__FILE__), '..','..','locales', '*.yml').to_s]
|
29
|
+
@speech_enabled = options[:speech_enabled]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Language is english for now, we need to add a language parameter to the user info or config for gaddygaddy
|
33
|
+
def language
|
34
|
+
'en'
|
35
|
+
end
|
36
|
+
|
37
|
+
def event= event
|
38
|
+
@event = JSON.parse(event)
|
39
|
+
end
|
40
|
+
|
41
|
+
def event
|
42
|
+
@event
|
43
|
+
end
|
44
|
+
|
45
|
+
def message_as_text
|
46
|
+
logger.debug "Will create message from event #{event['message_key']}"
|
47
|
+
translated_text = I18n.t event['message_key'], {locale: language}
|
48
|
+
count_values = translated_text.split("%").count - 1
|
49
|
+
if event['message_values']||count_values > 0
|
50
|
+
if count_values == event['message_values'].length
|
51
|
+
translated_text % event['message_values']
|
52
|
+
else
|
53
|
+
raise "Mismatch between the text for #{event['message_key']} - #{translated_text} have #{count_values} %s and the size of event values array is #{event['message_values'].length}"
|
54
|
+
end
|
55
|
+
else
|
56
|
+
translated_text
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Will do notifications to different sources like log file, web site and even speak
|
61
|
+
|
62
|
+
def notify(device_id)
|
63
|
+
event['event_time'] = Time.now unless event['event_time']
|
64
|
+
event['device_id'] = device_id
|
65
|
+
# Need to test before we put stuff in log file
|
66
|
+
should_speak = ! Notification::FileNotification.text_in_log_file(message_as_text)
|
67
|
+
Notification::Wall.notify(event, message_as_text)
|
68
|
+
Notification::FileNotification.notify(event, message_as_text)
|
69
|
+
Notification::Sensu.notify(event, message_as_text)
|
70
|
+
Notification::ESpeakNotification.notify(event, message_as_text) if should_speak && @speech_enabled
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|