ducksboard_reporter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 01a779528a28a87775f6473d1c815b52cd270862
4
+ data.tar.gz: 2d0c84b54e148009064adb03018c5083a8a7577b
5
+ SHA512:
6
+ metadata.gz: 10bc9823ca8b4115a41f94822abffa739dd23bcde0dd5c008f0637cc76df2c9ab6ccdb009575b32090f4a019155b5956a416bf73cb4b0a699c14913b136d090e
7
+ data.tar.gz: 92a734441fc61ec48a851794f3ee35ab9f2981606dd7f45ee389d1b44768f16733d1b980c51e46d3aad878bcee6c6cbe8f6b4fb720a5cb0e33897c2ca6a6dc82
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ config.yml
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ducksboard_reporter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 unnu
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # DucksboardReporter
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'ducksboard_reporter'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ducksboard_reporter
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/ducksboard_reporter/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+ $:.unshift File.expand_path("../../lib", __FILE__)
3
+
4
+ require "ducksboard_reporter"
5
+ require "trollop"
6
+
7
+ opts = Trollop::options do
8
+ opt :config_file, "Define config file", short: 'f', type: :string, required: true
9
+ end
10
+
11
+ DucksboardReporter.config_file = opts[:config_file]
12
+ DucksboardReporter.start
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ducksboard_reporter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ducksboard_reporter"
8
+ spec.version = DucksboardReporter::VERSION
9
+ spec.authors = ["unnu"]
10
+ spec.email = ["norman.timmler@gmail.com"]
11
+ spec.summary = %q{Report values to ducksboard}
12
+ spec.description = %q{Report values to ducksboard}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_runtime_dependency "ducksboard"
25
+ spec.add_runtime_dependency "hashie"
26
+ spec.add_runtime_dependency "celluloid"
27
+ spec.add_runtime_dependency "timers"
28
+ spec.add_runtime_dependency "trollop"
29
+ end
@@ -0,0 +1,16 @@
1
+ ---
2
+ api_key: YOUR_API_KEY
3
+
4
+ reporters:
5
+ - name: random
6
+ type: Random
7
+
8
+ - name: haproxy_log_requests
9
+ type: HaproxyLogRequests
10
+ logfile: /var/log/haproxy.log
11
+
12
+ widgets:
13
+ - type: Box
14
+ id: 506475
15
+ reporter: random
16
+ value: value
@@ -0,0 +1,34 @@
1
+ module DucksboardReporter
2
+ class Reporter
3
+ include Celluloid
4
+ include Celluloid::Logger
5
+
6
+ attr_reader :options, :value
7
+
8
+ def initialize(options = {})
9
+ @options = options
10
+ end
11
+
12
+ def start
13
+ debug log_format("Started")
14
+ async.collect
15
+ end
16
+
17
+ def collect; end
18
+
19
+ def timestamp
20
+ @timestamp || Time.now.to_i
21
+ end
22
+
23
+ def to_s
24
+ options.name
25
+ end
26
+
27
+ private
28
+
29
+ def log_format(msg)
30
+ @log_prefix ||= "Reporter #{self.class.name.split("::").last}(#{to_s}): "
31
+ @log_prefix + msg
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class Bandwidth < Reporter
4
+
5
+ def collect
6
+ @tx_bytes = 0
7
+
8
+ while true do
9
+ begin
10
+ current_tx_bytes = File.read("/sys/class/net/eth0/statistics/tx_bytes").to_i
11
+ rescue Errno::ENOENT
12
+ error("Bandwidth: Cannot open /sys/class/net/eth0/statistics/tx_bytes")
13
+ return
14
+ end
15
+
16
+ if @tx_bytes == 0
17
+ @tx_bytes = current_tx_bytes
18
+ next
19
+ end
20
+
21
+ @value = (current_tx_bytes - @tx_bytes) * 8
22
+ @tx_bytes = current_tx_bytes
23
+ sleep 1
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,32 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class CpuUsage < Reporter
4
+
5
+ def collect
6
+ stats = nil
7
+ while true do
8
+ begin
9
+ current_stats = File.readlines("/proc/stat").grep(/\Acpu /).first.split[1,4].map(&:to_i)
10
+ rescue Errno::ENOENT
11
+ error("CpuUsage: Cannot open /proc/stat")
12
+ return
13
+ end
14
+
15
+ sleep 1
16
+
17
+ unless stats
18
+ stats = current_stats
19
+ next
20
+ end
21
+
22
+ proc_usage = current_stats[0,3].reduce(:+) - stats[0,3].reduce(:+)
23
+ proc_total = current_stats.reduce(:+) - stats.reduce(:+)
24
+
25
+ self.value = (100 * proc_usage.to_f / proc_total).round
26
+
27
+ stats = current_stats
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class HaproxyLogRequests < Reporter
4
+
5
+ attr_reader :requests, :nosrvs
6
+
7
+ def collect
8
+ requests = 0
9
+ nosrvs = 0
10
+
11
+ begin
12
+ file = File.open(options.logfile, "r")
13
+ rescue Errno::ENOENT
14
+ error("HaproxyLogRequests: Cannot open #{options.logfile}")
15
+ return
16
+ end
17
+
18
+ file.seek(0, IO::SEEK_END)
19
+ @timestamp = Time.now.to_i
20
+
21
+ while true do
22
+ if (current_time = Time.now.to_i) > @time # flush every second
23
+ @requests, requests = requests, 0
24
+ @nosrvs, nosrvs = nosrvs, 0
25
+ @timestamp = current_time
26
+ end
27
+
28
+ IO.select([file])
29
+ line = file.gets
30
+
31
+ case line
32
+ when /NOSRV/
33
+ nosrvs += 1
34
+ when /./
35
+ requests += 1
36
+ else
37
+ sleep 0.1
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+
@@ -0,0 +1,11 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ class Random < Reporter
4
+
5
+ def value
6
+ rand(1000)
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,6 @@
1
+ module DucksboardReporter
2
+ module Reporters
3
+ end
4
+ end
5
+
6
+ Dir[File.dirname(__FILE__) + '/reporters/*.rb'].each {|file| require file }
@@ -0,0 +1,3 @@
1
+ module DucksboardReporter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,53 @@
1
+ module DucksboardReporter
2
+ class Widget
3
+ include Celluloid
4
+ include Celluloid::Logger
5
+
6
+ attr_reader :id, :reporter, :options
7
+
8
+ def initialize(klass, id, reporter, options = {})
9
+ @klass = klass
10
+ @id = id
11
+ @reporter = reporter
12
+ @options = options
13
+ @widget = instanciate_widget
14
+ end
15
+
16
+ def start
17
+ debug log_format("Started with reporter #{reporter}")
18
+
19
+ async.update # initial update
20
+ every(interval) do
21
+ update
22
+ end
23
+ end
24
+
25
+ def update
26
+ value = reporter.public_send(value_method)
27
+ debug log_format("Updating value #{value}")
28
+ @widget.update(value)
29
+ end
30
+
31
+ def interval
32
+ options.interval || 10
33
+ end
34
+
35
+ private
36
+
37
+ def log_format(msg)
38
+ @log_prefix ||= "Widget #{self.class.name.split("::").last}(#{id}): "
39
+ @log_prefix + msg
40
+ end
41
+
42
+ def value_method
43
+ options.value || :value
44
+ end
45
+
46
+ def instanciate_widget
47
+ klass = Class.new(Ducksboard.const_get(@klass, false))
48
+ klass.default_timeout(interval - 1)
49
+ klass.new(id)
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,79 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.require(:default)
4
+
5
+ require "logger"
6
+ require "hashie"
7
+ require "celluloid"
8
+ require "timers"
9
+ require "ducksboard"
10
+
11
+ require "ducksboard_reporter/version"
12
+ require "ducksboard_reporter/reporter"
13
+ require "ducksboard_reporter/reporters"
14
+ require "ducksboard_reporter/widget"
15
+
16
+ Thread.abort_on_exception = true
17
+
18
+ module DucksboardReporter
19
+ extend self
20
+ include Celluloid::Logger
21
+
22
+ def config
23
+ @config ||= Hashie::Mash.load(config_file)
24
+ end
25
+
26
+ def config_file
27
+ @config_file
28
+ end
29
+
30
+ def config_file=(file)
31
+ @config_file = file
32
+ end
33
+
34
+ def logger
35
+ @logger ||= Celluloid.logger = Logger.new($stdout)
36
+ end
37
+
38
+ def reporters
39
+ @reporters ||= {}
40
+ end
41
+
42
+ def widgets
43
+ @widgets ||= []
44
+ end
45
+
46
+ def start
47
+ Signal.trap("INT") { exit }
48
+
49
+ Ducksboard.api_key = config.api_key
50
+
51
+ instanciate_reporters
52
+ instanciate_widgets
53
+
54
+ sleep
55
+ end
56
+
57
+ def instanciate_reporters
58
+ DucksboardReporter.config.reporters.each do |config|
59
+ reporter = Reporters.const_get(config.type, false).new(config)
60
+ reporters[config.name] = reporter
61
+ reporter.start
62
+ end
63
+ end
64
+
65
+ def instanciate_widgets
66
+ DucksboardReporter.config.widgets.each do |config|
67
+ reporter = reporters[config.reporter]
68
+
69
+ unless reporter
70
+ logger.error("Cannot find reporter #{config.reporter}")
71
+ exit
72
+ end
73
+
74
+ widget = Widget.new(config.type, config.id, reporter, config)
75
+ widget.start
76
+ widgets << widget
77
+ end
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ducksboard_reporter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - unnu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ducksboard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hashie
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: celluloid
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: timers
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: trollop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Report values to ducksboard
112
+ email:
113
+ - norman.timmler@gmail.com
114
+ executables:
115
+ - ducksboard-reporter
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - bin/ducksboard-reporter
125
+ - ducksboard_reporter.gemspec
126
+ - example_config.yml
127
+ - lib/ducksboard_reporter.rb
128
+ - lib/ducksboard_reporter/reporter.rb
129
+ - lib/ducksboard_reporter/reporters.rb
130
+ - lib/ducksboard_reporter/reporters/bandwidth.rb
131
+ - lib/ducksboard_reporter/reporters/cpu_usage.rb
132
+ - lib/ducksboard_reporter/reporters/haproxy_log_requests.rb
133
+ - lib/ducksboard_reporter/reporters/random.rb
134
+ - lib/ducksboard_reporter/version.rb
135
+ - lib/ducksboard_reporter/widget.rb
136
+ homepage: ''
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.2.2
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: Report values to ducksboard
160
+ test_files: []