diff --git a/.gitignore b/.gitignore
index fea0565..463c1b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,11 @@
+*.swp
/Manifest
/newrelic.yml
log/
doc/
docs
html/
-
-*~
+Gemfile.lock
.DS_Store
newrelic_ia.log
@@ -17,5 +17,3 @@ newrelic_ia.log
# other scm
.svn
-
-
diff --git a/.loadpath b/.loadpath
deleted file mode 100644
index 948efaa..0000000
--- a/.loadpath
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/.project b/.project
deleted file mode 100644
index 4f5ad18..0000000
--- a/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
- Monitor
-
-
-
-
-
- org.rubypeople.rdt.core.rubybuilder
-
-
-
-
-
- org.rubypeople.rdt.core.rubynature
-
-
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..d65e2a6
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source 'http://rubygems.org'
+
+gemspec
diff --git a/PostInstall.txt b/PostInstall.txt
deleted file mode 100644
index a267c62..0000000
--- a/PostInstall.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
-For more information refer to http://support.newrelic.com or
-say 'newrelic' at #newrelic on freenode IRC.
-
diff --git a/README.rdoc b/README.rdoc
index d6b78b6..31e5a32 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -9,7 +9,7 @@ to your RPM console which can be viewed with custom dashboards.
== Synopsis
- newrelic_ia [ options ] aspect, aspect..
+ newrelic_ia [ options ] aspect, aspect..
aspect: one or more of 'iostat' or 'disk' or 'memcached' (more to come)
@@ -17,7 +17,7 @@ to your RPM console which can be viewed with custom dashboards.
-v, --verbose debug output
-q, --quiet quiet output
-e, --environment=ENV use ENV section in newrelic.yml
- --install create a default newrelic.yml
+ --install KEY create a default newrelic.yml
-h, --help Show this help message.
== Requirements
@@ -29,15 +29,15 @@ to your RPM console which can be viewed with custom dashboards.
sudo gem install newrelic_ia
-Once installed, run from the home directory of your Rails
+Once installed, run from the home directory of your Rails
application, or create a separate working directory and run
- newrelic_ia --install
+ newrelic_ia --install KEY
to create a template newrelic.yml file you can use. Edit this file
and substitute your license key and app_name value.
-specify memcached nodes in memcached-nodes.txt.
+specify memcached nodes in memcached-nodes.txt.
== Credits
@@ -58,24 +58,24 @@ Memcached stats are reported for each node and also sample reports aggregated st
uptime Number of seconds this server has been running
curr_items Current number of items stored by the server
- total_items Total number of items stored by this server
+ total_items Total number of items stored by this server
ever since it started
bytes Current number of bytes used by this server to store items
curr_connections Number of open connections
- total_connections Total number of connections opened since
+ total_connections Total number of connections opened since
the server started running
connection_structures Number of connection structures allocated by the server
cmd_get Cumulative number of retrieval requests
cmd_set Cumulative number of storage requests
get_hits Number of keys that have been requested and found present
get_misses Number of items that have been requested and not found
- evictions Number of valid items removed from cache to free
+ evictions Number of valid items removed from cache to free
memory for new items
bytes_read Total number of bytes read by this server from network
bytes_written Total number of bytes sent by this server to network
limit_maxbytes Number of bytes this server is allowed to use for storage
threads Number of worker threads requested
-
+
Derived Stats (computed stats):
free_maxbytes Number of free bytes this server has available for storage
@@ -84,7 +84,7 @@ Stats Derivatives (time derivatives of stats):
hit_ratio Percent of keys that have been requested and found present
miss_ratio Percent of keys that have been requested and found missing
- rpm Requests per minutes
+ rpm Requests per minutes
gpm Gets per minutes
hpm Hits per minutes
mpm Misses per minutes
@@ -99,34 +99,34 @@ Liquid template for NewRelic custom dashboard:
- {% line_chart value:average_value title:'Cache Miss Ratio' metric:'System/Memcached/Miss Ratio' simple_tooltip:true label:segment_3 value_suffix:'%' %}
+ {% line_chart value:average_value title:'Cache Miss Ratio' metric:'System/Memcached/all/miss_ratio' simple_tooltip:true label:segment_3 value_suffix:'%' %}
- {% line_chart value:average_value title:'Cache Memory' regexp:'System/Memcached/(Bytes|Free Bytes|Limit Maxbytes)' simple_tooltip:true label:segment_3 %}
+ {% line_chart value:average_value title:'Cache Memory' regexp:'System/Memcached/all/(bytes|free_bytes|limit_maxbytes)' simple_tooltip:true label:segment_3 %}
-
+
-
+
- {% line_chart value:average_value title:'Cache Gets & Sets' regexp:'System/Memcached/(Gpm|Spm)' simple_tooltip:true label:segment_3 %}
+ {% line_chart value:average_value title:'Cache Gets & Sets' regexp:'System/Memcached/all/(gpm|spm)' simple_tooltip:true label:segment_3 %}
- {% line_chart value:average_value title:'Cache Misses, Flushes, & Evictions' regexp:'System/Memcached/(Mpm|Epm|Fpm)' simple_tooltip:true label:segment_3 %}
+ {% line_chart value:average_value title:'Cache Misses, Flushes, & Evictions' regexp:'System/Memcached/all/(mpm|epm|fpm)' simple_tooltip:true label:segment_3 %}
-
+
-
+
- {% line_chart value:average_value title:'Active Connections' metric:'System/Memcached/Curr Connections' simple_tooltip:true hide_legend:true %}
+ {% line_chart value:average_value title:'Active Connections' metric:'System/Memcached/all/curr_connections' simple_tooltip:true hide_legend:true %}
- {% line_chart value:average_value title:'Cache Objects' metric:'System/Memcached/Curr Items' simple_tooltip:true hide_legend:true %}
+ {% line_chart value:average_value title:'Cache Objects' metric:'System/Memcached/all/curr_items' simple_tooltip:true hide_legend:true %}
diff --git a/Rakefile b/Rakefile
index 45bf431..d95c3f1 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,87 +1,10 @@
-require 'rubygems'
-require 'rake'
-require File.dirname(__FILE__) + '/lib/new_relic/ia/version.rb'
-require 'rake/testtask'
-
-GEM_NAME = "newrelic_ia"
-GEM_VERSION = NewRelic::IA::VERSION
-AUTHOR = "Bill Kayser"
-EMAIL = "bkayser@newrelic.com"
-HOMEPAGE = "http://www.newrelic.com"
-SUMMARY = "New Relic Gem for gathering system metrics"
-DESCRIPTION = <=2.10.6'
- gem.post_install_message = File.read 'PostInstall.txt'
- end
- Jeweler::GemcutterTasks.new
-rescue LoadError
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
+require "rspec"
+require "rspec/core/rake_task"
+RSpec::Core::RakeTask.new("spec") do |spec|
+ spec.pattern = "spec/*_spec.rb"
end
-load "#{File.dirname(__FILE__)}/tasks/rspec.rake"
-
-task :manifest do
- puts "Manifest task is no longer used since switching to jeweler."
-end
-
-begin
- require 'rcov/rcovtask'
- Rcov::RcovTask.new do |test|
- test.libs << 'test'
- test.pattern = 'spec/**/*.rb'
- test.verbose = true
- end
-rescue LoadError
- task :rcov do
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
- end
-end
-
-require 'spec/rake/spectask'
-Spec::Rake::SpecTask.new(:spec) do |spec|
- spec.libs << 'lib' << 'spec'
- spec.spec_files = FileList['spec/**/*_spec.rb']
-end
-
-task :spec => :check_dependencies
task :default => :spec
-
-require 'rake/rdoctask'
-Rake::RDocTask.new do |rdoc|
- rdoc.title = SUMMARY
- rdoc.main = "README.rdoc"
- rdoc.rdoc_files << 'LICENSE' << 'README*' << 'CHANGELOG' << 'lib/**/*.rb' << 'bin/**/*'
- rdoc.inline_source = true
-end
-
-begin
- require 'sdoc_helpers'
-rescue LoadError
- puts "sdoc support not enabled. Please gem install sdoc-helpers."
-end
diff --git a/config/newrelic.yml b/config/newrelic.yml
new file mode 100644
index 0000000..3406829
--- /dev/null
+++ b/config/newrelic.yml
@@ -0,0 +1,35 @@
+#
+# This is a configuration file for the RPM Agent, tailored
+# for use as a system monitor.
+#
+# Generated on Oct 12, 2011, from version 0.2.2
+#
+common: &default_settings
+ log_level: info
+ license_key: 'test'
+
+ app_name: System Monitor
+ ssl: false
+
+ # Set the array of nodes for the memcache monitor
+ memcached_nodes:
+ - localhost:11211
+# - localhost:11212
+# - localhost:11213
+
+ # These settings ensure we don't end up actually monitoring
+ # the IA agent itself--we aren't really interested in that.
+ # Don't change these.
+ disable_samplers: true
+ capture_params: false
+ transaction_tracer:
+ enabled: false
+
+# NOTE if your application has other named environments, you should
+# provide newrelic conifguration settings for these enviromnents here.
+production:
+ <<: *default_settings
+
+development:
+ <<: *default_settings
+
diff --git a/lib/new_relic/ia/cli.rb b/lib/new_relic/ia/cli.rb
index a1b3b4b..1d21093 100644
--- a/lib/new_relic/ia/cli.rb
+++ b/lib/new_relic/ia/cli.rb
@@ -5,34 +5,35 @@
module NewRelic::IA
class InitError < StandardError; end
-
+
class CLI
-
+
LOGFILE = "newrelic_ia.log"
-
+
class << self
-
+
def log
@log ||= Logger.new LOGFILE
end
-
+
def level= l
log.level = l
end
-
+
# Run the command line args. Return nil if running
# or an exit status if not.
def execute(stdout, arguments=[])
+ log.level = Logger::INFO
@aspects = []
parser = OptionParser.new do |opts|
opts.banner = <<-BANNER.gsub(/^ */,'')
New Relic Infrastructure Agent (IA) version #{NewRelic::IA::VERSION}
- Monitor different aspects of your environment with New Relic RPM.
+ Monitor different aspects of your environment with New Relic RPM.
- Usage: #{File.basename($0)} [ options ] aspect, aspect..
+ Usage: #{File.basename($0)} [ options ] aspect, aspect..
aspect: one or more of 'memcached', 'iostat' or 'disk' (more to come)
- BANNER
+ BANNER
opts.separator ""
opts.on("-a", "--all",
"use all available aspects") { @aspects = %w[iostat disk memcached] }
@@ -42,9 +43,9 @@ def execute(stdout, arguments=[])
"quiet output") { NewRelic::IA::CLI.log.level = Logger::ERROR }
opts.on("-e", "--environment=ENV",
"use ENV section in newrelic.yml") { |e| @env = e }
- opts.on("--install",
- "create a default newrelic.yml") { |e| return self.install(stdout) }
-
+ opts.on("--install license_key",
+ "create a default newrelic.yml") { |key| return self.install(key, stdout) }
+
opts.on("-h", "--help",
"Show this help message.") { stdout.puts "#{opts}\n"; return 0 }
begin
@@ -59,7 +60,7 @@ def execute(stdout, arguments=[])
end
end
@aspects.delete_if do |aspect|
- unless self.instance_methods(false).include? aspect
+ unless ASPECTS.include? aspect.to_sym
stdout.puts "Unknown aspect: #{aspect}"
true
end
@@ -69,12 +70,10 @@ def execute(stdout, arguments=[])
stdout.puts parser
return 1
end
- require_newrelic_rpm
+ require_newrelic_rpm
NewRelic::Agent.manual_start :env => @env, :monitor_mode => true, :log => self.log
# connected? due in a future version
- if not (NewRelic::Agent.instance.connected? rescue true)
- raise InitError, "Unable to connect to RPM server. Agent not started."
- end
+ raise InitError, "Unable to connect to RPM server. Agent not started." unless NewRelic::Agent.instance.connected?
cli = new
@aspects.each do | aspect |
cli.send aspect
@@ -84,8 +83,10 @@ def execute(stdout, arguments=[])
stdout.puts e.message
return 1
end
-
+
end
+
+ ASPECTS = [:iostat, :disk, :memcached]
# Aspect definitions
def iostat # :nodoc:
self.class.log.info "Starting iostat monitor..."
@@ -93,13 +94,13 @@ def iostat # :nodoc:
reader = NewRelic::IA::IostatReader.new
Thread.new { reader.run }
end
-
+
def disk
self.class.log.info "Starting disk sampler..."
require 'new_relic/ia/disk_sampler'
- NewRelic::Agent.instance.stats_engine.add_harvest_sampler NewRelic::IA::DiskSampler.new
+ NewRelic::Agent.instance.stats_engine.add_harvest_sampler NewRelic::IA::DiskSampler.new
end
-
+
def memcached
require 'new_relic/ia/memcached_sampler'
s = NewRelic::IA::MemcachedSampler.new
@@ -108,11 +109,11 @@ def memcached
end
private
-
+
def log
self.class.log
end
-
+
def self.require_newrelic_rpm
begin
require 'newrelic_rpm'
@@ -127,31 +128,22 @@ def self.require_newrelic_rpm
end
end
end
-
- def self.install stdout
+
+ def self.install license_key, stdout
require_newrelic_rpm
- if NewRelic::VersionNumber.new(NewRelic::VERSION::STRING) < '2.12'
- if File.exists? "newrelic.yml"
- stdout.puts "A newrelic.yml file already exists. Please remove it before installing another."
- return 1 # error
- else
- FileUtils.copy File.join(File.dirname(__FILE__), "newrelic.yml"), "."
- stdout.puts "A newrelic.yml template was copied to #{File.expand_path('.')}."
- stdout.puts "Please add a license key to the file before starting."
- return 0 # normal
- end
- else
- begin
- require 'new_relic/command'
- cmd = NewRelic::Command::Install.new \
- :src_file => File.join(File.dirname(__FILE__), "newrelic.yml"),
- :generated_for_user => "Generated on #{Time.now.strftime('%b %d, %Y')}, from version #{NewRelic::IA::VERSION}"
- cmd.run
- 0 # normal
- rescue NewRelic::Command::CommandFailure => e
- stdout.puts e.message
- 1 # error
- end
+ begin
+ require 'new_relic/command'
+ FileUtils.mkdir(File.join(File.dirname(__FILE__), "config"))
+ cmd = NewRelic::Command::Install.new \
+ :src_file => File.join(File.dirname(__FILE__), "config/newrelic.yml"),
+ :generated_for_user => "Generated on #{Time.now.strftime('%b %d, %Y')}, from version #{NewRelic::IA::VERSION}",
+ :app_name => 'System Monitor',
+ :license_key => license_key
+ cmd.run
+ 0 # normal
+ rescue NewRelic::Command::CommandFailure => e
+ stdout.puts e.message
+ 1 # error
end
end
end
diff --git a/lib/new_relic/ia/memcached_sampler.rb b/lib/new_relic/ia/memcached_sampler.rb
index fe73d84..0cf1817 100644
--- a/lib/new_relic/ia/memcached_sampler.rb
+++ b/lib/new_relic/ia/memcached_sampler.rb
@@ -8,7 +8,7 @@
class NewRelic::IA::MemcachedSampler < NewRelic::Agent::Sampler
include NewRelic::IA::MetricNames
- case RUBY_PLATFORM
+ case RUBY_PLATFORM
when /darwin/
# Do some special stuff...
when /linux/
@@ -23,11 +23,11 @@ def initialize
:cmd_flush, :cmd_get, :cmd_set, :get_hits, :get_misses, :evictions, :bytes_read, :bytes_written, :limit_maxbytes, :threads]
@derived_values = [ :free_bytes]
@derivatives = [:hit_ratio, :miss_ratio, :rpm, :gpm, :hpm, :mpm, :spm, :fpm, :epm]
-
+
@last_stats = Hash.new
@memcached_nodes = parse_config
end
-
+
def parse_config
# file with a list of mecached nodes. each line have hostname:port
memcached_nodes = NewRelic::Control.instance['memcached_nodes']
@@ -40,17 +40,17 @@ def parse_config
def memcached_nodes
@memcached_nodes
end
-
+
# Sanity check, make sure the servers are there.
def check
down_servers = []
memcached_nodes.each do | hostname_port |
- stats_text = issue_stats hostname_port
+ stats_text = issue_stats hostname_port
down_servers << hostname_port unless stats_text
end
raise NewRelic::Agent::Sampler::Unsupported, "Servers not available: #{down_servers.join(", ")}" unless down_servers.empty?
end
-
+
# This gets called once a minute in the agent worker thread. It
# pings each host in the array 'memcached_nodes'
def poll
@@ -61,22 +61,22 @@ def poll
@last_stats[hostname_port] = parse_and_report_stats hostname_port, stats_text
else
@last_stats[hostname_port] = nil #{}
- end
+ end
end
aggregate_stats
- debug "done with aggs"
+ debug "done with aggs"
end
end
-
- def logger
+
+ def logger
NewRelic::IA::CLI.log
end
-
+
def aggregate_stats
begin
-
- aggs_stats = Hash.new
+
+ aggs_stats = Hash.new
@int_values.each {|metric| aggs_stats[metric] = 0}
@derived_values.each {|metric| aggs_stats[metric] = 0}
@@ -95,9 +95,9 @@ def aggregate_stats
@derivatives[0,2].each do |metric|
aggs_stats[metric] += v[metric]
end
- aggs_count += 1
+ aggs_count += 1
- @derivatives[2,@derivatives.length - 2].each do |metric|
+ @derivatives[2,@derivatives.length - 2].each do |metric|
aggs_stats[metric] += v[metric]
end
end
@@ -106,9 +106,9 @@ def aggregate_stats
aggs_stats[:hit_ratio] = aggs_stats[:hit_ratio] /aggs_count
aggs_stats[:miss_ratio] = aggs_stats[:miss_ratio] /aggs_count
end
-
- if aggs_stats[:uptime] > 0
- @int_values.each do |stat|
+
+ if aggs_stats[:uptime] > 0
+ @int_values.each do |stat|
debug "recording #{MEMCACHED}/all/#{stat.to_s} = #{aggs_stats[stat]}"
begin
stats("#{MEMCACHED}/all/#{stat.to_s}").record_data_point(aggs_stats[stat])
@@ -117,7 +117,7 @@ def aggregate_stats
end
end
- @derived_values.each do |stat|
+ @derived_values.each do |stat|
debug "recording #{MEMCACHED}/all/#{stat.to_s} = #{aggs_stats[stat]}"
begin
stats("#{MEMCACHED}/all/#{stat.to_s}").record_data_point(aggs_stats[stat])
@@ -135,15 +135,15 @@ def aggregate_stats
end
end
end
- else
- debug "skipping aggregates since aggregate uptime is zero"
+ else
+ debug "skipping aggregates since aggregate uptime is zero"
end
rescue => e
debug "Could not record stat: stats\n #{e.backtrace.join("\n")}"
end
end
-
-
+
+
#TODO send stats for down nodes
def issue_stats(hostname_port)
debug "get stats from hostname #{hostname_port}"
@@ -151,10 +151,10 @@ def issue_stats(hostname_port)
split = hostname_port.split(':', 2)
hostname = split.first
port = split.last
-
+
socket = TCPSocket.open(hostname, port)
socket.send("stats\r\n", 0)
-
+
# TODO UDP or use memcached gem to use udp first and fallback to tcp
# socket = UDPSocket.open
# socket.connect(@host, @port)
@@ -182,28 +182,28 @@ def issue_stats(hostname_port)
end
nil
end
-
- def parse_stats(hostname_port, stats_text)
+
+ def parse_stats(hostname_port, stats_text)
end_index = stats_text =~ /\s+END\s+$/
stats_text = stats_text[0, end_index] if end_index
sss = stats_text.split(/\s+/)
if sss.size % 3 != 0
logger.error "memcached: unexcpected stats output from #{hostname_port}: #{stats_text}"
- break
+ raise "memcached: unexcpected stats output from #{hostname_port}: #{stats_text}"
end
triplets = []
while sss.any? do
triplets << [ sss.shift, sss.shift, sss.shift]
end
stats = Hash.new
- triplets.each do |triplet|
+ triplets.each do |triplet|
debug "#{triplet[1].to_sym} = #{triplet[2]}"
stats[triplet[1].to_sym] = triplet[2]
end
return stats
end
- def parse_and_report_stats(hostname_port, stats_text)
+ def parse_and_report_stats(hostname_port, stats_text)
# pid = 21355
# uptime = 2089
# time = 1264673782
@@ -229,46 +229,46 @@ def parse_and_report_stats(hostname_port, stats_text)
# threads = 5
# accepting_conns = 1
# listen_disabled_num = 0
-
-
+
+
# average_value
# * Active Connections - free
# * Current items
# * evictions
# * Total Size (memcache stat: limit_maxbytes)
# * Used size (memcache stat: bytes)
- #
+ #
# need to compute during collection
# * Hit Ratio (%)
- # * Requests per interval
+ # * Requests per interval
# * Hits per interval
# * Misses per interval
# * Sets per interval
# * Free size (memcache stat: limit_maxbytes - bytes)
- #
+ #
# Also send all stats.
- #
- #
- stats = parse_stats(hostname_port, stats_text)
+ #
+ #
+ stats = parse_stats(hostname_port, stats_text)
#we store ints in the hash
- @int_values.each do |stat|
- stats[stat] = stats[stat].to_i
+ @int_values.each do |stat|
+ stats[stat] = stats[stat].to_i
end
#time is not shipped to collector but we add it for derivative calculations
- stats[:time] = Time.at stats[:time].to_i
+ stats[:time] = Time.at stats[:time].to_i
stats[:free_bytes] = stats[:limit_maxbytes] - stats[:bytes]
-
+
previous_stats = @last_stats[hostname_port]
if previous_stats
tn = stats[:time]
- tm = previous_stats[:time]
+ tm = previous_stats[:time]
previous_r = previous_stats[:cmd_get] + previous_stats[:cmd_set]+ previous_stats[:cmd_flush]
current_r = stats[:cmd_get] + stats[:cmd_set]+ stats[:cmd_flush]
-
- #unit per minute
- stats[:rpm] = (current_r - previous_r) / (tn - tm) * 60
+
+ #unit per minute
+ stats[:rpm] = (current_r - previous_r) / (tn - tm) * 60
stats[:gpm] = (stats[:cmd_get] - previous_stats[:cmd_get]) / (tn - tm) * 60
stats[:spm] = (stats[:cmd_set] - previous_stats[:cmd_set]) / (tn - tm) * 60
stats[:fpm] = (stats[:cmd_flush] - previous_stats[:cmd_flush]) / (tn - tm) * 60
@@ -283,11 +283,11 @@ def parse_and_report_stats(hostname_port, stats_text)
stats[:miss_ratio] = 0
end
end
-
+
#string_values = [:version]
#float_values = [:rusage_user, :rusage_system]
-
- @int_values.each do |stat|
+
+ @int_values.each do |stat|
debug "recording #{MEMCACHED}/#{hostname_port}/#{stat.to_s} = #{stats[stat]}"
begin
stats("#{MEMCACHED}/#{hostname_port}/#{stat.to_s}").record_data_point(stats[stat])
@@ -295,7 +295,7 @@ def parse_and_report_stats(hostname_port, stats_text)
debug "Could not record stat: #{stat}\n #{e.backtrace.join("\n")}"
end
end
- @derived_values.each do |stat|
+ @derived_values.each do |stat|
debug "recording #{MEMCACHED}/#{hostname_port}/#{stat.to_s} = #{stats[stat]}"
begin
stats("#{MEMCACHED}/#{hostname_port}/#{stat.to_s}").record_data_point(stats[stat])
@@ -317,7 +317,7 @@ def parse_and_report_stats(hostname_port, stats_text)
end
end
- # float_values.each do |stat|
+ # float_values.each do |stat|
# debug "recording #{MEMCACHED}/#{hostname_port}/#{stat.to_s} = #{stats[stat].to_f}"
# begin
# stats("#{MEMCACHED}/#{hostname_port}/#{stat.to_s}").record_data_point(stats[stat].to_f)
@@ -328,11 +328,11 @@ def parse_and_report_stats(hostname_port, stats_text)
debug "Done with record data"
return stats
end
-
+
def stats(s)
NewRelic::Agent.get_stats_no_scope(s)
end
-
+
def debug(msg)
logger.debug "memcached: #{msg}"
end
diff --git a/lib/new_relic/ia/version.rb b/lib/new_relic/ia/version.rb
index 95eb8f4..755166f 100644
--- a/lib/new_relic/ia/version.rb
+++ b/lib/new_relic/ia/version.rb
@@ -1,5 +1,5 @@
module NewRelic
module IA
- VERSION = '0.2.1'
+ VERSION = '0.2.3'
end
end
diff --git a/newrelic_ia.gemspec b/newrelic_ia.gemspec
index a875e00..a9715aa 100644
--- a/newrelic_ia.gemspec
+++ b/newrelic_ia.gemspec
@@ -1,82 +1,26 @@
-# Generated by jeweler
-# DO NOT EDIT THIS FILE DIRECTLY
-# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/new_relic/ia/version', __FILE__)
-Gem::Specification.new do |s|
- s.name = %q{newrelic_ia}
- s.version = "0.2.1"
+Gem::Specification.new do |gem|
+ gem.authors = ["Bill Kayser"]
+ gem.email = ["bkayser@newrelic.com"]
+ gem.description = %q{The New Relic Infrastructure Agent (IA) collects system metrics and transmits
+them to the RPM server where they can be viewed with custom dashboards.}
+ gem.summary = %q{New Relic Gem for gathering system metrics}
+ gem.homepage = "http://www.newrelic.com"
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
- s.authors = ["Bill Kayser"]
- s.date = %q{2010-04-12}
- s.default_executable = %q{newrelic_ia}
- s.description = %q{The New Relic Infrastructure Agent (IA) collects system metrics and transmits
-them to the RPM server where they can be viewed with custom dashboards.
-}
- s.email = %q{bkayser@newrelic.com}
- s.executables = ["newrelic_ia"]
- s.extra_rdoc_files = [
- "CHANGELOG",
- "LICENSE",
- "README.rdoc",
- "bin/newrelic_ia"
- ]
- s.files = [
- "CHANGELOG",
- "README.rdoc",
- "Rakefile",
- "lib/new_relic/ia/cli.rb",
- "lib/new_relic/ia/disk_sampler.rb",
- "lib/new_relic/ia/iostat_reader.rb",
- "lib/new_relic/ia/iostat_reader/linux.rb",
- "lib/new_relic/ia/iostat_reader/osx.rb",
- "lib/new_relic/ia/memcached_sampler.rb",
- "lib/new_relic/ia/metric_names.rb",
- "lib/new_relic/ia/newrelic.yml",
- "lib/new_relic/ia/version.rb",
- "lib/newrelic_ia.rb",
- "spec/cli_spec.rb",
- "spec/disk_sampler_spec.rb",
- "spec/iostat-linux.out",
- "spec/iostat-osx.out",
- "spec/iostat_reader_spec.rb",
- "spec/memcached-1.out",
- "spec/memcached-nodes.txt",
- "spec/memcached_sampler_spec.rb",
- "spec/spec.opts",
- "spec/spec_helper.rb",
- "tasks/rspec.rake"
- ]
- s.homepage = %q{http://www.newrelic.com}
- s.post_install_message = %q{
-For more information refer to http://support.newrelic.com or
-say 'newrelic' at #newrelic on freenode IRC.
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ gem.files = `git ls-files`.split("\n")
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ gem.name = "newrelic_ia"
+ gem.require_paths = ["lib"]
+ gem.version = NewRelic::IA::VERSION
+ gem.extra_rdoc_files = %w[CHANGELOG LICENSE README.rdoc bin/newrelic_ia]
+ gem.post_install_message = %q{For more information refer to http://support.newrelic.com or
+say 'newrelic' at #newrelic on freenode IRC.}
-}
- s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source", "--title", "New Relic Gem for gathering system metrics", "-m", "README.rdoc"]
- s.require_paths = ["lib"]
- s.rubygems_version = %q{1.3.6}
- s.summary = %q{New Relic Gem for gathering system metrics}
- s.test_files = [
- "spec/cli_spec.rb",
- "spec/disk_sampler_spec.rb",
- "spec/iostat_reader_spec.rb",
- "spec/memcached_sampler_spec.rb",
- "spec/spec_helper.rb"
- ]
-
- if s.respond_to? :specification_version then
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
- s.specification_version = 3
-
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
- s.add_runtime_dependency(%q, [">= 2.10.6"])
- else
- s.add_dependency(%q, [">= 2.10.6"])
- end
- else
- s.add_dependency(%q, [">= 2.10.6"])
- end
+ gem.add_dependency 'newrelic_rpm', '>=3.1.0'
+ gem.add_development_dependency 'rspec', '>= 2.0.0'
+ gem.add_development_dependency 'mocha', '>= 0'
end
diff --git a/spec/cli_spec.rb b/spec/cli_spec.rb
index a018b8b..f3154e8 100644
--- a/spec/cli_spec.rb
+++ b/spec/cli_spec.rb
@@ -6,6 +6,7 @@
describe NewRelic::IA::CLI, "execute" do
before(:each) do
@stdout_io = StringIO.new
+ NewRelic::Agent::Agent.any_instance.stubs(:connected?).returns(true)
end
it "should print help" do
NewRelic::IA::CLI.execute(@stdout_io, [ "-h"])
@@ -30,12 +31,16 @@
end
it "should start memcached" do
NewRelic::Agent::StatsEngine.any_instance.expects(:add_harvest_sampler)
+ NewRelic::IA::MemcachedSampler.any_instance.stubs(:check)
stat = NewRelic::IA::CLI.execute(@stdout_io, [ "memcached"])
stat.should == nil
end
+ it "should install a newrelic.yml" do
+ NewRelic::IA::CLI.execute(@stdout_io, ["--install", "01234567"])
+ end
it "should override the env" do
stat = NewRelic::IA::CLI.execute(@stdout_io, [ "disk", "-e", "production"])
stat.should == nil
NewRelic::Control.instance.env.should == "production"
end
-end
\ No newline at end of file
+end
diff --git a/spec/disk_sampler_spec.rb b/spec/disk_sampler_spec.rb
index 9617889..511b6db 100644
--- a/spec/disk_sampler_spec.rb
+++ b/spec/disk_sampler_spec.rb
@@ -2,18 +2,18 @@
require 'new_relic/ia/disk_sampler'
# http://rspec.info/
describe NewRelic::IA::DiskSampler do
-
+
before do
@sampler = NewRelic::IA::DiskSampler.new
# @statsengine = stub(:get_stats => @stats)
@statsengine = NewRelic::Agent::StatsEngine.new
@sampler.stats_engine = @statsengine
end
-
+
it "should poll on demand" do
2.times { @sampler.poll }
@statsengine.metrics.each do |m|
- stats = @statsengine.lookup_stat m
+ stats = @statsengine.lookup_stats m
stats.call_count.should == 2
m.should match(/System\/Filesystem\/.*percent/)
end
diff --git a/spec/iostat_reader_spec.rb b/spec/iostat_reader_spec.rb
index 01c9186..a2f3a15 100644
--- a/spec/iostat_reader_spec.rb
+++ b/spec/iostat_reader_spec.rb
@@ -10,53 +10,53 @@ def cmd; "iostat -dCI 2" ; end
end
describe NewRelic::IA::IostatReader do
-
+
include NewRelic::IA::MetricNames
- METRICS = [NewRelic::IA::MetricNames::SYSTEM_CPU, NewRelic::IA::MetricNames::USER_CPU, NewRelic::IA::MetricNames::DISK_IO].sort
+ METRICS = [NewRelic::IA::MetricNames::SYSTEM_CPU, NewRelic::IA::MetricNames::USER_CPU, NewRelic::IA::MetricNames::DISK_IO].sort
before do
@statsengine = NewRelic::Agent::StatsEngine.new
NewRelic::Agent.instance.stubs(:stats_engine).returns(@statsengine)
@reader = NewRelic::IA::IostatReader.new
end
-
+
def canned_data_loader(filename)
@reader.instance_eval do
@pipe = File.open(File.join(File.dirname(__FILE__),filename))
end
- @reader.init
+ @reader.init
@reader.read_next
@reader.read_next
@reader.read_next
metrics = [NewRelic::IA::MetricNames::SYSTEM_CPU, NewRelic::IA::MetricNames::USER_CPU, NewRelic::IA::MetricNames::DISK_IO].sort
@statsengine.metrics.sort.should == metrics
- stats = metrics.map { | m | [m, @statsengine.lookup_stat(m) ] }
+ stats = metrics.map { | m | [m, @statsengine.lookup_stats(m) ] }
Hash[*stats.flatten]
end
-
+
it "should read repeatedly" do
@reader.init
@reader.read_next
@reader.read_next
@statsengine.metrics.sort.should == METRICS
@statsengine.metrics.each do |m|
- stats = @statsengine.lookup_stat m
+ stats = @statsengine.lookup_stats m
stats.call_count.should == 2
end
end
-
+
it "should process linux stats" do
# NewRelic::IA::CLI.log.level=Logger::DEBUG
@reader.extend NewRelic::IA::IostatReader::Linux
stats = canned_data_loader("iostat-linux.out")
-
+
stats[NewRelic::IA::MetricNames::DISK_IO].total_call_time.should == 8261632.0
stats[NewRelic::IA::MetricNames::DISK_IO].call_count.should == 9
- stats[NewRelic::IA::MetricNames::SYSTEM_CPU].call_count.should == 3
- stats[NewRelic::IA::MetricNames::SYSTEM_CPU].total_call_time.should == 1.51
- stats[NewRelic::IA::MetricNames::USER_CPU].call_count.should == 3
+ stats[NewRelic::IA::MetricNames::SYSTEM_CPU].call_count.should == 3
+ stats[NewRelic::IA::MetricNames::SYSTEM_CPU].total_call_time.should == 1.51
+ stats[NewRelic::IA::MetricNames::USER_CPU].call_count.should == 3
stats[NewRelic::IA::MetricNames::USER_CPU].total_call_time.should == 33.0
end
-
+
it "should process osx stats" do
# NewRelic::IA::CLI.log.level=Logger::DEBUG
@reader.extend NewRelic::IA::IostatReader::OSX
@@ -66,5 +66,5 @@ def canned_data_loader(filename)
stats[NewRelic::IA::MetricNames::USER_CPU].total_call_time.should == 15.0
stats[NewRelic::IA::MetricNames::DISK_IO].total_call_time.round.should == 1468006.0
end
-
+
end
diff --git a/spec/memcached_sampler_spec.rb b/spec/memcached_sampler_spec.rb
index 3e4203d..c622952 100644
--- a/spec/memcached_sampler_spec.rb
+++ b/spec/memcached_sampler_spec.rb
@@ -2,7 +2,7 @@
require 'new_relic/ia/memcached_sampler'
# http://rspec.info/
describe NewRelic::IA::MemcachedSampler do
-
+
before do
#NewRelic::Agent.instance.log.level = Logger::DEBUG
NewRelic::Agent.reset_stats
@@ -10,22 +10,22 @@
logger = Logger.new(STDOUT)
logger.level = Logger::INFO
@sampler.stubs(:logger).returns(logger)
-
+
# @statsengine = stub(:get_stats => @stats)
@statsengine = NewRelic::Agent::StatsEngine.new
@sampler.stats_engine = @statsengine
@sampler.stubs(:memcached_nodes).returns(["localhost:11211"])
- @statsengine.clear_stats
+ @statsengine.clear_stats
end
-
+
it "should parse stats" do
file = File.open(File.join(File.dirname(__FILE__),"memcached-1.out"), "r")
stats_text = file.read
@sampler.stubs(:issue_stats).returns(stats_text)
-
+
@sampler.poll
@statsengine.metrics.each do |m|
- stats = @statsengine.lookup_stat m
+ stats = @statsengine.lookup_stats m
stats.call_count.should == 1
m.should match(/System\/Memcached.*/)
end
@@ -34,15 +34,15 @@
@sampler.stubs(:issue_stats).returns(nil)
@sampler.poll
@statsengine.metrics.each do |m|
- stats = @statsengine.lookup_stat m
+ stats = @statsengine.lookup_stats m
stats.call_count.should == 0
end
@sampler.stubs(:issue_stats).returns("")
@sampler.poll
-
+
@statsengine.metrics.each do |m|
- stats = @statsengine.lookup_stat m
+ stats = @statsengine.lookup_stats m
puts "#{m}: #{stats}"
stats.call_count.should == 0
end
@@ -50,7 +50,7 @@
# it "should poll on demand" do
# 2.times { @sampler.poll }
# @statsengine.metrics.each do |m|
- # stats = @statsengine.lookup_stat m
+ # stats = @statsengine.lookup_stats m
# stats.call_count.should == 2
# m.should match(/System\/Filesystem\/.*percent/)
# end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 6abc103..dbb5776 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -4,8 +4,7 @@
require 'newrelic_rpm'
rescue LoadError
require 'rubygems' unless ENV['NO_RUBYGEMS']
- gem 'rspec'
- require 'spec'
+ require 'rspec'
require 'newrelic_ia'
require 'newrelic_rpm'
end
@@ -15,7 +14,7 @@
module NewRelic; TEST = true; end unless defined? NewRelic::TEST
NewRelic::IA::CLI.level = Logger::ERROR
-Spec::Runner.configure do |config|
+RSpec.configure do |config|
# == Fixtures
#
# You can declare fixtures for each example_group like this:
@@ -49,6 +48,6 @@ module NewRelic; TEST = true; end unless defined? NewRelic::TEST
config.mock_with :mocha
# == Notes
- #
+ #
# For more information take a look at Spec::Example::Configuration and Spec::Runner
end
diff --git a/tasks/rspec.rake b/tasks/rspec.rake
deleted file mode 100644
index 31a99b0..0000000
--- a/tasks/rspec.rake
+++ /dev/null
@@ -1,21 +0,0 @@
-begin
- require 'spec'
-rescue LoadError
- require 'rubygems' unless ENV['NO_RUBYGEMS']
- require 'spec'
-end
-begin
- require 'spec/rake/spectask'
-rescue LoadError
- puts <<-EOS
-To use rspec for testing you must install rspec gem:
- gem install rspec
-EOS
- exit(0)
-end
-
-desc "Run the specs under spec/models"
-Spec::Rake::SpecTask.new do |t|
- t.spec_opts = ['--options', "spec/spec.opts"]
- t.spec_files = FileList['spec/**/*_spec.rb']
-end