kurchatov 0.0.1
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/.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
|