ducksboard_reporter 0.1.9 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97c05a91c7f6ad158d30731b2a67495ca44cc88b
4
- data.tar.gz: c2f89dc1cbeaca7c2c836118839e1dedc19c3d88
3
+ metadata.gz: 11d10360f1a5542c45e2a91f852fb0f34dd3e0ff
4
+ data.tar.gz: 8f9c0b770d84c021a69950d4c878cc02b53908df
5
5
  SHA512:
6
- metadata.gz: 1f678da73b2bdf7111138ca50cc7bf0dd7aec014a2931e95c864e1141f2881e95da4dfde00e02a393b55f4c0edaa4327428c9988a97a0f9a43e4334be9b7a222
7
- data.tar.gz: e75957dc461d82f0774f6fcf6f5332b21503155e507847148ddfdd874566ea423997e247350bc7a2ecffb3c23d5e50024f1e86c9d3f78961a967ce066c18e1b1
6
+ metadata.gz: 6dbc5a31490055edb80c6f9e15a0cc1f4c3fce47cf5db3fd57c9092b052f9bbd991a60a45268933c683a52ec10b9f64803595df8a226be1e5c3056c56591fcf6
7
+ data.tar.gz: 7b04ea73a6c0cbf1dbfe55d129c79d9162c1693f0e44e4891dc9aa8aa9bda30b5f6f66440f1e7a6ee17cc15f3d40cde96233cdc6045afd48a2c16ff78d4eb707
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.2
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # DucksboardReporter
2
2
 
3
- TODO: Write a gem description
3
+ Ducksnoard is a cool dashboard as a service like geckoboard but looks nicer. This project can be seen as a infrastructure for and a collection of reporters that report values to ducksboard. In a way reporters are similar to nagios agents, but for generation pokemon. Surely it could turn into a more abstract reporter framework that can report to geckoboard, nagios, whatever aswell. Right now we use ducksboard, so it is for ducksboard.
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,7 +18,19 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
- TODO: Write usage instructions here
21
+ To run your reporters just launch it via
22
+
23
+ ducksboard_reporter -f /your/config_file.yml
24
+
25
+ See example_config.yml for in about the format etc.
26
+
27
+ To run in a production environment you could wrap in into a daemon and let it be managed by the init system du jour.
28
+
29
+ You can build new reporters by inheriting from DucksboardReporter::Reporters::Reporter and implement your own #collect method which must set @value. See existing reporters for examples.
30
+
31
+ ## Changelog
32
+
33
+ * bumped version number to 0.2.0 since it now has mysql reporters
22
34
 
23
35
  ## Contributing
24
36
 
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec"
24
24
  spec.add_development_dependency "fuubar"
25
- spec.add_development_dependency "byebug"
25
+ spec.add_development_dependency "parallel_tests"
26
26
 
27
27
  spec.add_runtime_dependency "ducksboard", "~> 0.1.6"
28
28
  spec.add_runtime_dependency "hashie", ">= 3.3.1"
data/example_config.yml CHANGED
@@ -10,14 +10,9 @@ reporters:
10
10
  options:
11
11
  log_file: haproxy.log
12
12
 
13
- - name: honeybadger
14
- type: Honeybadger
15
- options:
16
- api_key: 58L5pGcr82Vm11G1HHG6
17
- project_id: 2948
18
-
19
13
  widgets:
20
14
  - type: Box
21
15
  id: 506475
22
- reporter: honeybadger
23
- value: :unresolved_fault_count
16
+ reporter: random
17
+ value:
18
+ current: :value
@@ -1,11 +1,9 @@
1
1
  require "rubygems"
2
-
3
2
  require "logger"
4
3
  require "celluloid"
5
4
  require "timers"
6
5
  require "ducksboard"
7
6
  require "hashie/extensions/symbolize_keys"
8
- Hash.include Hashie::Extensions::SymbolizeKeys
9
7
 
10
8
  require "ducksboard_reporter/version"
11
9
  require "ducksboard_reporter/reporter"
@@ -19,6 +17,10 @@ require "ducksboard_reporter/reporters/haproxy_log_requests"
19
17
  require "ducksboard_reporter/reporters/cpu_usage"
20
18
  require "ducksboard_reporter/reporters/bandwidth"
21
19
  require "ducksboard_reporter/reporters/honeybadger"
20
+ require "ducksboard_reporter/reporters/mysql_base"
21
+ require "ducksboard_reporter/reporters/mysql_queries_per_second"
22
+ require "ducksboard_reporter/reporters/mysql_slow_queries"
23
+ require "ducksboard_reporter/reporters/mysql_innodb_rows_reads_per_second"
22
24
 
23
25
  Thread.abort_on_exception = true
24
26
 
@@ -36,11 +38,24 @@ module DucksboardReporter
36
38
  attr_reader :config, :reporters, :widgets
37
39
 
38
40
  def initialize(config)
39
- @config = config.symbolize_keys!
41
+ @config = symbolize_keys(config)
40
42
  register_reporters
41
43
  register_widgets
42
44
  end
43
45
 
46
+ def symbolize_keys(hash)
47
+ hash.inject({}) do |result, (key, value)|
48
+ new_key = key.is_a?(String) ? key.to_sym : key
49
+ new_value = case value
50
+ when Hash then symbolize_keys(value)
51
+ when Array then value.map {|v| symbolize_keys(v) }
52
+ else value
53
+ end
54
+ result[new_key] = new_value
55
+ result
56
+ end
57
+ end
58
+
44
59
  def start
45
60
  Signal.trap("INT") { exit }
46
61
 
@@ -63,7 +78,6 @@ module DucksboardReporter
63
78
 
64
79
  def register_widgets
65
80
  @widgets = []
66
-
67
81
  @config[:widgets].each do |config|
68
82
  reporter = @reporters.fetch(config[:reporter])
69
83
 
@@ -1,7 +1,6 @@
1
1
  module DucksboardReporter
2
2
  module Reporters
3
3
  class CpuUsage < Reporter
4
-
5
4
  def collect
6
5
  stats = nil
7
6
  while true do
@@ -0,0 +1,37 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class MySqlBase < Reporter
4
+
5
+ def period
6
+ 1
7
+ end
8
+
9
+ def collect
10
+ update # this is important!
11
+ every(period) do
12
+ update
13
+ end
14
+ end
15
+
16
+ def update
17
+ begin
18
+ @current_stats = gather_stats
19
+ rescue Errno::ENOENT
20
+ error("MysqlQueriesPerSecond: failed to use mysqladmin status")
21
+ return
22
+ end
23
+
24
+ self.value = moderated_stats
25
+ end
26
+
27
+ def moderated_stats
28
+ # default is to just take the absolute value
29
+ @current_stats
30
+ end
31
+
32
+ def gather_stats
33
+ raise NotImplementedError
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,10 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class MySqlInnodbRowsReadsPerSecond < MySqlBase
4
+ def gather_stats
5
+ out = `mysql -e 'SHOW ENGINE INNODB STATUS\\G'`.scan(/([-+]?[0-9]*\.?[0-9]+) (reads\/s)/)
6
+ out.nil? ? 0 : out[2][0]
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class MySqlQueriesPerSecond < MySqlBase
4
+ def gather_stats
5
+ out = `mysqladmin status`.match(/(Queries per second avg: )([-+]?[0-9]*\.?[0-9]+)/)
6
+ out.nil? ? 0 : out[2]
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class MySqlSlowQueries < MySqlBase
4
+
5
+ def period
6
+ 60
7
+ end
8
+
9
+ def gather_stats
10
+ out = `mysqladmin status`.match(/(Slow queries: )([-+]?[0-9]*\.?[0-9]+)/)
11
+ out.nil? ? 0 : out[2]
12
+ end
13
+
14
+ def moderated_stats
15
+ # in this case we want to know the delta
16
+ delta = @current_stats.to_i - @old_stats.to_i
17
+ @old_stats = @current_stats
18
+ debug(log_format("old: #{@old_stats}, current: #{@current_stats}, delta: #{delta}, thread id: #{Thread.current.object_id}"))
19
+ delta
20
+ end
21
+ end
22
+ end
23
+ end
@@ -8,4 +8,3 @@ module DucksboardReporter
8
8
  end
9
9
  end
10
10
  end
11
-
@@ -1,3 +1,3 @@
1
1
  module DucksboardReporter
2
- VERSION = "0.1.9"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  module DucksboardReporter
2
2
  class Widget
3
+
3
4
  include Celluloid
4
5
  include Celluloid::Logger
5
6
 
@@ -26,8 +27,8 @@ module DucksboardReporter
26
27
  debug log_format("Updating value #{value}")
27
28
 
28
29
  @updater.update(value)
29
- rescue Net::ReadTimeout, Net::OpenTimeout
30
- # accept timeout errors
30
+ rescue *timeout_errors, Errno::ECONNRESET => e
31
+ error e
31
32
  end
32
33
 
33
34
  def interval
@@ -66,6 +67,15 @@ module DucksboardReporter
66
67
  object
67
68
  end
68
69
  end
70
+
71
+ def timeout_errors
72
+ v = RUBY_VERSION.split(".")[0].to_i
73
+ if v >= 2
74
+ [Net::ReadTimeout, Net::OpenTimeout]
75
+ else
76
+ [Timeout::Error]
77
+ end
78
+ end
69
79
  end
70
80
  end
71
81
 
data/lib/rund.rb CHANGED
@@ -19,8 +19,6 @@ module Rund
19
19
  redirect_output
20
20
 
21
21
  close_local_stderr
22
-
23
- Process.pid
24
22
  end
25
23
 
26
24
  def log_file=(path)
@@ -11,7 +11,7 @@ describe DucksboardReporter::App do
11
11
  let(:widget) { app.widgets.first }
12
12
 
13
13
  it "registers reporters from config" do
14
- expect(app.reporters.values.map(&:class)).to include(DucksboardReporter::Reporters::Random)
14
+ expect(app.reporters.values.map(&:class)).to include(DucksboardReporter::Reporters::FooBar)
15
15
  end
16
16
 
17
17
  it "registers widgets from config" do
@@ -32,7 +32,7 @@ describe DucksboardReporter::App do
32
32
  describe "single widget" do
33
33
 
34
34
  it "sets id from config" do
35
- expect(widget.id).to eq(1234)
35
+ expect(widget.id).to eq(123123)
36
36
  end
37
37
 
38
38
  it "references reporter" do
@@ -0,0 +1,51 @@
1
+ require "spec_helper"
2
+ describe DucksboardReporter::Reporters::MySqlQueriesPerSecond do
3
+ it "loads and starts" do
4
+ expect {
5
+ reporter = DucksboardReporter::Reporters::MySqlQueriesPerSecond.new("lala")
6
+ reporter.start
7
+ }.not_to raise_error
8
+ end
9
+ end
10
+
11
+ describe DucksboardReporter::Reporters::MySqlInnodbRowsReadsPerSecond do
12
+ it "loads and starts" do
13
+ expect {
14
+ reporter = DucksboardReporter::Reporters::MySqlInnodbRowsReadsPerSecond.new("lala")
15
+ reporter.start
16
+ }.not_to raise_error
17
+ end
18
+ end
19
+
20
+ describe DucksboardReporter::Reporters::MySqlSlowQueries do
21
+ it "loads and starts" do
22
+ expect {
23
+ reporter = DucksboardReporter::Reporters::MySqlSlowQueries.new("lala")
24
+ reporter.start
25
+ }.not_to raise_error
26
+ end
27
+
28
+ it "calculates the delta per period correctly" do
29
+ # example mysql status output
30
+ # Uptime: 16076688 Threads: 174 Questions: 3193188096 Slow queries: 1235560 Opens: 2218 Flush tables: 2 Open tables: 474 Queries per second avg: 198.622
31
+ # the way the current value is gathered:
32
+ # `mysqladmin status`.match(/(Slow queries: )([-+]?[0-9]*\.?[0-9]+)/)
33
+ EXAMPLE_OUT1 = "Uptime: 16076688 Threads: 174 Questions: 3193188096 Slow queries: 10 Opens: 2218 Flush tables: 2 Open tables: 474 Queries per second avg: 198.622"
34
+ EXAMPLE_OUT2 = "Uptime: 16076688 Threads: 174 Questions: 3193188096 Slow queries: 30 Opens: 2218 Flush tables: 2 Open tables: 474 Queries per second avg: 198.622"
35
+ EXAMPLE_OUT3 = "Uptime: 16076688 Threads: 174 Questions: 3193188096 Slow queries: 130 Opens: 2218 Flush tables: 2 Open tables: 474 Queries per second avg: 198.622"
36
+ EXAMPLE_OUT4 = "Uptime: 16076688 Threads: 174 Questions: 3193188096 Slow queries: 130 Opens: 2218 Flush tables: 2 Open tables: 474 Queries per second avg: 198.622"
37
+
38
+ reporter = DucksboardReporter::Reporters::MySqlSlowQueries.new("test_reporter")
39
+
40
+ expect_any_instance_of(reporter.class).to receive(:`).and_return(EXAMPLE_OUT1, EXAMPLE_OUT2, EXAMPLE_OUT3, EXAMPLE_OUT4)
41
+ reporter.update
42
+ expect(reporter.value).to eq(10)
43
+ reporter.update
44
+ expect(reporter.value).to eq(20)
45
+ reporter.update
46
+ expect(reporter.value).to eq(100)
47
+ reporter.update
48
+ expect(reporter.value).to eq(0)
49
+
50
+ end
51
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "ducksboard_reporter"
2
- require "byebug"
3
2
 
4
3
  DucksboardReporter.logger.level = Logger::FATAL
5
4
 
6
5
  RSpec.configure do |config|
6
+ config.color = true
7
7
  end
data/spec/widget_spec.rb CHANGED
@@ -14,6 +14,7 @@ describe DucksboardReporter::Widget do
14
14
 
15
15
  let(:reporter) { WidgetReporter.new("name") }
16
16
  let(:widget) { DucksboardReporter::Widget.new("Box", 1234, reporter) }
17
+ let(:ruby_version) { RUBY_VERSION.split(".")[0].to_i }
17
18
 
18
19
  describe "#update" do
19
20
  it "updates value from reporter" do
@@ -22,12 +23,29 @@ describe DucksboardReporter::Widget do
22
23
  end
23
24
 
24
25
  it "will not crash on Net::ReadTimeout" do
25
- expect(widget.updater).to receive(:update).and_raise(Net::ReadTimeout)
26
+ if ruby_version >= 2
27
+ expect(widget.updater).to receive(:update).and_raise(Net::ReadTimeout)
28
+ end
29
+
30
+ if ruby_version < 2
31
+ expect(widget.updater).to receive(:update).and_raise(TimeoutError)
32
+ end
26
33
  widget.update
27
34
  end
28
35
 
29
36
  it "will not crash on Net::OpenTimeout" do
30
- expect(widget.updater).to receive(:update).and_raise(Net::OpenTimeout)
37
+ if ruby_version >= 2
38
+ expect(widget.updater).to receive(:update).and_raise(Net::OpenTimeout)
39
+ end
40
+
41
+ if ruby_version < 2
42
+ expect(widget.updater).to receive(:update).and_raise(TimeoutError)
43
+ end
44
+ widget.update
45
+ end
46
+
47
+ it "will not crash on Errno::ECONNRESET" do
48
+ expect(widget.updater).to receive(:update).and_raise(Errno::ECONNRESET)
31
49
  widget.update
32
50
  end
33
51
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ducksboard_reporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - unnu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-13 00:00:00.000000000 Z
11
+ date: 2015-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: byebug
70
+ name: parallel_tests
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -173,6 +173,7 @@ extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
175
  - ".gitignore"
176
+ - ".ruby-version"
176
177
  - Gemfile
177
178
  - LICENSE.txt
178
179
  - README.md
@@ -188,11 +189,17 @@ files:
188
189
  - lib/ducksboard_reporter/reporters/cpu_usage.rb
189
190
  - lib/ducksboard_reporter/reporters/haproxy_log_requests.rb
190
191
  - lib/ducksboard_reporter/reporters/honeybadger.rb
192
+ - lib/ducksboard_reporter/reporters/mysql_base.rb
193
+ - lib/ducksboard_reporter/reporters/mysql_innodb_rows_reads_per_second.rb
194
+ - lib/ducksboard_reporter/reporters/mysql_queries_per_second.rb
195
+ - lib/ducksboard_reporter/reporters/mysql_slow_queries.rb
191
196
  - lib/ducksboard_reporter/reporters/random.rb
192
197
  - lib/ducksboard_reporter/version.rb
193
198
  - lib/ducksboard_reporter/widget.rb
194
199
  - lib/rund.rb
200
+ - spec/config.yml
195
201
  - spec/ducksboard_reporter_spec.rb
202
+ - spec/mysql_reporter_spec.rb
196
203
  - spec/reporter_spec.rb
197
204
  - spec/spec_helper.rb
198
205
  - spec/widget_spec.rb
@@ -216,12 +223,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
216
223
  version: '0'
217
224
  requirements: []
218
225
  rubyforge_project:
219
- rubygems_version: 2.2.2
226
+ rubygems_version: 2.4.5
220
227
  signing_key:
221
228
  specification_version: 4
222
229
  summary: Report values to ducksboard
223
230
  test_files:
231
+ - spec/config.yml
224
232
  - spec/ducksboard_reporter_spec.rb
233
+ - spec/mysql_reporter_spec.rb
225
234
  - spec/reporter_spec.rb
226
235
  - spec/spec_helper.rb
227
236
  - spec/widget_spec.rb