cloudscale 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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +33 -0
  4. data/bin/autospec +16 -0
  5. data/bin/bundler +16 -0
  6. data/bin/htmldiff +16 -0
  7. data/bin/ldiff +16 -0
  8. data/bin/monitor +16 -0
  9. data/bin/rake +16 -0
  10. data/bin/rspec +16 -0
  11. data/lib/cloudscale.rb +127 -0
  12. data/lib/cloudscale/monitor/agent/init.rb +63 -0
  13. data/lib/cloudscale/monitor/agent/init_charts.rb +60 -0
  14. data/lib/cloudscale/monitor/agent/init_menus.rb +44 -0
  15. data/lib/cloudscale/monitor/agent/preops/general_preop.rb +34 -0
  16. data/lib/cloudscale/monitor/agent/preops/preop.rb +72 -0
  17. data/lib/cloudscale/monitor/model/agent/agent_instance.rb +33 -0
  18. data/lib/cloudscale/monitor/model/agent/agent_instance_settings.rb +26 -0
  19. data/lib/cloudscale/monitor/model/constants/agent_instance_store.rb +42 -0
  20. data/lib/cloudscale/monitor/model/constants/agent_store.rb +23 -0
  21. data/lib/cloudscale/monitor/model/constants/influxdb_store.rb +23 -0
  22. data/lib/cloudscale/monitor/model/influxdb/influxdata.rb +28 -0
  23. data/lib/cloudscale/monitor/reporter/influxdb_reporter.rb +188 -0
  24. data/lib/cloudscale/plugins/mongo/data/os_chart.json +362 -0
  25. data/lib/cloudscale/plugins/mongo/data/os_menu.json +17 -0
  26. data/lib/cloudscale/plugins/mongo/mongo_db_status.rb +57 -0
  27. data/lib/cloudscale/plugins/mongo/mongo_replica_status.rb +103 -0
  28. data/lib/cloudscale/plugins/mongo/mongo_server_status.rb +172 -0
  29. data/lib/cloudscale/plugins/os/data/os_chart.json +362 -0
  30. data/lib/cloudscale/plugins/os/data/os_menu.json +17 -0
  31. data/lib/cloudscale/plugins/os/preops/plugin_preop.rb +56 -0
  32. data/lib/cloudscale/plugins/os/sigar_cpu_perc.rb +54 -0
  33. data/lib/cloudscale/plugins/os/sigar_disk_iops.rb +55 -0
  34. data/lib/cloudscale/plugins/os/sigar_disk_space.rb +54 -0
  35. data/lib/cloudscale/plugins/os/sigar_net_byte_information.rb +53 -0
  36. data/lib/cloudscale/plugins/os/sigar_packet_information.rb +63 -0
  37. data/lib/cloudscale/plugins/os/sigar_ram_usage.rb +46 -0
  38. data/lib/cloudscale/plugins/os/sigar_swap_usage.rb +46 -0
  39. data/lib/cloudscale/plugins/plugin.rb +98 -0
  40. data/lib/cloudscale/plugins/postgres/postgres_server_status.rb +143 -0
  41. data/lib/cloudscale/plugins/preops/plugin_mongodb_preop.rb +105 -0
  42. data/lib/cloudscale/plugins/preops/plugin_postgres_preop.rb +70 -0
  43. data/lib/cloudscale/registry.rb +48 -0
  44. data/lib/cloudscale/rest/rest_client.rb +198 -0
  45. data/lib/cloudscale/rest/rest_client_helper.rb +70 -0
  46. data/lib/cloudscale/schedule.rb +32 -0
  47. data/lib/cloudscale/store/agent/agent.store +7 -0
  48. data/lib/cloudscale/store/agent/agent_instance.store +11 -0
  49. data/lib/cloudscale/store/agent/influxdb.store +6 -0
  50. data/lib/cloudscale/store/plugin/token +1 -0
  51. data/lib/cloudscale/version.rb +8 -0
  52. data/lib/test/rest/rest_client_test.rb +50 -0
  53. data/lib/test/sigar/sigar_test.rb +36 -0
  54. metadata +264 -0
@@ -0,0 +1,44 @@
1
+ require "yaml"
2
+ require "logger"
3
+ require "json"
4
+ require "#{File.dirname(__FILE__)}/../../rest/rest_client"
5
+
6
+ ##
7
+ #
8
+ # @author Johannes Hiemer.
9
+ #
10
+ ##
11
+ module Cloudscale
12
+ module Monitor
13
+ class InitMenus
14
+ attr_accessor :log, :customer, :agentInstanceId, :server, :client
15
+
16
+ def initialize(agentInstanceId, path)
17
+ if (agentInstanceId == nil)
18
+ raise "InitMenu.new(): AgentInstanceId may not be null"
19
+ end
20
+
21
+ @log = Logger.new(STDOUT)
22
+ @log.info("Initializing Menu")
23
+ @client = RestClientWrapper.instance
24
+
25
+ file = File.read(path);
26
+ plugin = YAML.load(JSON.parse(file).to_yaml)
27
+ plugin.each do | key, value |
28
+ init_menu(value, agentInstanceId)
29
+ end
30
+ end
31
+
32
+ def init_menu(menuItem, agentInstanceId)
33
+ menuItem["agentInstanceId"] = agentInstanceId
34
+ test_menu = @client.searchOne("menus", "findByAgentInstanceIdAndMenuId", { :agentInstanceId => agentInstanceId, :menuId => menuItem["menuId"]})
35
+ if (test_menu == nil)
36
+ client.post("menus", menuItem)
37
+ else
38
+ client.patch("menus", RestClientWrapper.load_entity_id(test_menu), menuItem)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ require "optparse"
2
+ require "logger"
3
+ require "#{File.dirname(__FILE__)}/preop"
4
+
5
+ ##
6
+ #
7
+ # @author Johannes Hiemer.
8
+ #
9
+ ##
10
+ module Cloudscale
11
+ module Monitor
12
+ class GeneralPreop < Preops::Preop
13
+ include Singleton
14
+
15
+ @@options = {
16
+ :token => {
17
+ :argument => "--token",
18
+ :description => "The Token, which is automatically generated in your Account for Monitoring",
19
+ :required => true,
20
+ :value => nil
21
+ },
22
+ }
23
+
24
+ def options
25
+ @@options
26
+ end
27
+
28
+ def initialize
29
+ self.init
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,72 @@
1
+ require "#{File.dirname(__FILE__)}/../../../registry"
2
+ require "#{File.dirname(__FILE__)}/../init_charts"
3
+ require "#{File.dirname(__FILE__)}/../init_menus"
4
+
5
+ ##
6
+ #
7
+ # @author Johannes Hiemer.
8
+ #
9
+ ##
10
+ module Cloudscale
11
+ module Preops
12
+ class Preop
13
+ attr_accessor :log, :registry
14
+
15
+ def init
16
+ @log = Logger.new(STDOUT)
17
+ @registry = Monitor::Registry.instance
18
+ @plugin_settings_db = FSDB::Database.new("#{File.dirname(__FILE__)}/../../../store/plugin/")
19
+ init_options()
20
+ end
21
+
22
+ def set_option_value(key, val)
23
+ options[key.to_sym][:value] = val
24
+ end
25
+
26
+ def get_option(key)
27
+ options[key.to_sym]
28
+ end
29
+
30
+ def get_option_value(key)
31
+ options[key.to_sym][:value] #|| @plugin_settings_db[key.to_s]
32
+ end
33
+
34
+ def init_options
35
+ @plugin_settings_db.fetch.each do | key |
36
+ if (options[key.to_sym])
37
+ options[key.to_sym][:value] = @plugin_settings_db[key]
38
+ end
39
+ end
40
+ end
41
+
42
+ def save_options
43
+ options.each do | key, value |
44
+ @plugin_settings_db[key.to_s] = value[:value].to_s
45
+ end
46
+ end
47
+
48
+ def clear_options
49
+ @plugin_settings_db.fetch.each do | element |
50
+ @plugin_settings_db.delete(element)
51
+ end
52
+ end
53
+
54
+ def init_charts(path)
55
+ log.info("Starting monitoring chart synchronization...")
56
+
57
+ Monitor::InitCharts.new(@registry.agent_instance_id, path)
58
+
59
+ log.info("Successfully synchronized charts...")
60
+ end
61
+
62
+ def init_menus(path)
63
+ log.info("Starting monitoring menu synchronization...")
64
+
65
+ Monitor::InitMenus.new(@registry.agent_instance_id, path)
66
+
67
+ log.info("Successfully synchronized menus...")
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,33 @@
1
+ require "hashable"
2
+
3
+ ##
4
+ #
5
+ # @author Johannes Hiemer.
6
+ #
7
+ ##
8
+ module Cloudscale
9
+ module Monitor
10
+ class AgentInstance
11
+ include Hashable
12
+
13
+ attr_accessor :agent, :agentInstanceId, :token, :server, :settings,
14
+ :started
15
+
16
+ def initialize(agent, agentInstanceId, token, server, settings, started)
17
+ @agent = agent
18
+ @agentInstanceId = agentInstanceId
19
+ @token = token
20
+ @server = server
21
+ @settings = settings
22
+ @started = started
23
+ end
24
+
25
+ def to_h
26
+ hash = {}
27
+ instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
28
+ return hash
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ require "hashable"
2
+
3
+ ##
4
+ #
5
+ # @author Johannes Hiemer.
6
+ #
7
+ ##
8
+ module Cloudscale
9
+ module Monitor
10
+ class Settings
11
+ include Hashable
12
+
13
+ attr_reader :measurementCollectionInterval, :coredataCollectionInterval, :tableCollectionInterval,
14
+ :reportingInterval
15
+
16
+ def initialize(measurementCollectionInterval, coredataCollectionInterval,
17
+ tableCollectionInterval, reportingInterval)
18
+ @measurementCollectionInterval = measurementCollectionInterval
19
+ @coredataCollectionInterval = coredataCollectionInterval
20
+ @tableCollectionInterval = tableCollectionInterval
21
+ @reportingInterval = reportingInterval
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,42 @@
1
+ require "yaml/store"
2
+
3
+ ##
4
+ #
5
+ # @author Johannes Hiemer.
6
+ #
7
+ ##
8
+ module Cloudscale
9
+ module Constants
10
+ class AgentInstance
11
+
12
+ @@AGENT_INSTANCE_STORE_PATH = "#{File.dirname(__FILE__)}/../../../store/agent/agent_instance.store"
13
+
14
+ def self.create(hash)
15
+ settings = YAML::Store.new(@@AGENT_INSTANCE_STORE_PATH)
16
+
17
+ settings.transaction {
18
+ hash.each { | key, value |
19
+ settings[key] = value
20
+ }
21
+ }
22
+ end
23
+
24
+ def self.load
25
+ begin
26
+ YAML.load(File.read(@@AGENT_INSTANCE_STORE_PATH))
27
+ rescue
28
+ return nil
29
+ end
30
+ end
31
+
32
+
33
+ def self.remove
34
+ file = File.read(@@AGENT_INSTANCE_STORE_PATH)
35
+ if (file)
36
+ File.delete(@@AGENT_INSTANCE_STORE_PATH)
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,23 @@
1
+ require "yaml/store"
2
+
3
+ ##
4
+ #
5
+ # @author Johannes Hiemer.
6
+ #
7
+ ##
8
+ module Cloudscale
9
+ module Constants
10
+ class Agent
11
+
12
+ @@AGENT_STORE = "#{File.dirname(__FILE__)}/../../../store/agent/agent.store"
13
+
14
+ def self.load
15
+ begin
16
+ YAML.load(File.read(@@AGENT_STORE))
17
+ rescue
18
+ return nil
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ require "yaml/store"
2
+
3
+ ##
4
+ #
5
+ # @author Johannes Hiemer.
6
+ #
7
+ ##
8
+ module Cloudscale
9
+ module Constants
10
+ class InfluxDb
11
+
12
+ @@INFLUXDB_STORE = "#{File.dirname(__FILE__)}/../../../store/agent/influxdb.store"
13
+
14
+ def self.load
15
+ begin
16
+ YAML.load(File.read(@@INFLUXDB_STORE))
17
+ rescue
18
+ return nil
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ require "hashable"
2
+
3
+ ##
4
+ #
5
+ # @author Johannes Hiemer.
6
+ #
7
+ ##
8
+ module Cloudscale
9
+ module Monitor
10
+ class InfluxData
11
+ include Hashable
12
+
13
+ attr_accessor :columns, :points
14
+
15
+ def initialize(columns, points)
16
+ @columns = columns
17
+ @points = points
18
+ end
19
+
20
+ def to_h
21
+ hash = {}
22
+ instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
23
+ return hash
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,188 @@
1
+ require "singleton"
2
+ require "influxdb"
3
+ require "#{File.dirname(__FILE__)}/../../registry"
4
+ require "#{File.dirname(__FILE__)}/../model/constants/influxdb_store"
5
+
6
+ ##
7
+ #
8
+ # @author Johannes Hiemer.
9
+ #
10
+ ##
11
+ module Cloudscale
12
+ module Monitor
13
+ class InfluxDbReporter
14
+ include Singleton
15
+
16
+ @@prefix = Monitor::Registry.instance.agent_instance_id + "."
17
+
18
+ @@iDB = Constants::InfluxDb.load
19
+
20
+ @@COLUMNS_TIMER = Array["time", "count", "min", "max", "mean", "std-dev",
21
+ "50-percentile", "75-percentile", "95-percentile", "99-percentile", "999-percentile",
22
+ "one-minute", "five-minute", "fifteen-minute", "mean-rate",
23
+ "run-count"
24
+ ]
25
+
26
+ @@COLUMNS_HISTOGRAM = Array["time", "count", "min", "max", "mean", "std-dev",
27
+ "50-percentile", "75-percentile", "95-percentile", "99-percentile", "999-percentile",
28
+ "run-count"
29
+ ]
30
+
31
+ @@COLUMNS_COUNT = Array["time", "count"]
32
+ @@COLUMNS_GAUGE = Array["time", "value"]
33
+ @@COLUMNS_METER = Array["time", "count", "one-minute", "five-minute", "fifteen-minute", "mean"]
34
+
35
+ @@pointsTimer = [[
36
+ 0,
37
+ 0,
38
+ 0.0,
39
+ 0.0,
40
+ 0.0,
41
+ 0.0,
42
+ 0.0,
43
+ 0.0,
44
+ 0.0,
45
+ 0.0,
46
+ 0.0,
47
+ 0.0,
48
+ 0.0,
49
+ 0.0,
50
+ 0,
51
+ 0
52
+ ]]
53
+
54
+ @@pointsHistogram = [[
55
+ 0,
56
+ 0,
57
+ 0.0,
58
+ 0.0,
59
+ 0.0,
60
+ 0.0,
61
+ 0.0,
62
+ 0.0,
63
+ 0.0,
64
+ 0.0,
65
+ 0,
66
+ 0
67
+ ]]
68
+
69
+ @@pointsCounter = [[
70
+ 0,
71
+ 0
72
+ ]]
73
+
74
+ @@pointsGauge = [[
75
+ 0,
76
+ 0
77
+ ]]
78
+
79
+ @@pointsMeter = [[
80
+ 0,
81
+ 0,
82
+ 0.0,
83
+ 0.0,
84
+ 0.0,
85
+ 0.0
86
+ ]]
87
+
88
+ def initialize()
89
+ end
90
+
91
+ def report(metrics)
92
+ timestamp = Time.now.to_i
93
+ metrics.each do | key, metric |
94
+ case metric
95
+ when Metrics::Instruments::Counter
96
+ reportCounter(key, metric, timestamp)
97
+ when Metrics::Instruments::Gauge
98
+ reportGauge(key, metric, timestamp)
99
+ when Metrics::Instruments::Timer
100
+ reportTimer(key, metric, timestamp)
101
+ when Metrics::Instruments::Histogram
102
+ reportHistogram(key, metric, timestamp)
103
+ when Metrics::Instruments::Meter
104
+ reportMeter(key, metric, timestamp)
105
+ else
106
+ puts 'Unhandled instrument'
107
+ end
108
+ end
109
+ end
110
+
111
+ def reportTimer(name, timer, timestamp)
112
+ p = @@pointsTimer[0]
113
+ p[0] = timestamp
114
+ p[1] = timer.count
115
+ p[2] = timer.min
116
+ p[3] = timer.max
117
+ p[4] = timer.mean
118
+ p[5] = timer.std_dev
119
+ p[6] = 0
120
+ p[7] = timer.quantiles(0.75)
121
+ p[8] = timer.quantiles(0.95)
122
+ p[9] = timer.quantiles(0.99)
123
+ p[11] = timer.one_minute_rate
124
+ p[12] = timer.five_minute_rate
125
+ p[13] = timer.fifteen_minute_rate
126
+ p[14] = timer.mean_rate
127
+ p[15] = timer.count
128
+ raise "timer dataset not equals column length" unless p.length == @@COLUMNS_TIMER.length
129
+ appendSeries(@@prefix, name, ".timer", @@COLUMNS_TIMER, p)
130
+ end
131
+
132
+ def reportHistogram(name, histogram, timestamp)
133
+ p = @@pointsHistogram[0]
134
+ p[0] = timestamp
135
+ p[1] = histogram.size
136
+ p[2] = histogram.min
137
+ p[3] = histogram.max
138
+ p[4] = histogram.mean
139
+ p[5] = histogram.std_dev
140
+ p[6] = 0
141
+ p[7] = histogram.quantiles(0.75)
142
+ p[8] = histogram.quantiles(0.95)
143
+ p[9] = histogram.quantiles(0.99)
144
+ p[11] = histogram.one_minute_rate
145
+ raise "histogram dataset not equals column length" unless p.length == @@COLUMNS_HISTOGRAM.length
146
+ appendSeries(@@prefix, name, ".histogram", @@COLUMNS_HISTOGRAM, p)
147
+ end
148
+
149
+ def reportCounter(name, counter, timestamp)
150
+ p = @@pointsCounter[0]
151
+ p[0] = timestamp
152
+ p[1] = counter.to_i
153
+ raise "counter dataset not equals column length" unless p.length == @@COLUMNS_COUNT.length
154
+ appendSeries(@@prefix, name, ".count", @@COLUMNS_COUNT, p)
155
+ end
156
+
157
+ def reportGauge(name, gauge, timestamp)
158
+ p = @@pointsGauge[0]
159
+ p[0] = timestamp
160
+ p[1] = gauge.get[:value]
161
+ raise "gauge dataset not equals column length" unless p.length == @@COLUMNS_GAUGE.length
162
+ appendSeries(@@prefix, name, ".value", @@COLUMNS_GAUGE, p)
163
+ end
164
+
165
+ def reportMeter(name, meter, timestamp)
166
+ p = @@pointsMeter[0]
167
+ p[1] = 0
168
+ p[2] = meter.one_minute_rate
169
+ p[3] = meter.five_minute_rate
170
+ p[4] = meter.fifteen_minute_rate
171
+ p[5] = meter.mean_rate
172
+ raise "meter dataset not equals column length" unless p.length == @@COLUMNS_METER.length
173
+ appendSeries(@@prefix, name, ".value", @@COLUMNS_METER, p)
174
+ end
175
+
176
+ def appendSeries(namePrefix, name, nameSuffix, columns, points)
177
+ data = Hash.new
178
+ columns.each_with_index { | val, index |
179
+ data[columns[index]] = points[index]
180
+ }
181
+ client = InfluxDB::Client.new @@iDB["database"], { :host => @@iDB["host"], :port => @@iDB["port"], :username => @@iDB["username"],
182
+ :password => @@iDB["password"] }
183
+ client.write_point(namePrefix + name + nameSuffix, data, false)
184
+ end
185
+
186
+ end
187
+ end
188
+ end