scout_api 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,3 @@
1
+ class Scout::Person < Hashie::Mash
2
+
3
+ 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
@@ -0,0 +1,11 @@
1
+ class Scout::Trigger < Hashie::Mash
2
+ attr_writer :server, :plugin
3
+
4
+ def server
5
+ @server ||= Scout::Server.first(id)
6
+ end
7
+
8
+ def plugin
9
+ @plugin ||= server.plugin(plugin_id)
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Scout
2
+ VERSION = '0.9.0'
3
+ 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
@@ -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
+
@@ -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>
@@ -0,0 +1,5 @@
1
+ <data>
2
+ <value>31.10</value>
3
+ <label>Cpu last minute</label>
4
+ <units></units>
5
+ </data>