sensu 0.12.6 → 0.13.0.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +41 -0
- data/lib/sensu/api.rb +145 -205
- data/lib/sensu/cli.rb +2 -1
- data/lib/sensu/client.rb +51 -119
- data/lib/sensu/constants.rb +1 -7
- data/lib/sensu/daemon.rb +221 -0
- data/lib/sensu/server.rb +105 -202
- data/lib/sensu/socket.rb +4 -4
- data/lib/sensu/utilities.rb +6 -29
- data/sensu.gemspec +10 -6
- metadata +223 -228
- data/lib/sensu/base.rb +0 -75
- data/lib/sensu/extensions.rb +0 -162
- data/lib/sensu/extensions/handlers/debug.rb +0 -17
- data/lib/sensu/extensions/mutators/only_check_output.rb +0 -17
- data/lib/sensu/io.rb +0 -98
- data/lib/sensu/logstream.rb +0 -93
- data/lib/sensu/process.rb +0 -48
- data/lib/sensu/rabbitmq.rb +0 -106
- data/lib/sensu/settings.rb +0 -483
data/lib/sensu/base.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
gem 'oj', '2.0.9'
|
4
|
-
gem 'eventmachine', '1.0.3'
|
5
|
-
|
6
|
-
require 'time'
|
7
|
-
require 'uri'
|
8
|
-
require 'oj'
|
9
|
-
|
10
|
-
require File.join(File.dirname(__FILE__), 'constants')
|
11
|
-
require File.join(File.dirname(__FILE__), 'utilities')
|
12
|
-
require File.join(File.dirname(__FILE__), 'cli')
|
13
|
-
require File.join(File.dirname(__FILE__), 'logstream')
|
14
|
-
require File.join(File.dirname(__FILE__), 'settings')
|
15
|
-
require File.join(File.dirname(__FILE__), 'extensions')
|
16
|
-
require File.join(File.dirname(__FILE__), 'process')
|
17
|
-
require File.join(File.dirname(__FILE__), 'io')
|
18
|
-
require File.join(File.dirname(__FILE__), 'rabbitmq')
|
19
|
-
|
20
|
-
Oj.default_options = {:mode => :compat, :symbol_keys => true}
|
21
|
-
|
22
|
-
module Sensu
|
23
|
-
class Base
|
24
|
-
def initialize(options={})
|
25
|
-
@options = options
|
26
|
-
end
|
27
|
-
|
28
|
-
def logger
|
29
|
-
logger = Logger.get
|
30
|
-
if @options[:log_level]
|
31
|
-
logger.level = @options[:log_level]
|
32
|
-
end
|
33
|
-
if @options[:log_file]
|
34
|
-
logger.reopen(@options[:log_file])
|
35
|
-
end
|
36
|
-
logger.setup_traps
|
37
|
-
logger
|
38
|
-
end
|
39
|
-
|
40
|
-
def settings
|
41
|
-
settings = Settings.new
|
42
|
-
settings.load_env
|
43
|
-
if @options[:config_file]
|
44
|
-
settings.load_file(@options[:config_file])
|
45
|
-
end
|
46
|
-
if @options[:config_dirs]
|
47
|
-
@options[:config_dirs].each do |config_dir|
|
48
|
-
settings.load_directory(config_dir)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
settings.validate
|
52
|
-
settings.set_env
|
53
|
-
settings
|
54
|
-
end
|
55
|
-
|
56
|
-
def extensions
|
57
|
-
extensions = Extensions.new
|
58
|
-
if @options[:extension_dir]
|
59
|
-
extensions.require_directory(@options[:extension_dir])
|
60
|
-
end
|
61
|
-
extensions.load_all
|
62
|
-
extensions
|
63
|
-
end
|
64
|
-
|
65
|
-
def setup_process
|
66
|
-
process = Process.new
|
67
|
-
if @options[:daemonize]
|
68
|
-
process.daemonize
|
69
|
-
end
|
70
|
-
if @options[:pid_file]
|
71
|
-
process.write_pid(@options[:pid_file])
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
data/lib/sensu/extensions.rb
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
module Sensu
|
2
|
-
class Extensions
|
3
|
-
def initialize
|
4
|
-
@logger = Logger.get
|
5
|
-
@extensions = Hash.new
|
6
|
-
EXTENSION_CATEGORIES.each do |category|
|
7
|
-
@extensions[category] = Hash.new
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def [](key)
|
12
|
-
@extensions[key]
|
13
|
-
end
|
14
|
-
|
15
|
-
EXTENSION_CATEGORIES.each do |category|
|
16
|
-
define_method(category) do
|
17
|
-
@extensions[category].map do |name, extension|
|
18
|
-
extension.definition
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
define_method(category.to_s.chop + '_exists?') do |name|
|
23
|
-
@extensions[category].has_key?(name)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def require_directory(directory)
|
28
|
-
path = directory.gsub(/\\(?=\S)/, '/')
|
29
|
-
Dir.glob(File.join(path, '**/*.rb')).each do |file|
|
30
|
-
begin
|
31
|
-
require File.expand_path(file)
|
32
|
-
rescue ScriptError => error
|
33
|
-
@logger.error('failed to require extension', {
|
34
|
-
:extension_file => file,
|
35
|
-
:error => error
|
36
|
-
})
|
37
|
-
@logger.warn('ignoring extension', {
|
38
|
-
:extension_file => file
|
39
|
-
})
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def load_all
|
45
|
-
require_directory(File.join(File.dirname(__FILE__), 'extensions'))
|
46
|
-
EXTENSION_CATEGORIES.each do |category|
|
47
|
-
extension_type = category.to_s.chop
|
48
|
-
Extension.const_get(extension_type.capitalize).descendants.each do |klass|
|
49
|
-
extension = klass.new
|
50
|
-
extension.logger = @logger
|
51
|
-
@extensions[category][extension.name] = extension
|
52
|
-
loaded(extension_type, extension.name, extension.description)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def load_settings(settings={})
|
58
|
-
all_extensions.each do |extension|
|
59
|
-
extension.settings = settings
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def stop_all(&block)
|
64
|
-
extensions = all_extensions
|
65
|
-
stopper = Proc.new do |extension|
|
66
|
-
if extension.nil?
|
67
|
-
block.call
|
68
|
-
else
|
69
|
-
extension.stop do
|
70
|
-
stopper.call(extensions.pop)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
stopper.call(extensions.pop)
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def all_extensions
|
80
|
-
all = @extensions.map do |category, extensions|
|
81
|
-
extensions.map do |name, extension|
|
82
|
-
extension
|
83
|
-
end
|
84
|
-
end
|
85
|
-
all.flatten
|
86
|
-
end
|
87
|
-
|
88
|
-
def loaded(type, name, description)
|
89
|
-
@logger.info('loaded extension', {
|
90
|
-
:type => type,
|
91
|
-
:name => name,
|
92
|
-
:description => description
|
93
|
-
})
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
module Extension
|
98
|
-
class Base
|
99
|
-
attr_accessor :logger, :settings
|
100
|
-
|
101
|
-
def initialize
|
102
|
-
EM::next_tick do
|
103
|
-
post_init
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
def name
|
108
|
-
'base'
|
109
|
-
end
|
110
|
-
|
111
|
-
def description
|
112
|
-
'extension description (change me)'
|
113
|
-
end
|
114
|
-
|
115
|
-
def definition
|
116
|
-
{
|
117
|
-
:type => 'extension',
|
118
|
-
:name => name
|
119
|
-
}
|
120
|
-
end
|
121
|
-
|
122
|
-
def post_init
|
123
|
-
true
|
124
|
-
end
|
125
|
-
|
126
|
-
def run(data=nil, &block)
|
127
|
-
block.call('noop', 0)
|
128
|
-
end
|
129
|
-
|
130
|
-
def stop(&block)
|
131
|
-
block.call
|
132
|
-
end
|
133
|
-
|
134
|
-
def [](key)
|
135
|
-
definition[key.to_sym]
|
136
|
-
end
|
137
|
-
|
138
|
-
def has_key?(key)
|
139
|
-
definition.has_key?(key.to_sym)
|
140
|
-
end
|
141
|
-
|
142
|
-
def safe_run(data=nil, &block)
|
143
|
-
begin
|
144
|
-
data ? run(data.dup, &block) : run(&block)
|
145
|
-
rescue => error
|
146
|
-
block.call(error.to_s, 2)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
def self.descendants
|
151
|
-
ObjectSpace.each_object(Class).select do |klass|
|
152
|
-
klass < self
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
EXTENSION_CATEGORIES.each do |category|
|
158
|
-
extension_type = category.to_s.chop
|
159
|
-
Object.const_set(extension_type.capitalize, Class.new(Base))
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Sensu
|
2
|
-
module Extension
|
3
|
-
class OnlyCheckOutput < Mutator
|
4
|
-
def name
|
5
|
-
'only_check_output'
|
6
|
-
end
|
7
|
-
|
8
|
-
def description
|
9
|
-
'returns check output'
|
10
|
-
end
|
11
|
-
|
12
|
-
def run(event, &block)
|
13
|
-
block.call(event[:check][:output], 0)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/sensu/io.rb
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
gem 'em-worker', '0.0.2'
|
2
|
-
|
3
|
-
require 'timeout'
|
4
|
-
require 'em/worker'
|
5
|
-
|
6
|
-
module Sensu
|
7
|
-
class IO
|
8
|
-
class << self
|
9
|
-
def popen(command, mode='r', timeout=nil, &block)
|
10
|
-
block ||= Proc.new {}
|
11
|
-
begin
|
12
|
-
if RUBY_VERSION < '1.9.3'
|
13
|
-
child = ::IO.popen(command + ' 2>&1', mode)
|
14
|
-
block.call(child)
|
15
|
-
wait_on_process(child, false)
|
16
|
-
else
|
17
|
-
options = {
|
18
|
-
:err => [:child, :out]
|
19
|
-
}
|
20
|
-
case RUBY_PLATFORM
|
21
|
-
when /(ms|cyg|bcc)win|mingw|win32/
|
22
|
-
shell = ['cmd', '/c']
|
23
|
-
options[:new_pgroup] = true
|
24
|
-
else
|
25
|
-
shell = ['sh', '-c']
|
26
|
-
options[:pgroup] = true
|
27
|
-
end
|
28
|
-
child = ::IO.popen(shell + [command, options], mode)
|
29
|
-
if timeout
|
30
|
-
Timeout.timeout(timeout) do
|
31
|
-
block.call(child)
|
32
|
-
wait_on_process(child)
|
33
|
-
end
|
34
|
-
else
|
35
|
-
block.call(child)
|
36
|
-
wait_on_process(child)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
rescue Timeout::Error
|
40
|
-
kill_process_group(child.pid)
|
41
|
-
wait_on_process_group(child.pid)
|
42
|
-
['Execution timed out', 2]
|
43
|
-
rescue => error
|
44
|
-
kill_process_group(child.pid)
|
45
|
-
wait_on_process_group(child.pid)
|
46
|
-
raise error
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def async_popen(command, data=nil, timeout=nil, &block)
|
51
|
-
execute = Proc.new do
|
52
|
-
begin
|
53
|
-
popen(command, 'r+', timeout) do |child|
|
54
|
-
unless data.nil?
|
55
|
-
child.write(data.to_s)
|
56
|
-
end
|
57
|
-
child.close_write
|
58
|
-
end
|
59
|
-
rescue => error
|
60
|
-
[error.to_s, 2]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
complete = Proc.new do |output, status|
|
64
|
-
block.call(output, status) if block
|
65
|
-
end
|
66
|
-
@async_popen_worker ||= EM::Worker.new
|
67
|
-
@async_popen_worker.enqueue(execute, complete)
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def kill_process_group(group_id)
|
73
|
-
begin
|
74
|
-
::Process.kill(9, -group_id)
|
75
|
-
rescue Errno::ESRCH, Errno::EPERM
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def wait_on_process_group(group_id)
|
80
|
-
begin
|
81
|
-
loop do
|
82
|
-
::Process.wait2(-group_id)
|
83
|
-
end
|
84
|
-
rescue Errno::ECHILD
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def wait_on_process(process, wait_on_group=true)
|
89
|
-
output = process.read
|
90
|
-
_, status = ::Process.wait2(process.pid)
|
91
|
-
if wait_on_group
|
92
|
-
wait_on_process_group(process.pid)
|
93
|
-
end
|
94
|
-
[output, status.exitstatus || 2]
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
data/lib/sensu/logstream.rb
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
module Sensu
|
2
|
-
class LogStream
|
3
|
-
def initialize
|
4
|
-
@log_stream = EM::Queue.new
|
5
|
-
@log_level = :info
|
6
|
-
STDOUT.sync = true
|
7
|
-
STDERR.reopen(STDOUT)
|
8
|
-
setup_writer
|
9
|
-
end
|
10
|
-
|
11
|
-
def level=(level)
|
12
|
-
@log_level = level
|
13
|
-
end
|
14
|
-
|
15
|
-
def level_filtered?(level)
|
16
|
-
LOG_LEVELS.index(level) < LOG_LEVELS.index(@log_level)
|
17
|
-
end
|
18
|
-
|
19
|
-
def add(level, *arguments)
|
20
|
-
unless level_filtered?(level)
|
21
|
-
log_event = create_log_event(level, *arguments)
|
22
|
-
if EM::reactor_running?
|
23
|
-
@log_stream << log_event
|
24
|
-
else
|
25
|
-
puts log_event
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
LOG_LEVELS.each do |level|
|
31
|
-
define_method(level) do |*arguments|
|
32
|
-
add(level, *arguments)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def reopen(file)
|
37
|
-
@log_file = file
|
38
|
-
if File.writable?(file) || !File.exist?(file) && File.writable?(File.dirname(file))
|
39
|
-
STDOUT.reopen(file, 'a')
|
40
|
-
STDOUT.sync = true
|
41
|
-
STDERR.reopen(STDOUT)
|
42
|
-
else
|
43
|
-
error('log file is not writable', {
|
44
|
-
:log_file => file
|
45
|
-
})
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def setup_traps
|
50
|
-
if Signal.list.include?('USR1')
|
51
|
-
Signal.trap('USR1') do
|
52
|
-
@log_level = @log_level == :info ? :debug : :info
|
53
|
-
end
|
54
|
-
end
|
55
|
-
if Signal.list.include?('USR2')
|
56
|
-
Signal.trap('USR2') do
|
57
|
-
if @log_file
|
58
|
-
reopen(@log_file)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def create_log_event(level, message, data=nil)
|
67
|
-
log_event = Hash.new
|
68
|
-
log_event[:timestamp] = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%6N%z")
|
69
|
-
log_event[:level] = level
|
70
|
-
log_event[:message] = message
|
71
|
-
if data.is_a?(Hash)
|
72
|
-
log_event.merge!(data)
|
73
|
-
end
|
74
|
-
Oj.dump(log_event)
|
75
|
-
end
|
76
|
-
|
77
|
-
def setup_writer
|
78
|
-
writer = Proc.new do |log_event|
|
79
|
-
puts log_event
|
80
|
-
EM::next_tick do
|
81
|
-
@log_stream.pop(&writer)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
@log_stream.pop(&writer)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class Logger
|
89
|
-
def self.get
|
90
|
-
@logger ||= LogStream.new
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|