sensu 0.12.6 → 0.13.0.alpha
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.
- 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
|