scout_api 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/CHANGELOG +3 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +25 -0
- data/LICENSE +20 -0
- data/README.rdoc +81 -0
- data/Rakefile +43 -0
- data/lib/scout_api/account.rb +72 -0
- data/lib/scout_api/alert.rb +17 -0
- data/lib/scout_api/group.rb +73 -0
- data/lib/scout_api/metric.rb +243 -0
- data/lib/scout_api/metric_calculation.rb +61 -0
- data/lib/scout_api/metric_proxy.rb +112 -0
- data/lib/scout_api/person.rb +3 -0
- data/lib/scout_api/plugin.rb +61 -0
- data/lib/scout_api/server.rb +165 -0
- data/lib/scout_api/trigger.rb +11 -0
- data/lib/scout_api/version.rb +3 -0
- data/lib/scout_api.rb +22 -0
- data/scout_scout.gemspec +86 -0
- data/test/alert_test.rb +20 -0
- data/test/fixtures/activities.xml +33 -0
- data/test/fixtures/client.xml +22 -0
- data/test/fixtures/client_by_hostname.xml +23 -0
- data/test/fixtures/clients.xml +59 -0
- data/test/fixtures/data.xml +5 -0
- data/test/fixtures/descriptors.xml +93 -0
- data/test/fixtures/plugin_data.xml +62 -0
- data/test/fixtures/plugins.xml +127 -0
- data/test/fixtures/triggers.xml +40 -0
- data/test/global_test.rb +27 -0
- data/test/metric_proxy_test.rb +17 -0
- data/test/metric_test.rb +32 -0
- data/test/plugin_test.rb +12 -0
- data/test/server_test.rb +97 -0
- data/test/test_helper.rb +53 -0
- metadata +185 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
# This class works similar to Ruby on Rails' AssociationProxy, providing a nice interface to metrics
|
2
|
+
# from owner objects in Scout (ex: Server, Group, Plugin).
|
3
|
+
# See http://stackoverflow.com/questions/1529606/how-do-rails-association-methods-work for background
|
4
|
+
#
|
5
|
+
# Example usage:
|
6
|
+
# group.metrics => all metrics associated with the group
|
7
|
+
# server.metrics.average('idle') => average value of all metrics w/name 'idle' associated with the server
|
8
|
+
class Scout::MetricProxy
|
9
|
+
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$|is\_a\?)/ }
|
10
|
+
attr_reader :owner
|
11
|
+
|
12
|
+
def initialize(owner) #:nodoc:
|
13
|
+
@owner = owner
|
14
|
+
@avg_calc = Scout::MetricCalculation.new(self,:AVG)
|
15
|
+
@min_calc = Scout::MetricCalculation.new(self,:MIN)
|
16
|
+
@max_calc = Scout::MetricCalculation.new(self,:MAX)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Calculate the average value of the metric w/<tt>:name => metric_name</tt> associated with the proxy owner (Group, Server, or Plugin).
|
20
|
+
#
|
21
|
+
# See Metric#average for options.
|
22
|
+
#
|
23
|
+
# @return [Hash]
|
24
|
+
def average(options)
|
25
|
+
@avg_calc.metric_name = metric_from_options(options)
|
26
|
+
@avg_calc.options = options
|
27
|
+
@avg_calc
|
28
|
+
end
|
29
|
+
alias avg average
|
30
|
+
|
31
|
+
# Calculate the minimum value of the metric w/<tt>:name => metric_name</tt> associated with the proxy owner (Group, Server, or Plugin).
|
32
|
+
#
|
33
|
+
# See Metric#average for options.
|
34
|
+
#
|
35
|
+
# @return [Hash]
|
36
|
+
def minimum(options)
|
37
|
+
@min_calc.metric_name = metric_from_options(options)
|
38
|
+
@min_calc.options = options
|
39
|
+
@min_calc
|
40
|
+
end
|
41
|
+
alias min minimum
|
42
|
+
|
43
|
+
# Calculate the maximum value of the metric w/<tt>:name => metric_name</tt> associated with the proxy owner (Group, Server, or Plugin).
|
44
|
+
#
|
45
|
+
# See Metric#average for options.
|
46
|
+
#
|
47
|
+
# @return [Hash]
|
48
|
+
def maximum(options)
|
49
|
+
@max_calc.metric_name = metric_from_options(options)
|
50
|
+
@max_calc.options = options
|
51
|
+
@max_calc
|
52
|
+
end
|
53
|
+
alias max maximum
|
54
|
+
|
55
|
+
# Find all metrics w/ <tt>:name => metric_name</tt> associated with the proxy owner (Group, Server, or Plugin).
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
#
|
59
|
+
# <tt>server.metrics.all(:name => 'request_rate')</tt> => returns all metrics on +server+ w/the name 'request_rate'.
|
60
|
+
#
|
61
|
+
# @return [Array] An array of [Scout::Metric] objects
|
62
|
+
def all(options = nil)
|
63
|
+
metric_name = options[:name] if options
|
64
|
+
Scout::Metric.all(
|
65
|
+
owner_key_value.merge!(:name => metric_name)
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def load_target #:nodoc:
|
70
|
+
@target = find_target
|
71
|
+
end
|
72
|
+
|
73
|
+
def find_target #:nodoc:
|
74
|
+
if @owner.is_a?(Scout::Plugin) # plugin already has metric info
|
75
|
+
@owner.descriptor_hash.map { |d| Scout::Metric.new(d) }
|
76
|
+
else
|
77
|
+
Scout::Metric.all(owner_key_value)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# Ensures that a metric name is provided in the +options+ Hash.
|
84
|
+
# If one isn't provided, a Scout::Error is raised.
|
85
|
+
#
|
86
|
+
# @return [String]
|
87
|
+
def metric_from_options(options)
|
88
|
+
metric_name = options[:name]
|
89
|
+
raise Scout::Error, "The name of the metric is required (:name => metric_name)" if metric_name.blank?
|
90
|
+
metric_name
|
91
|
+
end
|
92
|
+
|
93
|
+
def owner_key_value
|
94
|
+
{ (@owner.class.to_s.sub('Scout::','').downcase+'_ids').to_sym => @owner.id}
|
95
|
+
end
|
96
|
+
|
97
|
+
def method_missing(method, *args)
|
98
|
+
if load_target
|
99
|
+
unless @target.respond_to?(method)
|
100
|
+
message = "undefined method `#{method.to_s}' for \"#{@target}\":#{@target.class.to_s}"
|
101
|
+
raise NoMethodError, message
|
102
|
+
end
|
103
|
+
|
104
|
+
if block_given?
|
105
|
+
@target.send(method, *args) { |*block_args| yield(*block_args) }
|
106
|
+
else
|
107
|
+
@target.send(method, *args)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Scout::Plugin < Hashie::Mash
|
2
|
+
attr_accessor :server
|
3
|
+
|
4
|
+
# Retrieve metric information. See Scout::Metric#average for a list of options for the calculation
|
5
|
+
# methods (average, minimum, maximum).
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
#
|
9
|
+
# * <tt>Scout::Plugin.metrics => All metrics associated with this plugin.</tt>
|
10
|
+
# * <tt>Scout::Plugin.metrics.all(:name => 'mem_used') => Metrics with name =~ 'mem_used' on this plugin.</tt>
|
11
|
+
# * <tt>Scout::Plugin.metrics.average(:name => 'mem_used') => Average value of metrics with name =~ 'mem_used' on this plugin.</tt>
|
12
|
+
# * <tt>Scout::Plugin.metrics.maximum(:name => 'mem_used')</tt>
|
13
|
+
# * <tt>Scout::Plugin.metrics.minimum(:name => 'mem_used')</tt>
|
14
|
+
# * <tt>Scout::Plugin.metrics.average(:name => 'request_rate', :aggregate => true) => Sum metrics, then take average</tt>
|
15
|
+
# * <tt>Scout::Plugin.metrics.average(:name => 'request_rate', :start => Time.now.utc-5*3600, :end => Time.now.utc-2*3600) => Retrieve data starting @ 5 hours ago ending at 2 hours ago</tt>
|
16
|
+
# * <tt>Scout::Plugin.metrics.average(:name => 'mem_used').to_array => An array of time series values over the past hour.</tt>
|
17
|
+
# * <tt>Scout::Plugin.metrics.average(:name => 'mem_used').to_sparkline => A Url to a Google Sparkline Chart.</tt>
|
18
|
+
attr_reader :metrics
|
19
|
+
|
20
|
+
attr_reader :descriptor_hash #:nodoc:
|
21
|
+
|
22
|
+
def initialize(hash) #:nodoc:
|
23
|
+
if hash['descriptors'] && hash['descriptors']['descriptor']
|
24
|
+
@descriptor_hash = hash['descriptors']['descriptor']
|
25
|
+
hash.delete('descriptors')
|
26
|
+
end
|
27
|
+
@metrics = Scout::MetricProxy.new(self)
|
28
|
+
super(hash)
|
29
|
+
end
|
30
|
+
|
31
|
+
def email_subscribers
|
32
|
+
response = Scout::Account.get("/clients/#{server.id}/email_subscribers?plugin_id=#{id}")
|
33
|
+
doc = Nokogiri::HTML(response.body)
|
34
|
+
|
35
|
+
table = doc.css('table.list').first
|
36
|
+
user_rows = table.css('tr')[1..-1] # skip first row, which is headings
|
37
|
+
|
38
|
+
user_rows.map do |row|
|
39
|
+
name_td, receiving_notifications_td = *row.css('td')
|
40
|
+
|
41
|
+
name = name_td.content.gsub(/[\t\n]/, '')
|
42
|
+
checked = receiving_notifications_td.css('input').attribute('checked')
|
43
|
+
receiving_notifications = checked && checked.value == 'checked'
|
44
|
+
Hashie::Mash.new :name => name, :receiving_notifications => receiving_notifications
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def triggers
|
49
|
+
response = Scout::Account.get("/clients/#{server.id}/triggers.xml?plugin_id=#{id}")
|
50
|
+
response['triggers'].map { |trigger| decorate_with_server_and_plugin(Scout::Trigger.new(trigger)) }
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def decorate_with_server_and_plugin(hashie) #:nodoc:
|
56
|
+
hashie.server = self.server
|
57
|
+
hashie.plugin = self
|
58
|
+
hashie
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
class Scout::Server < Hashie::Mash
|
2
|
+
# Retrieve metric information. See Scout::Metric#average for a list of options for the calculation
|
3
|
+
# methods (average, minimum, maximum).
|
4
|
+
#
|
5
|
+
# Examples:
|
6
|
+
#
|
7
|
+
# * <tt>Scout::Server.metrics => All metrics associated with this server.</tt>
|
8
|
+
# * <tt>Scout::Server.metrics.all(:name => 'mem_used') => Metrics with name =~ 'mem_used' on this server.</tt>
|
9
|
+
# * <tt>Scout::Server.metrics.average(:name => 'mem_used') => Average value of metrics with name =~ 'mem_used' on this server.</tt>
|
10
|
+
# * <tt>Scout::Server.metrics.maximum(:name => 'mem_used')</tt>
|
11
|
+
# * <tt>Scout::Server.metrics.minimum(:name => 'mem_used')</tt>
|
12
|
+
# * <tt>Scout::Server.metrics.average(:name => 'request_rate', :aggregate => true) => Sum metrics, then take average</tt>
|
13
|
+
# * <tt>Scout::Server.metrics.average(:name => 'request_rate', :start => Time.now.utc-5*3600, :end => Time.now.utc-2*3600) => Retrieve data starting @ 5 hours ago ending at 2 hours ago</tt>
|
14
|
+
# * <tt>Scout::Server.metrics.average(:name => 'mem_used').to_array => An array of time series values over the past hour.</tt>
|
15
|
+
# * <tt>Scout::Server.metrics.average(:name => 'mem_used').to_sparkline => A Url to a Google Sparkline Chart.</tt>
|
16
|
+
attr_reader :metrics
|
17
|
+
|
18
|
+
def initialize(hash) #:nodoc:
|
19
|
+
if hash['active_alerts']
|
20
|
+
@alert_hash = hash['active_alerts']
|
21
|
+
hash.delete('active_alerts')
|
22
|
+
end
|
23
|
+
@metrics = Scout::MetricProxy.new(self)
|
24
|
+
super(hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Finds the first server that meets the given conditions. Possible parameter formats:
|
28
|
+
#
|
29
|
+
# * <tt>Scout::Server.first</tt>
|
30
|
+
# * <tt>Scout::Server.first(1)</tt>
|
31
|
+
# * <tt>Scout::Server.first(:name => 'db slaves')</tt>
|
32
|
+
# * <tt>Scout::Server.first(:host => 'web*.geocities')</tt>
|
33
|
+
#
|
34
|
+
#
|
35
|
+
# For the <tt>:name</tt> and <tt>:host</tt> options, a {MySQL-formatted Regex}[http://dev.mysql.com/doc/refman/5.0/en/regexp.html] can be used.
|
36
|
+
#
|
37
|
+
# @return [Scout::Server]
|
38
|
+
def self.first(id_or_options = nil)
|
39
|
+
if id_or_options.nil?
|
40
|
+
response = Scout::Account.get("/clients.xml?limit=1")
|
41
|
+
Scout::Server.new(response['clients'].first)
|
42
|
+
elsif id_or_options.is_a?(Hash)
|
43
|
+
if name=id_or_options[:name]
|
44
|
+
response = Scout::Account.get("/clients.xml?name=#{CGI.escape(name)}")
|
45
|
+
raise Scout::Error, 'Not Found' if response['clients'].nil?
|
46
|
+
Scout::Server.new(response['clients'].first)
|
47
|
+
elsif host=id_or_options[:host]
|
48
|
+
response = Scout::Account.get("/clients.xml?host=#{CGI.escape(host)}")
|
49
|
+
raise Scout::Error, 'Not Found' if response['clients'].nil?
|
50
|
+
Scout::Server.new(response['clients'].first)
|
51
|
+
else
|
52
|
+
raise Scout::Error, "Invalid finder condition"
|
53
|
+
end
|
54
|
+
elsif id_or_options.is_a?(Fixnum)
|
55
|
+
response = Scout::Account.get("/clients/#{id_or_options}.xml")
|
56
|
+
Scout::Server.new(response['client'])
|
57
|
+
elsif id_or_options.is_a?(String)
|
58
|
+
warn "Server#first(hostname) will be deprecated. Use Server#first(:host => hostname)"
|
59
|
+
response = Scout::Account.get("/clients.xml?host=#{CGI.escape(id_or_options)}")
|
60
|
+
raise Scout::Error, 'Not Found' if response['clients'].nil?
|
61
|
+
Scout::Server.new(response['clients'].first)
|
62
|
+
else
|
63
|
+
raise Scout::Error, "Invalid finder condition"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Finds all servers that meets the given conditions. Possible parameter formats:
|
68
|
+
#
|
69
|
+
# * <tt>Scout::Server.all(:name => 'db slaves')</tt>
|
70
|
+
# * <tt>Scout::Server.all(:host => 'web*.geocities')</tt>
|
71
|
+
#
|
72
|
+
# For the <tt>:name</tt> and <tt>:host</tt> options, a {MySQL-formatted Regex}[http://dev.mysql.com/doc/refman/5.0/en/regexp.html] can be used.
|
73
|
+
#
|
74
|
+
# @return [Array] An array of Scout::Server objects
|
75
|
+
def self.all(options = {})
|
76
|
+
if name=options[:name]
|
77
|
+
response = Scout::Account.get("/clients.xml?name=#{CGI.escape(name)}")
|
78
|
+
elsif host=options[:host]
|
79
|
+
response = Scout::Account.get("/clients.xml?host=#{CGI.escape(host)}")
|
80
|
+
elsif options.empty?
|
81
|
+
response = Scout::Account.get("/clients.xml")
|
82
|
+
else
|
83
|
+
raise Scout::Error, "Invalid finder condition"
|
84
|
+
end
|
85
|
+
response['clients'] ? response['clients'].map { |client| Scout::Server.new(client) } : Array.new
|
86
|
+
end
|
87
|
+
|
88
|
+
# Creates a new server. If an error occurs, a [Scout::Error] is raised.
|
89
|
+
#
|
90
|
+
# An optional existing server id can be used as a template:
|
91
|
+
# <tt>Scout::Server.create('web server 12',:id => 99999)</tt>
|
92
|
+
#
|
93
|
+
# @return [Scout::Server]
|
94
|
+
def self.create(name,options = {})
|
95
|
+
id = options[:id]
|
96
|
+
response = Scout::Account.post("/#{Scout::Account.param}/clients.xml",
|
97
|
+
:query => {:client => {:name => name, :copy_plugins_from_client_id => id}, :api_version => Scout::VERSION})
|
98
|
+
|
99
|
+
raise Scout::Error, response['errors']['error'] if response['errors']
|
100
|
+
|
101
|
+
first(response.headers['id'].first.to_i)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Delete a server by <tt>id</tt>. If an error occurs, a [Scout::Error] is raised.
|
105
|
+
#
|
106
|
+
# @return [true]
|
107
|
+
def self.delete(id)
|
108
|
+
response = Scout::Account.delete("/#{Scout::Account.param}/clients/#{id}.xml?api_version=#{Scout::VERSION}")
|
109
|
+
|
110
|
+
if response.headers['status'].first.match('404')
|
111
|
+
raise Scout::Error, "Server Not Found"
|
112
|
+
elsif !response.headers['status'].first.match('200')
|
113
|
+
raise Scout::Error, "An error occured"
|
114
|
+
else
|
115
|
+
return true
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Active alerts for this server
|
120
|
+
#
|
121
|
+
# @return [Array] An array of Scout::Alert objects
|
122
|
+
def active_alerts
|
123
|
+
@active_alerts ||= @alert_hash.map { |a| decorate_with_server(Scout::Alert.new(a)) }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Recent alerts for this server
|
127
|
+
#
|
128
|
+
# @return [Array] An array of Scout::Alert objects
|
129
|
+
def alerts
|
130
|
+
response = Scout::Account.get("/clients/#{self.id}/activities.xml")
|
131
|
+
response['alerts'].map { |alert| decorate_with_server(Scout::Alert.new(alert)) }
|
132
|
+
end
|
133
|
+
|
134
|
+
# Details about all plugins for this server
|
135
|
+
#
|
136
|
+
# @return [Array] An array of Scout::Plugin objects
|
137
|
+
def plugins
|
138
|
+
response = Scout::Account.get("/clients/#{self.id}/plugins.xml")
|
139
|
+
response['plugins'].map { |plugin| decorate_with_server(Scout::Plugin.new(plugin)) }
|
140
|
+
end
|
141
|
+
|
142
|
+
# Details about a specific plugin
|
143
|
+
#
|
144
|
+
# @return [Scout::Plugin]
|
145
|
+
def plugin(id)
|
146
|
+
response = Scout::Account.get("/clients/#{self.id}/plugins/#{id}.xml")
|
147
|
+
decorate_with_server(Scout::Plugin.new(response['plugin']))
|
148
|
+
end
|
149
|
+
|
150
|
+
# Details about all triggers for this server
|
151
|
+
#
|
152
|
+
# @return [Array] An array of Scout::Trigger objects
|
153
|
+
def triggers
|
154
|
+
response = Scout::Account.get("/clients/#{self.id}/triggers.xml")
|
155
|
+
response['triggers'].map { |trigger| decorate_with_server(Scout::Trigger.new(trigger)) }
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
def decorate_with_server(hashie) #:nodoc:
|
161
|
+
hashie.server = self
|
162
|
+
hashie
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
data/lib/scout_api.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hashie'
|
3
|
+
require 'httparty'
|
4
|
+
require 'nokogiri'
|
5
|
+
require 'cgi'
|
6
|
+
require 'scout_api/version'
|
7
|
+
require 'scout_api/account'
|
8
|
+
require 'scout_api/server'
|
9
|
+
require 'scout_api/plugin'
|
10
|
+
require 'scout_api/trigger'
|
11
|
+
require 'scout_api/alert'
|
12
|
+
require 'scout_api/group.rb'
|
13
|
+
require 'scout_api/metric.rb'
|
14
|
+
require 'scout_api/person'
|
15
|
+
require 'scout_api/metric_proxy'
|
16
|
+
require 'scout_api/metric_calculation'
|
17
|
+
|
18
|
+
|
19
|
+
module Scout
|
20
|
+
class Error < RuntimeError
|
21
|
+
end
|
22
|
+
end
|
data/scout_scout.gemspec
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{scout_scout}
|
8
|
+
s.version = "0.0.6"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jesse Newland"]
|
12
|
+
s.date = %q{2011-04-10}
|
13
|
+
s.description = %q{API wrapper for scout.com}
|
14
|
+
s.email = %q{jnewland@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"lib/scout_scout.rb",
|
27
|
+
"lib/scout_scout/alert.rb",
|
28
|
+
"lib/scout_scout/cluster.rb",
|
29
|
+
"lib/scout_scout/descriptor.rb",
|
30
|
+
"lib/scout_scout/metric.rb",
|
31
|
+
"lib/scout_scout/person.rb",
|
32
|
+
"lib/scout_scout/plugin.rb",
|
33
|
+
"lib/scout_scout/server.rb",
|
34
|
+
"lib/scout_scout/trigger.rb",
|
35
|
+
"lib/scout_scout/version.rb",
|
36
|
+
"scout_scout.gemspec",
|
37
|
+
"spec/fixtures/activities.xml",
|
38
|
+
"spec/fixtures/client.xml",
|
39
|
+
"spec/fixtures/client_by_hostname.xml",
|
40
|
+
"spec/fixtures/clients.xml",
|
41
|
+
"spec/fixtures/data.xml",
|
42
|
+
"spec/fixtures/descriptors.xml",
|
43
|
+
"spec/fixtures/plugin_data.xml",
|
44
|
+
"spec/fixtures/plugins.xml",
|
45
|
+
"spec/fixtures/triggers.xml",
|
46
|
+
"spec/scout_scout_spec.rb",
|
47
|
+
"spec/spec.opts",
|
48
|
+
"spec/spec_helper.rb"
|
49
|
+
]
|
50
|
+
s.homepage = %q{http://github.com/jnewland/scout_scout}
|
51
|
+
s.require_paths = ["lib"]
|
52
|
+
s.rubygems_version = %q{1.4.2}
|
53
|
+
s.summary = %q{API wrapper for scout.com}
|
54
|
+
s.test_files = [
|
55
|
+
"spec/scout_scout_spec.rb",
|
56
|
+
"spec/spec_helper.rb"
|
57
|
+
]
|
58
|
+
|
59
|
+
if s.respond_to? :specification_version then
|
60
|
+
s.specification_version = 3
|
61
|
+
|
62
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
63
|
+
s.add_runtime_dependency(%q<hashie>, ["~> 0.1.8"])
|
64
|
+
s.add_runtime_dependency(%q<httparty>, ["~> 0.5.0"])
|
65
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
66
|
+
s.add_development_dependency(%q<rspec>, ["~> 1.3.0"])
|
67
|
+
s.add_development_dependency(%q<fakeweb>, [">= 0"])
|
68
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.0"])
|
69
|
+
else
|
70
|
+
s.add_dependency(%q<hashie>, ["~> 0.1.8"])
|
71
|
+
s.add_dependency(%q<httparty>, ["~> 0.5.0"])
|
72
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
73
|
+
s.add_dependency(%q<rspec>, ["~> 1.3.0"])
|
74
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
75
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.0"])
|
76
|
+
end
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<hashie>, ["~> 0.1.8"])
|
79
|
+
s.add_dependency(%q<httparty>, ["~> 0.5.0"])
|
80
|
+
s.add_dependency(%q<nokogiri>, [">= 0"])
|
81
|
+
s.add_dependency(%q<rspec>, ["~> 1.3.0"])
|
82
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
83
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.0"])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
data/test/alert_test.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path('../test_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
class AlertTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@scout = Scout::Account.new('account', 'username', 'password')
|
6
|
+
@scout.stub_get('activities.xml')
|
7
|
+
@scout.stub_get('clients/24331.xml', 'client.xml')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_server
|
11
|
+
activities = @scout.alerts
|
12
|
+
assert activities.first.server.is_a?(Scout::Server)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_plugin
|
16
|
+
@scout.stub_get('clients/13431/plugins/122761.xml', 'plugin_data.xml')
|
17
|
+
activities = @scout.alerts
|
18
|
+
assert activities.first.plugin.is_a?(Scout::Plugin)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<alerts type="array">
|
3
|
+
<alert>
|
4
|
+
<body nil="true"></body>
|
5
|
+
<client-id type="integer">24331</client-id>
|
6
|
+
<email-viewed-at type="datetime" nil="true"></email-viewed-at>
|
7
|
+
<id type="integer">35793021</id>
|
8
|
+
<last-repeated-at type="datetime">2010-01-21T20:30:00-05:00</last-repeated-at>
|
9
|
+
<needs-sms type="integer">0</needs-sms>
|
10
|
+
<num-repeats type="integer">1</num-repeats>
|
11
|
+
<plugin-id type="integer">122761</plugin-id>
|
12
|
+
<sms-sent-at type="datetime" nil="true"></sms-sent-at>
|
13
|
+
<stopped-repeating-at type="datetime" nil="true"></stopped-repeating-at>
|
14
|
+
<time type="datetime">2010-01-21T20:30:00-05:00</time>
|
15
|
+
<trigger-id type="integer">101821</trigger-id>
|
16
|
+
<title> Passenger Global Queue Depth met or exceeded 1 , increasing to 2 for 30 minutes at 08:30PM </title>
|
17
|
+
</alert>
|
18
|
+
<alert>
|
19
|
+
<body nil="true"></body>
|
20
|
+
<client-id type="integer">22301</client-id>
|
21
|
+
<email-viewed-at type="datetime" nil="true"></email-viewed-at>
|
22
|
+
<id type="integer">35793011</id>
|
23
|
+
<last-repeated-at type="datetime">2010-01-21T20:30:00-05:00</last-repeated-at>
|
24
|
+
<needs-sms type="integer">0</needs-sms>
|
25
|
+
<num-repeats type="integer">1</num-repeats>
|
26
|
+
<plugin-id type="integer">122731</plugin-id>
|
27
|
+
<sms-sent-at type="datetime" nil="true"></sms-sent-at>
|
28
|
+
<stopped-repeating-at type="datetime" nil="true"></stopped-repeating-at>
|
29
|
+
<time type="datetime">2010-01-21T20:30:00-05:00</time>
|
30
|
+
<trigger-id type="integer">101731</trigger-id>
|
31
|
+
<title> Passenger Global Queue Depth met or exceeded 1 , increasing to 1 for 30 minutes at 08:30PM </title>
|
32
|
+
</alert>
|
33
|
+
</alerts>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<client>
|
3
|
+
<checkin-interval type="integer">3</checkin-interval>
|
4
|
+
<checkup-status>OK</checkup-status>
|
5
|
+
<external-id nil="true"></external-id>
|
6
|
+
<id type="integer">13431</id>
|
7
|
+
<key>FOOBAR</key>
|
8
|
+
<last-checkin type="datetime">2010-01-21T20:35:01-05:00</last-checkin>
|
9
|
+
<last-ping type="datetime">2010-01-21T20:35:00-05:00</last-ping>
|
10
|
+
<name>foobar</name>
|
11
|
+
<num-checkins type="integer">20785</num-checkins>
|
12
|
+
<partner-id type="integer" nil="true"></partner-id>
|
13
|
+
<plan-updated-at type="datetime">2010-01-19T08:59:32-05:00</plan-updated-at>
|
14
|
+
<second-to-last-checkin type="datetime">2010-01-21T20:32:01-05:00</second-to-last-checkin>
|
15
|
+
<second-to-last-ping type="datetime">2010-01-21T20:32:00-05:00</second-to-last-ping>
|
16
|
+
<send-checkup-email type="boolean" nil="true"></send-checkup-email>
|
17
|
+
<send-checkup-sms type="boolean" nil="true"></send-checkup-sms>
|
18
|
+
<take-snapshots type="boolean">false</take-snapshots>
|
19
|
+
<hostname>foobar.com</hostname>
|
20
|
+
<version>3.2.6</version>
|
21
|
+
<active-alerts type="array"/>
|
22
|
+
</client>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<clients type="array">
|
3
|
+
<client>
|
4
|
+
<checkin-interval type="integer">3</checkin-interval>
|
5
|
+
<checkup-status>OK</checkup-status>
|
6
|
+
<external-id nil="true"></external-id>
|
7
|
+
<id type="integer">13431</id>
|
8
|
+
<key>FOOBAR</key>
|
9
|
+
<last-checkin type="datetime">2010-01-21T20:35:01-05:00</last-checkin>
|
10
|
+
<last-ping type="datetime">2010-01-21T20:35:00-05:00</last-ping>
|
11
|
+
<name>foobar</name>
|
12
|
+
<num-checkins type="integer">20785</num-checkins>
|
13
|
+
<partner-id type="integer" nil="true"></partner-id>
|
14
|
+
<plan-updated-at type="datetime">2010-01-19T08:59:32-05:00</plan-updated-at>
|
15
|
+
<second-to-last-checkin type="datetime">2010-01-21T20:32:01-05:00</second-to-last-checkin>
|
16
|
+
<second-to-last-ping type="datetime">2010-01-21T20:32:00-05:00</second-to-last-ping>
|
17
|
+
<send-checkup-email type="boolean" nil="true"></send-checkup-email>
|
18
|
+
<send-checkup-sms type="boolean" nil="true"></send-checkup-sms>
|
19
|
+
<take-snapshots type="boolean">false</take-snapshots>
|
20
|
+
<version>3.2.6</version>
|
21
|
+
<active-alerts type="array"/>
|
22
|
+
</client>
|
23
|
+
</clients>
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<clients type="array">
|
3
|
+
<client>
|
4
|
+
<checkin-interval type="integer">3</checkin-interval>
|
5
|
+
<checkup-status>OK</checkup-status>
|
6
|
+
<external-id nil="true"></external-id>
|
7
|
+
<id type="integer">13431</id>
|
8
|
+
<key>FOOBAR</key>
|
9
|
+
<last-checkin type="datetime">2010-01-21T20:35:01-05:00</last-checkin>
|
10
|
+
<last-ping type="datetime">2010-01-21T20:35:00-05:00</last-ping>
|
11
|
+
<name>foobar</name>
|
12
|
+
<num-checkins type="integer">20785</num-checkins>
|
13
|
+
<partner-id type="integer" nil="true"></partner-id>
|
14
|
+
<plan-updated-at type="datetime">2010-01-19T08:59:32-05:00</plan-updated-at>
|
15
|
+
<second-to-last-checkin type="datetime">2010-01-21T20:32:01-05:00</second-to-last-checkin>
|
16
|
+
<second-to-last-ping type="datetime">2010-01-21T20:32:00-05:00</second-to-last-ping>
|
17
|
+
<send-checkup-email type="boolean" nil="true"></send-checkup-email>
|
18
|
+
<send-checkup-sms type="boolean" nil="true"></send-checkup-sms>
|
19
|
+
<take-snapshots type="boolean">false</take-snapshots>
|
20
|
+
<hostname>foobar.com</hostname>
|
21
|
+
<version>3.2.6</version>
|
22
|
+
<active-alerts type="array"/>
|
23
|
+
</client>
|
24
|
+
<client>
|
25
|
+
<checkin-interval type="integer">3</checkin-interval>
|
26
|
+
<checkup-status>Failure</checkup-status>
|
27
|
+
<external-id nil="true"></external-id>
|
28
|
+
<id type="integer">22751</id>
|
29
|
+
<key>FOO2</key>
|
30
|
+
<last-checkin type="datetime">2010-01-15T07:33:59-05:00</last-checkin>
|
31
|
+
<last-ping type="datetime">2010-01-15T07:33:52-05:00</last-ping>
|
32
|
+
<name>foo2</name>
|
33
|
+
<num-checkins type="integer">4801</num-checkins>
|
34
|
+
<partner-id type="integer" nil="true"></partner-id>
|
35
|
+
<plan-updated-at type="datetime">2010-01-19T08:59:32-05:00</plan-updated-at>
|
36
|
+
<second-to-last-checkin type="datetime">2010-01-05T05:33:14-05:00</second-to-last-checkin>
|
37
|
+
<second-to-last-ping type="datetime">2010-01-05T05:33:03-05:00</second-to-last-ping>
|
38
|
+
<send-checkup-email type="boolean" nil="true"></send-checkup-email>
|
39
|
+
<send-checkup-sms type="boolean" nil="true"></send-checkup-sms>
|
40
|
+
<take-snapshots type="boolean">false</take-snapshots>
|
41
|
+
<hostname>foo2.com</hostname>
|
42
|
+
<version>5.0.3</version>
|
43
|
+
<active-alerts type="array">
|
44
|
+
<alert>
|
45
|
+
<body nil="true"></body>
|
46
|
+
<email-viewed-at type="datetime" nil="true"></email-viewed-at>
|
47
|
+
<id type="integer">34555661</id>
|
48
|
+
<last-repeated-at type="datetime">2010-01-05T06:00:00-05:00</last-repeated-at>
|
49
|
+
<needs-sms type="integer">0</needs-sms>
|
50
|
+
<num-repeats type="integer">2</num-repeats>
|
51
|
+
<plugin-id type="integer">112001</plugin-id>
|
52
|
+
<sms-sent-at type="datetime" nil="true"></sms-sent-at>
|
53
|
+
<time type="datetime">2010-01-05T05:00:00-05:00</time>
|
54
|
+
<trigger-id type="integer">88111</trigger-id>
|
55
|
+
<title> Passenger private total increased 1,133 MB (200%) from 566 MB to 1,699 MB from 04:00AM-05:00AM relative to 03:00AM-04:00AM and is still continuing as of 06:00AM (16 days so far) </title>
|
56
|
+
</alert>
|
57
|
+
</active-alerts>
|
58
|
+
</client>
|
59
|
+
</clients>
|