fiveruns-dash-sensor 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +5 -0
- data/README.rdoc +71 -0
- data/bin/fiveruns-dash-sensor +42 -0
- data/config.rb +19 -0
- data/lib/daemon.rb +46 -0
- data/lib/sensor.rb +93 -0
- data/lib/sensor_plugin.rb +16 -0
- data/plugins/apache.rb +56 -0
- data/plugins/memcached.rb +65 -0
- data/plugins/nginx.rb +62 -0
- data/plugins/starling.rb +64 -0
- metadata +64 -0
data/History.rdoc
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
= fiveruns-dash-sensor
|
2
|
+
|
3
|
+
Please see http://dash.fiveruns.com for an overview of the Dash service.
|
4
|
+
|
5
|
+
== Summary
|
6
|
+
|
7
|
+
Sensor provides a mechanism for "external" monitoring of infrastructure with Dash.
|
8
|
+
Since Dash is usually embedded within an application (i.e. internal), there's no easy
|
9
|
+
way to monitor things like Apache, memcached, or other pieces. Sensor is designed to
|
10
|
+
be installed on a machine and upload metrics for any infrastructure on that machine.
|
11
|
+
The user just needs to configure which elements they want to monitor.
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
gem install fiveruns-dash-sensor -s http://gems.github.com
|
16
|
+
|
17
|
+
== Configuration
|
18
|
+
|
19
|
+
When you run 'fiveruns-dash-sensor start' for the first time, it will create a blank
|
20
|
+
configuration for you in ~/.fiveruns-dash-sensor/config.rb. You will need to edit
|
21
|
+
this file with your app token and activate the plugins for your environment. Once
|
22
|
+
done, you should be able to run 'fiveruns-dash-sensor run' for a few minutes to verify
|
23
|
+
everything is working as designed. If there are no problems, you can run
|
24
|
+
'fiveruns-dash-sensor start' to spin off the daemon into the background and forget about it.
|
25
|
+
|
26
|
+
== Command Summary
|
27
|
+
|
28
|
+
'fiveruns-dash-sensor run' - start the daemon in the foreground, for debugging purposes.
|
29
|
+
'fiveruns-dash-sensor start' - start the daemon in the background, output and PID file goes
|
30
|
+
in the ~/.fiveruns-dash-sensor/log/ directory.
|
31
|
+
'fiveruns-dash-sensor stop' - stop the daemon in the background
|
32
|
+
|
33
|
+
You can run Sensor in verbose mode to get more debug output:
|
34
|
+
|
35
|
+
'fiveruns-dash-sensor run -- -v'
|
36
|
+
|
37
|
+
== Creating your own Plugins
|
38
|
+
|
39
|
+
Sensor allows you to create your own custom plugins for your own infrastructure. Each
|
40
|
+
plugin should reside in ~/.fiveruns-dash-sensor/<name>.rb and config.rb should have an
|
41
|
+
entry in it like this:
|
42
|
+
|
43
|
+
sensor.plugin :<name>, any options here...
|
44
|
+
|
45
|
+
Please see the existing plugins for examples of how your code should work.
|
46
|
+
|
47
|
+
|
48
|
+
== License
|
49
|
+
|
50
|
+
# (The FiveRuns License)
|
51
|
+
#
|
52
|
+
# Copyright (c) 2009 FiveRuns Corporation
|
53
|
+
#
|
54
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
55
|
+
# a copy of this software and associated documentation files (the
|
56
|
+
# 'Software'), to deal in the Software without restriction, including
|
57
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
58
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
59
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
60
|
+
# the following conditions:
|
61
|
+
#
|
62
|
+
# The above copyright notice and this permission notice shall be
|
63
|
+
# included in all copies or substantial portions of the Software.
|
64
|
+
#
|
65
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
66
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
67
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
68
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
69
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
70
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
71
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
unless File.exist?("#{ENV['HOME']}/.fiveruns-dash-sensor/config.rb")
|
5
|
+
local = File.join(File.dirname(__FILE__), "..", "config.rb")
|
6
|
+
dir = File.expand_path("~/.fiveruns-dash-sensor")
|
7
|
+
if File.exist?(local)
|
8
|
+
require 'fileutils'
|
9
|
+
FileUtils.mkdir_p dir
|
10
|
+
FileUtils.cp local, dir
|
11
|
+
puts ""
|
12
|
+
puts "Configuration Required"
|
13
|
+
puts ""
|
14
|
+
puts "A blank configuration file has been placed in ~/.fiveruns-dash-sensor/config.rb"
|
15
|
+
puts "Please edit this file to add your application token and configure the plugins"
|
16
|
+
puts "appropriate to this environment."
|
17
|
+
puts ""
|
18
|
+
end
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
root = File.expand_path("~/.fiveruns-dash-sensor")
|
23
|
+
log_dir = File.join(root, "log")
|
24
|
+
unless File.exist? log_dir
|
25
|
+
require 'fileutils'
|
26
|
+
FileUtils.mkdir_p log_dir
|
27
|
+
end
|
28
|
+
|
29
|
+
gem 'daemons'
|
30
|
+
require 'daemons'
|
31
|
+
|
32
|
+
options = {
|
33
|
+
:app_name => "dash-sensor",
|
34
|
+
:dir_mode => :normal,
|
35
|
+
:dir => log_dir,
|
36
|
+
:multiple => true,
|
37
|
+
:backtrace => true,
|
38
|
+
:monitor => false,
|
39
|
+
:log_output => true
|
40
|
+
}
|
41
|
+
|
42
|
+
Daemons.run(File.join(File.dirname(__FILE__), '..', 'lib', 'daemon.rb'), options)
|
data/config.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Example configuration for FiveRuns Dash Sensor daemon.
|
2
|
+
# Configure your Dash sensor instance here.
|
3
|
+
# This file should reside in ~/.fiveruns-dash-sensor/config.rb
|
4
|
+
#
|
5
|
+
# We suggest you have a single Dash Sensor instance running per machine
|
6
|
+
# and an application token per environment. So if you have 8 machines
|
7
|
+
# in your application's production cluster, you would have 8 sensor instances
|
8
|
+
# running for one application named "<App> Production Cluster".
|
9
|
+
|
10
|
+
#sensor.token = 'change-to-your-application-token'
|
11
|
+
|
12
|
+
# One line per piece of infrastructure you wish to monitor.
|
13
|
+
# The plugins are in the plugins directory.
|
14
|
+
|
15
|
+
# Available options and their defaults are listed.
|
16
|
+
#sensor.plugin 'memcached', :iface => 'localhost', :port => 11211
|
17
|
+
#sensor.plugin 'starling', :iface => 'localhost', :port => 22122
|
18
|
+
#sensor.plugin 'apache', :url => 'http://localhost/server-status?auto'
|
19
|
+
#sensor.plugin 'nginx', :url => 'http://localhost/nginx_status'
|
data/lib/daemon.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
# Sent by daemons when you run '<script> stop'
|
5
|
+
Signal.trap('TERM') { puts "fiveruns-dash-sensor PID #{$$} exiting at #{Time.now}..."; exit(0) }
|
6
|
+
# Sent by daemons when you hit Ctrl-C after '<script> run'
|
7
|
+
Signal.trap('INT') { puts "fiveruns-dash-sensor terminated at #{Time.now}..."; exit(0) }
|
8
|
+
|
9
|
+
options = OpenStruct.new
|
10
|
+
options.environment = ENV['RAILS_ENV'] || 'production'
|
11
|
+
options.verbose = false
|
12
|
+
options.config_file = "#{ENV['HOME']}/.fiveruns-dash-sensor/config.rb"
|
13
|
+
|
14
|
+
op = OptionParser.new do |opts|
|
15
|
+
opts.banner = "Usage: fiveruns-dash-sensor [options]"
|
16
|
+
opts.separator "General Options:"
|
17
|
+
opts.on("-e ENVIRONMENT", "--environment NAME", "Select environment [default: #{options.environment}]") do |v|
|
18
|
+
options.environment = v
|
19
|
+
end
|
20
|
+
opts.on("-c CONFIG", "--config FILE", "Select config file [default: #{options.config_file}]") do |v|
|
21
|
+
options.config_file = v
|
22
|
+
end
|
23
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
24
|
+
options.verbose = v
|
25
|
+
end
|
26
|
+
opts.separator "Other Options:"
|
27
|
+
opts.on("-h", "--help", "Display this message") do |v|
|
28
|
+
STDERR.puts opts
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
op.parse!(ARGV)
|
33
|
+
|
34
|
+
unless File.exist? options.config_file
|
35
|
+
puts "Please create a configuration file for your environment in ~/.fiveruns-dash-sensor/config.rb"
|
36
|
+
exit(1)
|
37
|
+
end
|
38
|
+
|
39
|
+
require 'logger'
|
40
|
+
LOG = Logger.new(STDOUT)
|
41
|
+
LOG.level = options.verbose ? Logger::DEBUG : Logger::INFO
|
42
|
+
|
43
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
44
|
+
require "sensor"
|
45
|
+
LOG.info("Starting Dash Sensor [#{$$}] at #{Time.now}")
|
46
|
+
Dash::Sensor::Engine.new.start(options)
|
data/lib/sensor.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'fiveruns/dash'
|
2
|
+
require 'sensor_plugin'
|
3
|
+
|
4
|
+
module Dash
|
5
|
+
module Sensor
|
6
|
+
|
7
|
+
RECIPES = []
|
8
|
+
|
9
|
+
class Engine
|
10
|
+
|
11
|
+
def self.registered(name, url, klass)
|
12
|
+
klass.instance = klass.new
|
13
|
+
RECIPES << [name, url, klass]
|
14
|
+
end
|
15
|
+
|
16
|
+
def start(options)
|
17
|
+
load_plugins(options)
|
18
|
+
wait_forever
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def load_plugins(options)
|
24
|
+
# Add the user's config directory to the load path so they can load custom plugins
|
25
|
+
# without modifying this gem.
|
26
|
+
$PLUGIN_PATH = [
|
27
|
+
File.dirname(options.config_file),
|
28
|
+
File.expand_path(File.join(File.dirname(__FILE__), '..', 'plugins')),
|
29
|
+
nil
|
30
|
+
]
|
31
|
+
|
32
|
+
setup = Setup.new
|
33
|
+
config = File.read(options.config_file)
|
34
|
+
setup.instance_eval(config, options.config_file)
|
35
|
+
|
36
|
+
start_dash(setup)
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_dash(setup)
|
40
|
+
LOG.info("Configured Dash Sensor for #{setup.name} [#{setup.token}]")
|
41
|
+
Fiveruns::Dash.configure :app => setup.token do |config|
|
42
|
+
RECIPES.each do |(name, url, _)|
|
43
|
+
config.add_recipe name.to_sym, url
|
44
|
+
end
|
45
|
+
end
|
46
|
+
Fiveruns::Dash.session.reporter.interval = 60
|
47
|
+
Fiveruns::Dash.session.start
|
48
|
+
end
|
49
|
+
|
50
|
+
def wait_forever
|
51
|
+
while true
|
52
|
+
sleep 60
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Setup
|
58
|
+
|
59
|
+
attr_accessor :token, :name
|
60
|
+
|
61
|
+
def initialize
|
62
|
+
self.name = 'My App Name'
|
63
|
+
self.token = 'change-me-to-your-app-token'
|
64
|
+
end
|
65
|
+
|
66
|
+
def plugin(name, options={})
|
67
|
+
LOG.info("Loading plugin #{name} with options #{options.inspect}")
|
68
|
+
|
69
|
+
$PLUGIN_PATH.each do |path|
|
70
|
+
raise ArgumentError, "Unable to find #{name}.rb in plugin path: #{$PLUGIN_PATH[0..-2].inspect}" unless path
|
71
|
+
file = File.join(path, name)
|
72
|
+
if File.exist?("#{file}.rb")
|
73
|
+
LOG.debug "Loading #{file}"
|
74
|
+
require file
|
75
|
+
break
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
RECIPES.last.last.instance.configure(options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def url=(value)
|
83
|
+
ENV['DASH_UPDATE'] = value
|
84
|
+
end
|
85
|
+
|
86
|
+
def sensor
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SensorPlugin
|
2
|
+
|
3
|
+
def self.included(base)
|
4
|
+
base.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
attr_accessor :instance
|
9
|
+
|
10
|
+
def register(name, url, &block)
|
11
|
+
Fiveruns::Dash.register_recipe(name, url, &block)
|
12
|
+
Dash::Sensor::Engine.registered(name, url, self)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/plugins/apache.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
module Dash::Sensor::Plugins
|
4
|
+
class Apache
|
5
|
+
include SensorPlugin
|
6
|
+
|
7
|
+
ONE_KB = 1024
|
8
|
+
|
9
|
+
register :apache, :url => 'http://dash.fiveruns.com' do |recipe|
|
10
|
+
recipe.counter :requests, 'Requests' do
|
11
|
+
total = Integer(stats['Total Accesses'])
|
12
|
+
last = Integer(old_stats['Total Accesses'])
|
13
|
+
this_minute = total - last
|
14
|
+
this_minute > 0 && last > 0 ? this_minute : 0
|
15
|
+
end
|
16
|
+
recipe.counter :mbytes, 'Transferred', :unit => 'MB' do
|
17
|
+
total = Integer(stats['Total kBytes'])
|
18
|
+
last = Integer(old_stats['Total kBytes'])
|
19
|
+
this_minute = Float(total - last) / ONE_KB
|
20
|
+
this_minute > 0 && last > 0 ? this_minute : 0
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def configure(options)
|
25
|
+
@url = options.fetch(:url, 'http://localhost/server-status?auto')
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def self.stats
|
31
|
+
if !@time || @time < Time.now - 55
|
32
|
+
@old_stats = @stats || Hash.new(0)
|
33
|
+
LOG.debug "Fetching status at #{Time.now}"
|
34
|
+
@stats = instance.send(:stats_data)
|
35
|
+
@time = Time.now
|
36
|
+
end
|
37
|
+
@stats
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.old_stats
|
41
|
+
@old_stats
|
42
|
+
end
|
43
|
+
|
44
|
+
def stats_data
|
45
|
+
begin
|
46
|
+
lines = open(@url).read.split("\n")
|
47
|
+
Hash[*lines.map {|line| line.split(':') }.flatten]
|
48
|
+
rescue => e
|
49
|
+
LOG.error "Error contacting #{@url}"
|
50
|
+
LOG.error "#{e.class.name}: #{e.message}"
|
51
|
+
Hash.new(0)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Dash::Sensor::Plugins
|
2
|
+
class Memcached
|
3
|
+
include SensorPlugin
|
4
|
+
|
5
|
+
register :memcached, :url => 'http://dash.fiveruns.com' do |recipe|
|
6
|
+
recipe.absolute :bytes, 'Cache Size', :unit => 'MB' do
|
7
|
+
Float(stats['bytes']) / (1024 * 1024)
|
8
|
+
end
|
9
|
+
recipe.percentage :hit_rate, 'Cache Hit Rate' do
|
10
|
+
hits = Integer(stats['get_hits'])
|
11
|
+
misses = Integer(stats['get_misses'])
|
12
|
+
total = hits + misses
|
13
|
+
total == 0 ? 0 : ((Float(hits) / total) * 100)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def configure(options)
|
18
|
+
@host = options.fetch(:iface, 'localhost')
|
19
|
+
@port = Integer(options.fetch(:port, 11211))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.stats
|
25
|
+
if !@time || @time < Time.now - 55
|
26
|
+
LOG.debug "Fetching stats at #{Time.now}"
|
27
|
+
@stats = parse(instance.send(:stats_data))
|
28
|
+
@time = Time.now
|
29
|
+
end
|
30
|
+
@stats
|
31
|
+
end
|
32
|
+
|
33
|
+
def stats_data
|
34
|
+
data = ''
|
35
|
+
begin
|
36
|
+
sock = TCPSocket.new(@host, @port)
|
37
|
+
sock.print("stats\r\n")
|
38
|
+
sock.flush
|
39
|
+
# memcached does not close the socket once it is done writing
|
40
|
+
# the stats data. We need to read line by line until we detect
|
41
|
+
# the END line and then stop/close on our side.
|
42
|
+
stats = sock.gets
|
43
|
+
while true
|
44
|
+
data += stats
|
45
|
+
break if stats.strip == 'END'
|
46
|
+
stats = sock.gets
|
47
|
+
end
|
48
|
+
sock.close
|
49
|
+
rescue Exception => e
|
50
|
+
LOG.error "Error contacting Starling at #{@host}:#{@port}"
|
51
|
+
LOG.error "#{e.class.name}: #{e.message}"
|
52
|
+
end
|
53
|
+
data
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.parse(stats_data)
|
57
|
+
stats = Hash.new(0)
|
58
|
+
stats_data.each_line do |line|
|
59
|
+
stats[$1] = $2 if line =~ /STAT (\w+) (\S+)/
|
60
|
+
end
|
61
|
+
stats
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
data/plugins/nginx.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
module Dash::Sensor::Plugins
|
4
|
+
class Nginx
|
5
|
+
include SensorPlugin
|
6
|
+
|
7
|
+
ONE_KB = 1024
|
8
|
+
|
9
|
+
register :nginx, :url => 'http://dash.fiveruns.com' do |recipe|
|
10
|
+
recipe.counter :requests, 'Requests' do
|
11
|
+
total = stats[:requests]
|
12
|
+
last = old_stats[:requests]
|
13
|
+
this_minute = total - last
|
14
|
+
this_minute > 0 && last > 0 ? this_minute : 0
|
15
|
+
end
|
16
|
+
recipe.absolute :connections, 'Active Connections' do
|
17
|
+
stats[:active]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def configure(options)
|
22
|
+
@url = options.fetch(:url, 'http://localhost/nginx-status')
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.stats
|
28
|
+
if !@time || @time < Time.now - 55
|
29
|
+
@old_stats = @stats || Hash.new(0)
|
30
|
+
LOG.debug "Fetching status at #{Time.now}"
|
31
|
+
@stats = instance.send(:stats_data)
|
32
|
+
@time = Time.now
|
33
|
+
end
|
34
|
+
@stats
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.old_stats
|
38
|
+
@old_stats
|
39
|
+
end
|
40
|
+
|
41
|
+
def stats_data
|
42
|
+
begin
|
43
|
+
results = Hash.new(0)
|
44
|
+
data = open(@url).read
|
45
|
+
data.each_line do |line|
|
46
|
+
case line
|
47
|
+
when /^Active connections:\s+(\d+)/
|
48
|
+
results[:active] = Integer($1)
|
49
|
+
when /^\s+(\d+)\s+(\d+)\s+(\d+)/
|
50
|
+
results[:requests] = Integer($3)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
results
|
54
|
+
rescue Exception => e
|
55
|
+
LOG.error "Error contacting #{@url}"
|
56
|
+
LOG.error "#{e.class.name}: #{e.message}"
|
57
|
+
Hash.new(0)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/plugins/starling.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Dash::Sensor::Plugins
|
2
|
+
class Starling
|
3
|
+
include SensorPlugin
|
4
|
+
|
5
|
+
register :starling, :url => 'http://dash.fiveruns.com' do |recipe|
|
6
|
+
recipe.absolute :processed, 'Processed Items' do
|
7
|
+
queues = stats.keys.map { |name| name =~ /queue_(\w+)_total_items/; $1 }.compact
|
8
|
+
queues.inject(0) { |total, queue_name| total + Integer(stats["queue_#{queue_name}_total_items"]) - Integer(stats["queue_#{queue_name}_items"]) }
|
9
|
+
end
|
10
|
+
recipe.absolute :queue_size, 'Current Size' do
|
11
|
+
queues = stats.keys.find_all { |name| name =~ /queue_\w+_items/ }
|
12
|
+
queues.inject(0) { |total, queue_name| total + Integer(stats[queue_name]) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def configure(options)
|
17
|
+
@host = options.fetch(:iface, 'localhost')
|
18
|
+
@port = Integer(options.fetch(:port, 22122))
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def self.stats
|
24
|
+
if !@time || @time < Time.now - 55
|
25
|
+
LOG.debug "Fetching stats at #{Time.now}"
|
26
|
+
@stats = parse(instance.send(:stats_data))
|
27
|
+
@time = Time.now
|
28
|
+
end
|
29
|
+
@stats
|
30
|
+
end
|
31
|
+
|
32
|
+
def stats_data
|
33
|
+
data = ''
|
34
|
+
begin
|
35
|
+
sock = TCPSocket.new(@host, @port)
|
36
|
+
sock.print("stats\r\n")
|
37
|
+
sock.flush
|
38
|
+
# memcached does not close the socket once it is done writing
|
39
|
+
# the stats data. We need to read line by line until we detect
|
40
|
+
# the END line and then stop/close on our side.
|
41
|
+
stats = sock.gets
|
42
|
+
while true
|
43
|
+
data += stats
|
44
|
+
break if stats.strip == 'END'
|
45
|
+
stats = sock.gets
|
46
|
+
end
|
47
|
+
sock.close
|
48
|
+
rescue Exception => e
|
49
|
+
LOG.error "Error contacting Starling at #{@host}:#{@port}"
|
50
|
+
LOG.error "#{e.class.name}: #{e.message}"
|
51
|
+
end
|
52
|
+
data
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parse(stats_data)
|
56
|
+
stats = Hash.new(0)
|
57
|
+
stats_data.each_line do |line|
|
58
|
+
stats[$1] = $2 if line =~ /STAT (\w+) (\S+)/
|
59
|
+
end
|
60
|
+
stats
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fiveruns-dash-sensor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- FiveRuns
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-02-05 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Sensor allows Dash to monitor ad-hoc infrastructure non-invasively
|
17
|
+
email: support@fiveruns.com
|
18
|
+
executables:
|
19
|
+
- fiveruns-dash-sensor
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- History.rdoc
|
25
|
+
files:
|
26
|
+
- bin/fiveruns-dash-sensor
|
27
|
+
- config.rb
|
28
|
+
- lib/daemon.rb
|
29
|
+
- lib/sensor.rb
|
30
|
+
- lib/sensor_plugin.rb
|
31
|
+
- plugins/memcached.rb
|
32
|
+
- plugins/starling.rb
|
33
|
+
- plugins/nginx.rb
|
34
|
+
- plugins/apache.rb
|
35
|
+
- README.rdoc
|
36
|
+
- History.rdoc
|
37
|
+
has_rdoc: false
|
38
|
+
homepage: http://github.com/fiveruns/dash-sensor/
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.2.0
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: Sensor allows Dash to monitor ad-hoc infrastructure non-invasively
|
63
|
+
test_files: []
|
64
|
+
|