bipbip 0.5.24 → 0.6.0
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 +4 -4
- data/bin/bipbip +5 -3
- data/lib/bipbip.rb +3 -1
- data/lib/bipbip/agent.rb +33 -64
- data/lib/bipbip/config.rb +62 -0
- data/lib/bipbip/plugin.rb +42 -39
- data/lib/bipbip/version.rb +1 -1
- metadata +4 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dad495dcac92d89bce9202405e212fc5395cdc2
|
4
|
+
data.tar.gz: 63e38ea535ac06437ab9f15bcb916f74d8b6fc1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18dfce67a0feeb23f8370ff3d20c49dd574f2087a2e6f9fc6e3a9cd215144bff93bb73e6b887fd156396492542e74aed87c3b914a54b711c48b159996ef09fd0
|
7
|
+
data.tar.gz: 80f6389027697b47ed98bad817bea8335cee6ef8ee0f741eadf44626dc73e65e86ac3252615aa96aa615e75fc26ce7fb71ac02e45135462ba3359f685a3aa3e1
|
data/bin/bipbip
CHANGED
@@ -29,7 +29,7 @@ end
|
|
29
29
|
|
30
30
|
begin
|
31
31
|
optparse.parse!
|
32
|
-
|
32
|
+
unless options[:config]
|
33
33
|
puts "Missing options: config file [-c PATH]"
|
34
34
|
exit
|
35
35
|
end
|
@@ -40,8 +40,10 @@ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
|
40
40
|
end
|
41
41
|
|
42
42
|
begin
|
43
|
-
Bipbip::
|
43
|
+
config = Bipbip::Config.factory_from_file(options[:config])
|
44
|
+
agent = Bipbip::Agent.new(config)
|
45
|
+
agent.run
|
44
46
|
rescue => e
|
45
|
-
Bipbip.logger.fatal e.message + "\n" + e.backtrace.map{|s| "\t#{s}"}.join("\n")
|
47
|
+
Bipbip.logger.fatal e.message + "\n" + e.backtrace.map { |s| "\t#{s}" }.join("\n")
|
46
48
|
exit 1
|
47
49
|
end
|
data/lib/bipbip.rb
CHANGED
@@ -7,12 +7,14 @@ module Bipbip
|
|
7
7
|
require 'logger'
|
8
8
|
require 'socket'
|
9
9
|
require 'shellwords'
|
10
|
+
require 'thwait'
|
11
|
+
require 'timeout'
|
10
12
|
|
11
13
|
require 'interruptible_sleep'
|
12
|
-
require 'process_exists'
|
13
14
|
|
14
15
|
require 'bipbip/version'
|
15
16
|
require 'bipbip/helper'
|
17
|
+
require 'bipbip/config'
|
16
18
|
require 'bipbip/agent'
|
17
19
|
require 'bipbip/storage'
|
18
20
|
require 'bipbip/plugin'
|
data/lib/bipbip/agent.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
module Bipbip
|
2
2
|
|
3
3
|
class Agent
|
4
|
+
include InterruptibleSleep
|
4
5
|
|
5
6
|
PLUGIN_RESPAWN_DELAY = 5
|
6
7
|
|
7
8
|
attr_accessor :plugins
|
8
9
|
attr_accessor :storages
|
10
|
+
attr_accessor :threads
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
@
|
12
|
+
# @param [Bipbip::Config] config
|
13
|
+
def initialize(config)
|
14
|
+
@plugins = config.plugins
|
15
|
+
@storages = config.storages
|
16
|
+
Bipbip.logger = config.logger
|
13
17
|
|
14
|
-
|
18
|
+
@threads = []
|
15
19
|
end
|
16
20
|
|
17
21
|
def run
|
@@ -29,88 +33,53 @@ module Bipbip
|
|
29
33
|
end
|
30
34
|
end
|
31
35
|
|
32
|
-
['INT', 'TERM'].each
|
33
|
-
|
36
|
+
['INT', 'TERM'].each do |sig|
|
37
|
+
trap(sig) do
|
38
|
+
Bipbip.logger.info "Received signal #{sig}, interrupting..."
|
34
39
|
interrupt
|
35
|
-
exit
|
36
40
|
end
|
37
|
-
|
41
|
+
end
|
38
42
|
|
39
43
|
@plugins.each do |plugin|
|
40
44
|
Bipbip.logger.info "Starting plugin #{plugin.name} with config #{plugin.config}"
|
41
|
-
plugin
|
45
|
+
start_plugin(plugin, @storages)
|
42
46
|
end
|
43
47
|
|
44
48
|
@interrupted = false
|
45
49
|
until @interrupted
|
46
|
-
|
50
|
+
thread = ThreadsWait.new(@threads).next_wait
|
51
|
+
@threads.delete(thread)
|
52
|
+
plugin = thread['plugin']
|
47
53
|
next if @interrupted
|
48
|
-
plugin = plugin_by_pid(pid)
|
49
|
-
Bipbip.logger.error "Plugin #{plugin.name} with config #{plugin.config} died. Respawning..."
|
50
|
-
sleep(PLUGIN_RESPAWN_DELAY)
|
51
|
-
plugin.run(@storages)
|
52
|
-
end
|
53
|
-
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
'logfile' => STDOUT,
|
59
|
-
'loglevel' => 'INFO',
|
60
|
-
'frequency' => 60,
|
61
|
-
'include' => nil,
|
62
|
-
'services' => [],
|
63
|
-
'tags' => [],
|
64
|
-
}.merge(config)
|
65
|
-
|
66
|
-
Bipbip.logger = Logger.new(config['logfile'])
|
67
|
-
Bipbip.logger.level = Logger::const_get(config['loglevel'])
|
68
|
-
|
69
|
-
services = config['services'].to_a
|
70
|
-
if config['include']
|
71
|
-
include_path = File.expand_path(config['include'].to_s, File.dirname(config_file))
|
72
|
-
|
73
|
-
files = Dir[include_path + '/**/*.yaml', include_path + '/**/*.yml']
|
74
|
-
services += files.map { |file| YAML.load(File.open(file)) }
|
75
|
-
end
|
76
|
-
|
77
|
-
@plugins = services.map do |service|
|
78
|
-
plugin_name = service['plugin']
|
79
|
-
metric_group = service['metric_group']
|
80
|
-
frequency = service['frequency'].nil? ? config['frequency'] : service['frequency']
|
81
|
-
tags = config['tags'].to_a + service['tags'].to_a
|
82
|
-
plugin_config = service.reject { |key, value| ['plugin', 'frequency', 'tags', 'metric_group'].include?(key) }
|
83
|
-
Bipbip::Plugin.factory(plugin_name, plugin_config, frequency, tags, metric_group)
|
84
|
-
end
|
55
|
+
Bipbip.logger.error "Plugin #{plugin.name} with config #{plugin.config} terminated. Restarting..."
|
56
|
+
interruptible_sleep(PLUGIN_RESPAWN_DELAY)
|
57
|
+
next if @interrupted
|
85
58
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
59
|
+
# Re-instantiate plugin to get rid of existing database-connections etc
|
60
|
+
plugin_new = Bipbip::Plugin.factory_from_plugin(plugin)
|
61
|
+
@plugins.delete(plugin)
|
62
|
+
@plugins.push(plugin_new)
|
63
|
+
start_plugin(plugin_new, @storages)
|
91
64
|
end
|
92
65
|
end
|
93
66
|
|
94
67
|
def interrupt
|
95
68
|
@interrupted = true
|
96
|
-
|
97
|
-
|
98
|
-
@plugins.each do |plugin|
|
99
|
-
Process.kill('TERM', plugin.pid) if Process.exists?(plugin.pid)
|
69
|
+
@threads.each do |thread|
|
70
|
+
thread.terminate
|
100
71
|
end
|
101
|
-
|
102
|
-
Bipbip.logger.info 'Waiting for all plugin processes to exit...'
|
103
|
-
Process.waitall
|
72
|
+
interrupt_sleep
|
104
73
|
end
|
105
74
|
|
106
75
|
private
|
107
76
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
77
|
+
# @param [Bipbip::Plugin] plugin
|
78
|
+
# @param [Array<Bipbip::Storage>] storages
|
79
|
+
def start_plugin(plugin, storages)
|
80
|
+
thread = Thread.new { plugin.run(storages) }
|
81
|
+
thread['plugin'] = plugin
|
82
|
+
@threads.push(thread)
|
114
83
|
end
|
115
84
|
end
|
116
85
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Bipbip
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
attr_reader :plugins
|
6
|
+
attr_reader :storages
|
7
|
+
attr_reader :logger
|
8
|
+
|
9
|
+
# @param [String] file_path
|
10
|
+
# @return [Bipbip::Config]
|
11
|
+
def self.factory_from_file(file_path)
|
12
|
+
config = YAML.load(File.open(file_path))
|
13
|
+
config = {
|
14
|
+
'logfile' => STDOUT,
|
15
|
+
'loglevel' => 'INFO',
|
16
|
+
'frequency' => 60,
|
17
|
+
'include' => nil,
|
18
|
+
'services' => [],
|
19
|
+
'tags' => [],
|
20
|
+
}.merge(config)
|
21
|
+
|
22
|
+
logger = Logger.new(config['logfile'])
|
23
|
+
logger.level = Logger::const_get(config['loglevel'])
|
24
|
+
|
25
|
+
plugins_config = config['services'].to_a
|
26
|
+
if config['include']
|
27
|
+
include_path = File.expand_path(config['include'].to_s, File.dirname(file_path))
|
28
|
+
|
29
|
+
files = Dir[include_path + '/**/*.yaml', include_path + '/**/*.yml']
|
30
|
+
plugins_config += files.map { |file| YAML.load(File.open(file)) }
|
31
|
+
end
|
32
|
+
|
33
|
+
plugins = plugins_config.map do |service|
|
34
|
+
plugin_name = service['plugin']
|
35
|
+
metric_group = service['metric_group']
|
36
|
+
frequency = service['frequency'].nil? ? config['frequency'] : service['frequency']
|
37
|
+
tags = config['tags'].to_a + service['tags'].to_a
|
38
|
+
plugin_config = service.reject { |key, value| ['plugin', 'frequency', 'tags', 'metric_group'].include?(key) }
|
39
|
+
Bipbip::Plugin.factory(plugin_name, plugin_config, frequency, tags, metric_group)
|
40
|
+
end
|
41
|
+
|
42
|
+
storages_config = config['storages'].to_a
|
43
|
+
storages = storages_config.map do |storage|
|
44
|
+
storage_name = storage['name'].to_s
|
45
|
+
storage_config = storage.reject { |key, value| ['name'].include?(key) }
|
46
|
+
Bipbip::Storage.factory(storage_name, storage_config)
|
47
|
+
end
|
48
|
+
|
49
|
+
Bipbip::Config.new(plugins, storages, logger)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param [Array<Bipbip::Plugin>] [plugins]
|
53
|
+
# @param [Array<Bipbip::Storage>] [storages]
|
54
|
+
# @param [Logger] [logger]
|
55
|
+
def initialize(plugins = nil, storages = nil, logger = nil)
|
56
|
+
@plugins = plugins || []
|
57
|
+
@storages = storages || []
|
58
|
+
@logger = logger || Logger.new(STDOUT)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/bipbip/plugin.rb
CHANGED
@@ -1,19 +1,30 @@
|
|
1
1
|
module Bipbip
|
2
2
|
|
3
3
|
class Plugin
|
4
|
+
|
5
|
+
class MeasurementTimeout < RuntimeError
|
6
|
+
end
|
7
|
+
|
4
8
|
include InterruptibleSleep
|
5
9
|
|
6
10
|
attr_accessor :name
|
7
11
|
attr_accessor :config
|
8
|
-
attr_accessor :
|
12
|
+
attr_accessor :frequency
|
9
13
|
attr_accessor :tags
|
10
|
-
attr_accessor :
|
14
|
+
attr_accessor :metric_group
|
11
15
|
|
12
16
|
def self.factory(name, config, frequency, tags, metric_group = nil)
|
13
17
|
require "bipbip/plugin/#{Bipbip::Helper.name_to_filename(name)}"
|
14
18
|
Plugin::const_get(Bipbip::Helper.name_to_classname(name)).new(name, config, frequency, tags, metric_group)
|
15
19
|
end
|
16
20
|
|
21
|
+
# @param [Bipbip::Plugin] plugin
|
22
|
+
# @return [Bipbip::Plugin]
|
23
|
+
def self.factory_from_plugin(plugin)
|
24
|
+
class_name = plugin.class.name.gsub(/^Bipbip::/, '')
|
25
|
+
Bipbip::const_get(class_name).new(plugin.name, plugin.config, plugin.frequency, plugin.tags, plugin.metric_group)
|
26
|
+
end
|
27
|
+
|
17
28
|
def initialize(name, config, frequency, tags = nil, metric_group = nil)
|
18
29
|
@name = name.to_s
|
19
30
|
@config = config.to_hash
|
@@ -22,49 +33,30 @@ module Bipbip
|
|
22
33
|
@metric_group = (metric_group || name).to_s
|
23
34
|
end
|
24
35
|
|
36
|
+
# @param [Array] storages
|
25
37
|
def run(storages)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
begin
|
33
|
-
until interrupted? do
|
34
|
-
time = Time.now
|
35
|
-
data = monitor
|
36
|
-
if data.empty?
|
37
|
-
raise "#{name} #{source_identifier}: Empty data"
|
38
|
-
end
|
39
|
-
log(Logger::DEBUG, "Data: #{data}")
|
40
|
-
storages.each do |storage|
|
41
|
-
storage.store_sample(self, time, data)
|
42
|
-
end
|
43
|
-
retry_delay = frequency
|
44
|
-
interruptible_sleep (frequency - (Time.now - time))
|
38
|
+
begin
|
39
|
+
timeout = frequency * 2
|
40
|
+
while true
|
41
|
+
time = Time.now
|
42
|
+
Timeout::timeout(timeout, MeasurementTimeout) do
|
43
|
+
run_measurement(frequency, storages)
|
45
44
|
end
|
46
|
-
|
47
|
-
log_exception(Logger::ERROR, e)
|
48
|
-
interruptible_sleep retry_delay
|
49
|
-
retry_delay += frequency if retry_delay < frequency * 10
|
50
|
-
retry
|
51
|
-
rescue Exception => e
|
52
|
-
log_exception(Logger::FATAL, e)
|
53
|
-
raise e
|
45
|
+
interruptible_sleep (frequency - (Time.now - time))
|
54
46
|
end
|
47
|
+
rescue MeasurementTimeout => e
|
48
|
+
log(Logger::ERROR, "Measurement timeout of #{timeout} seconds reached.")
|
49
|
+
retry
|
50
|
+
rescue StandardError => e
|
51
|
+
log_exception(Logger::ERROR, e)
|
52
|
+
interruptible_sleep frequency
|
53
|
+
retry
|
54
|
+
rescue Exception => e
|
55
|
+
log_exception(Logger::FATAL, e)
|
56
|
+
raise e
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
def interrupt
|
59
|
-
log(Logger::INFO, "Interrupting plugin process #{Process.pid}")
|
60
|
-
@interrupted = true
|
61
|
-
interrupt_sleep
|
62
|
-
end
|
63
|
-
|
64
|
-
def interrupted?
|
65
|
-
@interrupted || Process.getpgid(Process.ppid) != Process.getpgrp
|
66
|
-
end
|
67
|
-
|
68
60
|
def frequency
|
69
61
|
@frequency
|
70
62
|
end
|
@@ -91,6 +83,17 @@ module Bipbip
|
|
91
83
|
|
92
84
|
private
|
93
85
|
|
86
|
+
def run_measurement(time, storages)
|
87
|
+
data = monitor
|
88
|
+
if data.empty?
|
89
|
+
raise "#{name} #{source_identifier}: Empty data"
|
90
|
+
end
|
91
|
+
log(Logger::DEBUG, "Data: #{data}")
|
92
|
+
storages.each do |storage|
|
93
|
+
storage.store_sample(self, time, data)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
94
97
|
def log(severity, message)
|
95
98
|
Bipbip.logger.add(severity, message, "#{name} #{source_identifier}")
|
96
99
|
end
|
data/lib/bipbip/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bipbip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cargo Media
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-04-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: copperegg-revealmetrics
|
@@ -138,20 +138,6 @@ dependencies:
|
|
138
138
|
- - "~>"
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '1.10'
|
141
|
-
- !ruby/object:Gem::Dependency
|
142
|
-
name: process_exists
|
143
|
-
requirement: !ruby/object:Gem::Requirement
|
144
|
-
requirements:
|
145
|
-
- - "~>"
|
146
|
-
- !ruby/object:Gem::Version
|
147
|
-
version: 0.1.3
|
148
|
-
type: :runtime
|
149
|
-
prerelease: false
|
150
|
-
version_requirements: !ruby/object:Gem::Requirement
|
151
|
-
requirements:
|
152
|
-
- - "~>"
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
version: 0.1.3
|
155
141
|
- !ruby/object:Gem::Dependency
|
156
142
|
name: rb-inotify
|
157
143
|
requirement: !ruby/object:Gem::Requirement
|
@@ -222,6 +208,7 @@ files:
|
|
222
208
|
- data/php-opcache-status.php
|
223
209
|
- lib/bipbip.rb
|
224
210
|
- lib/bipbip/agent.rb
|
211
|
+
- lib/bipbip/config.rb
|
225
212
|
- lib/bipbip/helper.rb
|
226
213
|
- lib/bipbip/plugin.rb
|
227
214
|
- lib/bipbip/plugin/apache2.rb
|
@@ -268,7 +255,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
268
255
|
version: '0'
|
269
256
|
requirements: []
|
270
257
|
rubyforge_project:
|
271
|
-
rubygems_version: 2.4.
|
258
|
+
rubygems_version: 2.4.6
|
272
259
|
signing_key:
|
273
260
|
specification_version: 4
|
274
261
|
summary: Gather services data and store in CopperEgg
|