kurchatov 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +111 -0
- data/Rakefile +1 -0
- data/Vagrantfile +16 -0
- data/bin/kurchatov +6 -0
- data/examples/check_file_contains.rb +14 -0
- data/examples/count_proc.rb +14 -0
- data/examples/cpu.rb +29 -0
- data/examples/disk.rb +56 -0
- data/examples/disk_stat.rb +28 -0
- data/examples/dns_check.rb +5 -0
- data/examples/exim.rb +12 -0
- data/examples/file_age.rb +11 -0
- data/examples/find_files.rb +21 -0
- data/examples/http.rb +25 -0
- data/examples/iptables.rb +27 -0
- data/examples/la.rb +10 -0
- data/examples/mdadm.rb +43 -0
- data/examples/megacli.rb +12 -0
- data/examples/memory.rb +28 -0
- data/examples/net.rb +25 -0
- data/examples/net_stat.rb +25 -0
- data/examples/nfs.rb +9 -0
- data/examples/nginx.rb +22 -0
- data/examples/nginx_500.rb +48 -0
- data/examples/ntp.rb +15 -0
- data/examples/openfiles.rb +6 -0
- data/examples/pgsql.rb +67 -0
- data/examples/ping_icmp.rb +12 -0
- data/examples/ping_tcp.rb +14 -0
- data/examples/proc_mem.rb +24 -0
- data/examples/process_usage.rb +15 -0
- data/examples/rabbitmq.rb +16 -0
- data/examples/runit.rb +47 -0
- data/examples/sidekiq.rb +21 -0
- data/examples/sidekiq_queue_state.rb +9 -0
- data/examples/status_file.rb +14 -0
- data/examples/tw_cli.rb +17 -0
- data/examples/uptime.rb +14 -0
- data/kurchatov.gemspec +28 -0
- data/lib/kurchatov/application.rb +154 -0
- data/lib/kurchatov/config.rb +14 -0
- data/lib/kurchatov/log.rb +9 -0
- data/lib/kurchatov/mashie.rb +152 -0
- data/lib/kurchatov/mixin/command.rb +31 -0
- data/lib/kurchatov/mixin/event.rb +63 -0
- data/lib/kurchatov/mixin/http.rb +21 -0
- data/lib/kurchatov/mixin/init.rb +6 -0
- data/lib/kurchatov/mixin/ohai.rb +22 -0
- data/lib/kurchatov/mixin/queue.rb +14 -0
- data/lib/kurchatov/monitor.rb +62 -0
- data/lib/kurchatov/plugin/config.rb +68 -0
- data/lib/kurchatov/plugin/dsl.rb +81 -0
- data/lib/kurchatov/plugin/riemann.rb +54 -0
- data/lib/kurchatov/plugin.rb +15 -0
- data/lib/kurchatov/queue.rb +28 -0
- data/lib/kurchatov/responders/http.rb +36 -0
- data/lib/kurchatov/responders/init.rb +3 -0
- data/lib/kurchatov/responders/riemann.rb +46 -0
- data/lib/kurchatov/responders/udp.rb +32 -0
- data/lib/kurchatov/riemann/client.rb +49 -0
- data/lib/kurchatov/riemann/event.rb +42 -0
- data/lib/kurchatov/riemann/message.rb +18 -0
- data/lib/kurchatov/version.rb +3 -0
- data/lib/kurchatov.rb +3 -0
- data/lib/ohai/plugins/darwin/hostname.rb +22 -0
- data/lib/ohai/plugins/darwin/platform.rb +38 -0
- data/lib/ohai/plugins/hostname.rb +27 -0
- data/lib/ohai/plugins/linux/hostname.rb +26 -0
- data/lib/ohai/plugins/linux/platform.rb +113 -0
- data/lib/ohai/plugins/linux/virtualization.rb +125 -0
- data/lib/ohai/plugins/os.rb +53 -0
- data/lib/ohai/plugins/platform.rb +28 -0
- data/lib/ohai/plugins/virtualization.rb +86 -0
- data/lib/ohai/plugins/windows/hostname.rb +33 -0
- data/lib/ohai/plugins/windows/platform.rb +27 -0
- data/tests/run.sh +55 -0
- metadata +209 -0
@@ -0,0 +1,152 @@
|
|
1
|
+
class Mashie < Hash
|
2
|
+
|
3
|
+
def initialize(source_hash = nil, default = nil, &blk)
|
4
|
+
deep_update(source_hash) if source_hash
|
5
|
+
default ? super(default) : super(&blk)
|
6
|
+
end
|
7
|
+
|
8
|
+
class << self; alias [] new; end
|
9
|
+
|
10
|
+
def id #:nodoc:
|
11
|
+
self["id"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def type #:nodoc:
|
15
|
+
self["type"]
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :regular_reader, :[]
|
19
|
+
alias_method :regular_writer, :[]=
|
20
|
+
|
21
|
+
def custom_reader(key)
|
22
|
+
value = regular_reader(convert_key(key))
|
23
|
+
yield value if block_given?
|
24
|
+
value
|
25
|
+
end
|
26
|
+
|
27
|
+
def custom_writer(key,value) #:nodoc:
|
28
|
+
regular_writer(convert_key(key), convert_value(value))
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :[], :custom_reader
|
32
|
+
alias_method :[]=, :custom_writer
|
33
|
+
|
34
|
+
def initializing_reader(key)
|
35
|
+
ck = convert_key(key)
|
36
|
+
regular_writer(ck, self.class.new) unless key?(ck)
|
37
|
+
regular_reader(ck)
|
38
|
+
end
|
39
|
+
|
40
|
+
def underbang_reader(key)
|
41
|
+
ck = convert_key(key)
|
42
|
+
if key?(ck)
|
43
|
+
regular_reader(ck)
|
44
|
+
else
|
45
|
+
self.class.new
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch(key, *args)
|
50
|
+
super(convert_key(key), *args)
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete(key)
|
54
|
+
super(convert_key(key))
|
55
|
+
end
|
56
|
+
|
57
|
+
alias_method :regular_dup, :dup
|
58
|
+
# Duplicates the current mash as a new mash.
|
59
|
+
def dup
|
60
|
+
self.class.new(self, self.default)
|
61
|
+
end
|
62
|
+
|
63
|
+
def key?(key)
|
64
|
+
super(convert_key(key))
|
65
|
+
end
|
66
|
+
alias_method :has_key?, :key?
|
67
|
+
alias_method :include?, :key?
|
68
|
+
alias_method :member?, :key?
|
69
|
+
|
70
|
+
def deep_merge(other_hash, &blk)
|
71
|
+
dup.deep_update(other_hash, &blk)
|
72
|
+
end
|
73
|
+
alias_method :merge, :deep_merge
|
74
|
+
|
75
|
+
def deep_update(other_hash, &blk)
|
76
|
+
other_hash.each_pair do |k,v|
|
77
|
+
key = convert_key(k)
|
78
|
+
if regular_reader(key).is_a?(Mash) and v.is_a?(::Hash)
|
79
|
+
custom_reader(key).deep_update(v, &blk)
|
80
|
+
else
|
81
|
+
value = convert_value(v, true)
|
82
|
+
value = blk.call(key, self[k], value) if blk
|
83
|
+
custom_writer(key, value)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
self
|
87
|
+
end
|
88
|
+
alias_method :deep_merge!, :deep_update
|
89
|
+
alias_method :update, :deep_update
|
90
|
+
alias_method :merge!, :update
|
91
|
+
|
92
|
+
def shallow_merge(other_hash)
|
93
|
+
dup.shallow_update(other_hash)
|
94
|
+
end
|
95
|
+
|
96
|
+
def shallow_update(other_hash)
|
97
|
+
other_hash.each_pair do |k,v|
|
98
|
+
regular_writer(convert_key(k), convert_value(v, true))
|
99
|
+
end
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
def replace(other_hash)
|
104
|
+
(keys - other_hash.keys).each { |key| delete(key) }
|
105
|
+
other_hash.each { |key, value| self[key] = value }
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def respond_to?(method_name, include_private=false)
|
110
|
+
return true if key?(method_name) || method_name.to_s.slice(/[=?!_]\Z/)
|
111
|
+
super
|
112
|
+
end
|
113
|
+
|
114
|
+
def method_missing(method_name, *args, &blk)
|
115
|
+
return self.[](method_name, &blk) if key?(method_name)
|
116
|
+
match = method_name.to_s.match(/(.*?)([?=!_]?)$/)
|
117
|
+
case match[2]
|
118
|
+
when "="
|
119
|
+
self[match[1]] = args.first
|
120
|
+
when "?"
|
121
|
+
!!self[match[1]]
|
122
|
+
when "!"
|
123
|
+
initializing_reader(match[1])
|
124
|
+
when "_"
|
125
|
+
underbang_reader(match[1])
|
126
|
+
else
|
127
|
+
default(method_name, *args, &blk)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
protected
|
132
|
+
|
133
|
+
def convert_key(key) #:nodoc:
|
134
|
+
key.to_s
|
135
|
+
end
|
136
|
+
|
137
|
+
def convert_value(val, duping=false) #:nodoc:
|
138
|
+
case val
|
139
|
+
when self.class
|
140
|
+
val.dup
|
141
|
+
when Hash
|
142
|
+
duping ? val.dup : val
|
143
|
+
when ::Hash
|
144
|
+
val = val.dup if duping
|
145
|
+
self.class.new(val)
|
146
|
+
when Array
|
147
|
+
val.collect{ |e| convert_value(e) }
|
148
|
+
else
|
149
|
+
val
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "mixlib/shellout"
|
2
|
+
|
3
|
+
module Kurchatov
|
4
|
+
module Mixin
|
5
|
+
module Command
|
6
|
+
|
7
|
+
def shell_out(cmd)
|
8
|
+
mix = ::Mixlib::ShellOut.new(cmd)
|
9
|
+
mix.run_command
|
10
|
+
mix
|
11
|
+
end
|
12
|
+
|
13
|
+
def shell_out!(cmd)
|
14
|
+
mix = shell_out(cmd)
|
15
|
+
mix.error!
|
16
|
+
mix
|
17
|
+
end
|
18
|
+
|
19
|
+
def shell(cmd)
|
20
|
+
mix = shell_out!(cmd)
|
21
|
+
mix.stdout
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_unix_mem_info
|
25
|
+
pid, size = `ps ax -o pid,rss | grep -E "^[[:space:]]*#{$$}"`.strip.split.map(&:to_i)
|
26
|
+
puts "Pid: #{pid}, memusage: #{size}"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Kurchatov
|
2
|
+
module Mixin
|
3
|
+
module Event
|
4
|
+
|
5
|
+
EVENT_FIELDS = [
|
6
|
+
:time, :state, :service, :host,
|
7
|
+
:description, :tags, :ttl, :metric
|
8
|
+
]
|
9
|
+
|
10
|
+
def event(hash = {})
|
11
|
+
normilize_event(hash)
|
12
|
+
Log.info("Mock message for test plugin: #{hash.inspect}") if Kurchatov::Config[:test_plugin]
|
13
|
+
events << hash
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def normilize_event(hash = {})
|
19
|
+
hash[:description] = hash[:desc] if hash[:description].nil? && hash[:desc]
|
20
|
+
if hash[:metric].kind_of?(Float)
|
21
|
+
hash[:metric] = 0.0 if hash[:metric].nan?
|
22
|
+
hash[:metric] = hash[:metric].round(2)
|
23
|
+
end
|
24
|
+
set_diff_metric(hash)
|
25
|
+
set_event_state(hash)
|
26
|
+
hash.each {|k,_| hash.delete(k) unless EVENT_FIELDS.include?(k)}
|
27
|
+
hash[:service] ||= name
|
28
|
+
hash[:tags] ||= Kurchatov::Config[:tags]
|
29
|
+
hash[:host] ||= Kurchatov::Config[:host]
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_event_state(hash = {})
|
33
|
+
return if hash[:state]
|
34
|
+
return if hash[:critical].nil? && hash[:warning].nil?
|
35
|
+
return if hash[:metric].nil?
|
36
|
+
if hash[:state] == true || hash[:state] == false
|
37
|
+
hash[:state] = hash[:state] ? 'ok' : 'critical'
|
38
|
+
return
|
39
|
+
end
|
40
|
+
hash[:state] = 'ok'
|
41
|
+
hash[:state] = 'warning' if hash[:warning] && hash[:metric] >= hash[:warning]
|
42
|
+
hash[:state] = 'critical' if hash[:critical] && hash[:metric] >= hash[:critical]
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_diff_metric(hash ={})
|
46
|
+
hash[:diff] ||= hash[:as_diff] if hash[:as_diff]
|
47
|
+
return if hash[:diff].nil? && !hash[:diff]
|
48
|
+
return if hash[:metric].nil?
|
49
|
+
return if hash[:service].nil?
|
50
|
+
@history ||= {}
|
51
|
+
if @history[hash[:service]]
|
52
|
+
old_metric = @history[hash[:service]]
|
53
|
+
@history[hash[:service]] = hash[:metric]
|
54
|
+
hash[:metric] = hash[:metric] - old_metric
|
55
|
+
else
|
56
|
+
@history[hash[:service]] = hash[:metric]
|
57
|
+
hash[:metric] = nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "open-uri"
|
2
|
+
require "yajl/json_gem"
|
3
|
+
|
4
|
+
module Kurchatov
|
5
|
+
module Mixin
|
6
|
+
module Http
|
7
|
+
|
8
|
+
# /path/to/file, https://ya.ru, http://a:a@yandex.ru
|
9
|
+
def rest_get(url)
|
10
|
+
uri = URI(url)
|
11
|
+
if uri.userinfo
|
12
|
+
open("#{uri.scheme}://#{uri.hostname}:#{uri.port}#{uri.request_uri}",
|
13
|
+
:http_basic_authentication => [uri.user, uri.password]).read
|
14
|
+
else
|
15
|
+
open(url).read
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Kurchatov
|
2
|
+
|
3
|
+
module Ohai
|
4
|
+
def self.data
|
5
|
+
@ohai ||= ::Ohai::System.new
|
6
|
+
Log.info("Load ohai plugins")
|
7
|
+
@ohai.all_plugins
|
8
|
+
@ohai.data
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Mixin
|
13
|
+
module Ohai
|
14
|
+
class << self; attr_accessor :ohai_instance; end
|
15
|
+
def ohai
|
16
|
+
@ohai_instance ||= Kurchatov::Mixin::Ohai.ohai_instance ||= Kurchatov::Ohai.data
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "kurchatov/queue"
|
4
|
+
|
5
|
+
module Kurchatov
|
6
|
+
module Mixin
|
7
|
+
module Queue
|
8
|
+
class << self; attr_accessor :instance_queue end
|
9
|
+
def events
|
10
|
+
@instance_queue ||= Kurchatov::Mixin::Queue.instance_queue ||= Kurchatov::Queue.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "kurchatov/mixin/queue"
|
2
|
+
|
3
|
+
module Kurchatov
|
4
|
+
class Monitor
|
5
|
+
|
6
|
+
class Task
|
7
|
+
include Kurchatov::Mixin::Event
|
8
|
+
include Kurchatov::Mixin::Queue
|
9
|
+
attr_accessor :thread, :instance
|
10
|
+
|
11
|
+
def initialize(plugin)
|
12
|
+
@plugin = plugin
|
13
|
+
@thread = Thread.new { @plugin.run }
|
14
|
+
end
|
15
|
+
|
16
|
+
def died?
|
17
|
+
return false if @thread.alive?
|
18
|
+
# thread died, join and extract error
|
19
|
+
begin
|
20
|
+
@thread.join # call error
|
21
|
+
rescue => e
|
22
|
+
desc = "Plugin '#{@plugin.name}' died. #{e.class}: #{e}\n #{e.backtrace.join("\n")}"
|
23
|
+
Log.error(desc)
|
24
|
+
event(:service => "riemann client errors", :desc => desc, :state => 'critical')
|
25
|
+
end
|
26
|
+
@thread = Thread.new { @plugin.run }
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def status
|
31
|
+
{@plugin.name => @thread.alive?}
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_accessor :tasks
|
37
|
+
CHECK_ALIVE_TIMEOUT = 5
|
38
|
+
|
39
|
+
def initialize(stop = false)
|
40
|
+
@stop_on_error = stop
|
41
|
+
@tasks = Array.new
|
42
|
+
end
|
43
|
+
|
44
|
+
def <<(plugin)
|
45
|
+
Log.debug("Add new plugin: #{plugin.inspect}")
|
46
|
+
@tasks << Task.new(plugin)
|
47
|
+
end
|
48
|
+
|
49
|
+
def run
|
50
|
+
loop do
|
51
|
+
@tasks.each { |t| exit Config[:ERROR_PLUGIN_REQ] if t.died? && @stop_on_error }
|
52
|
+
Log.debug("Check alive plugins [#{@tasks.count}]")
|
53
|
+
sleep CHECK_ALIVE_TIMEOUT
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def tasks_status
|
58
|
+
@tasks.map {|t| t.status }
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "kurchatov/plugin/riemann"
|
2
|
+
require "kurchatov/plugin/dsl"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Kurchatov
|
6
|
+
module Plugins
|
7
|
+
module Config
|
8
|
+
|
9
|
+
def self.find_plugin(name, array)
|
10
|
+
array.find {|p| p.name == name }
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.load_plugins(plugins_path, config_file)
|
14
|
+
Log.error("Config file #{config_file} not found") and exit Kurchatov::Config[:ERROR_CONFIG] unless File.exists?(config_file)
|
15
|
+
@all_plugins = Kurchatov::Plugins::DSL.load_riemann_plugins(plugins_path)
|
16
|
+
@all_names = Array.new
|
17
|
+
@plugins_to_run = Array.new
|
18
|
+
config = YAML.load_file(config_file)
|
19
|
+
config.each do |name, val|
|
20
|
+
@all_names << name
|
21
|
+
next if val.nil?
|
22
|
+
#
|
23
|
+
# dup plugins from array
|
24
|
+
#
|
25
|
+
if val.kind_of? Array
|
26
|
+
parent = find_plugin(name, @all_plugins)
|
27
|
+
Log.error("Unable to find parent plugin for #{name}") and next if parent.nil?
|
28
|
+
val.each_with_index do |p_settings, i|
|
29
|
+
child = parent.dup
|
30
|
+
child.name = "#{name}_#{i}"
|
31
|
+
child.plugin = parent.plugin.dup
|
32
|
+
child.plugin.merge!(p_settings)
|
33
|
+
@all_plugins << child
|
34
|
+
@all_names << child.name
|
35
|
+
end
|
36
|
+
@all_plugins.delete(parent)
|
37
|
+
next
|
38
|
+
end
|
39
|
+
#
|
40
|
+
# dup plugins from 'parent'
|
41
|
+
#
|
42
|
+
if val.is_a?(Hash) && val.has_key?('parent')
|
43
|
+
parent = find_plugin(val['parent'], @all_plugins)
|
44
|
+
Log.error("Unable to find parent '#{parent_name}' for '#{name}'") and next if parent.nil?
|
45
|
+
child = parent.dup
|
46
|
+
child.name = name
|
47
|
+
child.plugin = parent.plugin.dup
|
48
|
+
child.plugin.merge!(val)
|
49
|
+
@all_plugins << child
|
50
|
+
@all_names << child.name
|
51
|
+
next
|
52
|
+
end
|
53
|
+
end
|
54
|
+
@all_plugins.each do |p|
|
55
|
+
unless p.always_start || @all_names.include?(p.name)
|
56
|
+
Log.info("Plugin '#{p.name}' not started, because it " +
|
57
|
+
"not 'always_start' and not in config file")
|
58
|
+
next
|
59
|
+
end
|
60
|
+
@plugins_to_run << p if p.runnable_by_config?
|
61
|
+
end
|
62
|
+
Log.debug("Plugins to start: #{@plugins_to_run.inspect}")
|
63
|
+
@plugins_to_run
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Kurchatov
|
2
|
+
module Plugins
|
3
|
+
class DSL
|
4
|
+
|
5
|
+
attr_reader :plugins
|
6
|
+
PLUGIN_EXT = '.rb'
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@plugins = Array.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def last
|
13
|
+
@plugins.last
|
14
|
+
end
|
15
|
+
|
16
|
+
# plugins dsl part
|
17
|
+
def always_start(val)
|
18
|
+
last.always_start = !!val
|
19
|
+
end
|
20
|
+
|
21
|
+
def interval(val)
|
22
|
+
last.interval = val
|
23
|
+
end
|
24
|
+
|
25
|
+
def name(val)
|
26
|
+
last.name = val
|
27
|
+
end
|
28
|
+
|
29
|
+
def critical(val)
|
30
|
+
last.plugin[:critical] = val
|
31
|
+
end
|
32
|
+
|
33
|
+
def warning(val)
|
34
|
+
last.plugin[:warning] = val
|
35
|
+
end
|
36
|
+
|
37
|
+
def collect(opts = {}, *args, &block)
|
38
|
+
return unless last.respond_to_ohai?(opts)
|
39
|
+
last.collect = block
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_if(opts = {}, &block)
|
43
|
+
return unless last.respond_to_ohai?(opts)
|
44
|
+
last.run_if = block
|
45
|
+
end
|
46
|
+
|
47
|
+
def last_plugin
|
48
|
+
last.plugin
|
49
|
+
end
|
50
|
+
alias :default :last_plugin
|
51
|
+
|
52
|
+
|
53
|
+
# load part
|
54
|
+
|
55
|
+
def self.load_riemann_plugins(paths)
|
56
|
+
dsl = Kurchatov::Plugins::DSL.new
|
57
|
+
paths.map do |path|
|
58
|
+
Log.error("Directory #{path} not exists") and exit Kurchatov::Config[:ERROR_CONFIG] unless File.directory? path
|
59
|
+
Dir["#{path}/*#{PLUGIN_EXT}"].sort
|
60
|
+
end.flatten.each do |path|
|
61
|
+
begin
|
62
|
+
dsl.plugins << Kurchatov::Plugins::Riemann.new(File.basename(path, PLUGIN_EXT))
|
63
|
+
dsl.instance_eval(File.read(path), path)
|
64
|
+
rescue LoadError, SyntaxError => e
|
65
|
+
dsl.plugins.pop # todo: plugin.new creates
|
66
|
+
Log.error("Load plugin from file #{path}, #{e.class}: #{e}\n #{e.backtrace.join("\n")}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
dsl.plugins
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.load_riemann_plugin(file)
|
73
|
+
dsl = Kurchatov::Plugins::DSL.new
|
74
|
+
dsl.plugins << Kurchatov::Plugins::Riemann.new(File.basename(file, PLUGIN_EXT))
|
75
|
+
dsl.instance_eval(File.read(file), file)
|
76
|
+
dsl.last
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "kurchatov/plugin"
|
4
|
+
require "kurchatov/mashie"
|
5
|
+
require "kurchatov/mixin/init"
|
6
|
+
|
7
|
+
module Kurchatov
|
8
|
+
module Plugins
|
9
|
+
class Riemann < Kurchatov::Plugin
|
10
|
+
|
11
|
+
include Kurchatov::Mixin::Queue
|
12
|
+
include Kurchatov::Mixin::Ohai
|
13
|
+
include Kurchatov::Mixin::Event
|
14
|
+
include Kurchatov::Mixin::Command
|
15
|
+
include Kurchatov::Mixin::Http
|
16
|
+
|
17
|
+
attr_accessor :run_if, :collect, :always_start, :interval, :plugin
|
18
|
+
|
19
|
+
def initialize(name = '')
|
20
|
+
super(name)
|
21
|
+
@run_if = Proc.new {true}
|
22
|
+
@plugin = Mashie.new
|
23
|
+
@always_start = false
|
24
|
+
@collect = nil
|
25
|
+
@interval = 60
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
loop do
|
30
|
+
t_start = Time.now
|
31
|
+
Timeout::timeout(interval * 2/3) do
|
32
|
+
self.instance_eval(&collect)
|
33
|
+
end
|
34
|
+
sleep(interval - (Time.now - t_start).to_i)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def respond_to_ohai?(opts = {})
|
39
|
+
opts.each { |k,v| return false unless ohai[k] == v }
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def runnable_by_config?
|
44
|
+
Log.info("Plugin '#{self.name}' disabled by nil collect") and return if collect.nil?
|
45
|
+
Log.info("Plugin '#{self.name}' disabled in config") and return if plugin[:disable] == true
|
46
|
+
Log.info("Plugin '#{self.name}' not started by run_if condition ") and
|
47
|
+
return if !self.instance_eval(&run_if)
|
48
|
+
@plugin[:service] = name if @plugin[:service].nil?
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Kurchatov
|
4
|
+
class Queue
|
5
|
+
QUEUE_MAX_SIZE = 100
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@events = ::Queue.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def <<(event)
|
12
|
+
if @events.size >= QUEUE_MAX_SIZE
|
13
|
+
drop = @events.shift
|
14
|
+
Log.error("Drop event: #{drop.inspect}. See Kurchatov::Queue::QUEUE_MAX_SIZE")
|
15
|
+
end
|
16
|
+
@events << event
|
17
|
+
end
|
18
|
+
|
19
|
+
def all
|
20
|
+
cur_events = Array.new
|
21
|
+
until @events.empty?
|
22
|
+
cur_events << @events.shift
|
23
|
+
end
|
24
|
+
cur_events
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Kurchatov
|
2
|
+
module Responders
|
3
|
+
class Http < Kurchatov::Plugin
|
4
|
+
|
5
|
+
def initialize(conn)
|
6
|
+
@host, @port = conn.split(':')
|
7
|
+
@name = "http server #{@host}:#{@port}"
|
8
|
+
@s_time = Time.now
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
@server ||= TCPServer.new(@host, @port)
|
13
|
+
loop do
|
14
|
+
client = @server.accept
|
15
|
+
response = info
|
16
|
+
headers = "HTTP/1.1 200 OK\r\n" +
|
17
|
+
"Server: Kurchatov Ruby\r\n" +
|
18
|
+
"Content-Length: #{response.bytesize}\r\n" +
|
19
|
+
"Content-Type: application/json\r\n\r\n"
|
20
|
+
client.print headers
|
21
|
+
client.print response
|
22
|
+
client.close
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def info
|
27
|
+
{
|
28
|
+
:version => Kurchatov::VERSION,
|
29
|
+
:uptime => (Time.now - @s_time).to_i,
|
30
|
+
:config => Kurchatov::Config.to_hash,
|
31
|
+
}.to_json + "\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|