newrelic_api 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+ require 'jeweler'
12
+ require 'rdiscount'
13
+
14
+ require 'ci/reporter/rake/test_unit'
15
+ TITLE = %Q{Documentation and helper code for the New Relic API}
16
+ RDOC_FILES=['README*', 'CHANGELOG', 'sample*']
17
+ Jeweler::Tasks.new do |gem|
18
+ gem.name = "newrelic_api"
19
+ gem.homepage = "http://www.github.com/newrelic/newrelic_api"
20
+ gem.license = "MIT"
21
+ gem.summary = TITLE
22
+ gem.description = %Q{Use this gem to access New Relic application information via a REST api}
23
+ gem.email = "support@newrelic.com"
24
+ gem.authors = ["New Relic"]
25
+ gem.extra_rdoc_files = FileList[*RDOC_FILES]
26
+ gem.rdoc_options <<
27
+ "--line-numbers" <<
28
+ "--title" << TITLE <<
29
+ "-m" << "README.rdoc"
30
+ end
31
+ #Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rake/testtask'
34
+ Rake::TestTask.new(:test) do |test|
35
+ test.libs << 'lib' << 'test'
36
+ test.pattern = 'test/**/*_test.rb'
37
+ test.verbose = true
38
+ end
39
+
40
+ require 'rcov/rcovtask'
41
+ Rcov::RcovTask.new do |test|
42
+ test.libs << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = true
45
+ end
46
+
47
+ task :default => :test
48
+
49
+ require 'rdoc/task'
50
+ Rake::RDocTask.new do |rdoc|
51
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = TITLE
54
+ rdoc.rdoc_files.include(*RDOC_FILES)
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ rdoc.main = "README.rdoc"
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.2
@@ -0,0 +1,35 @@
1
+ # This mixin defines ActiveRecord style associations (like has_many) for ActiveResource objects.
2
+ # ActiveResource objects using this mixin must define the method 'query_params'.
3
+ module ActiveResourceAssociations #:nodoc:
4
+ class << self
5
+ protected
6
+ def included(base)
7
+ class << base
8
+ # a special ActiveResource implementation of has_many
9
+ def has_many(*associations)
10
+ associations.to_a.each do |association|
11
+ define_method association do |*args|
12
+ val = attributes[association.to_s] # if we've already fetched the relationship in the initial fetch, return it
13
+ return val if val
14
+
15
+ options = args.extract_options!
16
+ type = args.first || :all
17
+
18
+ begin
19
+ # look for the class definition within the current class
20
+ clazz = ( self.class.name + '::' + association.to_s.camelize.singularize).constantize
21
+ rescue
22
+ # look for the class definition in the NRAPI module
23
+ clazz = ( "#{self.class.parent.name}::" + association.to_s.camelize.singularize).constantize
24
+ end
25
+ params = (options[:params] || {}).update(self.query_params)
26
+ options[:params] = params
27
+ clazz.find(type, options)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,231 @@
1
+ require 'active_resource_associations'
2
+
3
+ # = New Relic REST API
4
+ #
5
+ # This is a helper module for working with the New Relic API's XML interface. Requires Rails 2.0 or later to be loaded.
6
+ #
7
+ # Can also be used as a script using script/runner.
8
+ #
9
+ # In this version of the api, authentication is handled using your account API key, available in your Account settings
10
+ # in http://rpm.newrelic.com.
11
+ # Log in, click Account at the top of the page and check the "Make my account data accessible" checkbox. An
12
+ # API key will appear.
13
+ #
14
+ # Refer to the README file for details and examples on the REST API.
15
+ #
16
+ # == Examples
17
+ #
18
+ # # Fetching the list of applications for an account
19
+ # NewRelicApi::Account.find(:first).applications
20
+ #
21
+ # # Fetching the health values for all account applications
22
+ # NewRelicApi::Account.application_health
23
+ #
24
+ # # Fetching the health values for an application
25
+ # NewRelicApi::Account.find(:first).applications.first.threshold_values
26
+ #
27
+ # # Finding an application by name
28
+ # NewRelicApi::Account.find(:first).applications(:params => {:conditions => {:name => 'My App'}})
29
+ #
30
+
31
+ module NewRelicApi
32
+
33
+ class << self
34
+ attr_accessor :api_key, :ssl, :host, :port
35
+
36
+ # Resets the base path of all resources. This should be called when overridding the newrelic.yml settings
37
+ # using the ssl, host or port accessors.
38
+ def reset!
39
+ @classes.each {|klass| klass.reset!} if @classes
40
+ NewRelicApi::Account.site_url
41
+ end
42
+
43
+
44
+ def track_resource(klass) #:nodoc:
45
+ (@classes ||= []) << klass
46
+ end
47
+ end
48
+
49
+ class BaseResource < ActiveResource::Base #:nodoc:
50
+ include ActiveResourceAssociations
51
+
52
+ class << self
53
+ def inherited(klass) #:nodoc:
54
+ NewRelicApi.track_resource(klass)
55
+ end
56
+
57
+ def headers
58
+ raise "api_key required" unless NewRelicApi.api_key
59
+ {'x-api-key' => NewRelicApi.api_key}
60
+ end
61
+
62
+ def site_url
63
+ host = NewRelicApi.host || 'rpm.newrelic.com'
64
+ port = NewRelicApi.port || 80
65
+ "#{port == 443 ? 'https' : 'http'}://#{host}:#{port}"
66
+ end
67
+
68
+ def reset!
69
+ self.site = self.site_url
70
+ end
71
+ end
72
+ self.site = self.site_url
73
+ end
74
+ ACCOUNT_RESOURCE_PATH = '/accounts/:account_id/' #:nodoc:
75
+ ACCOUNT_AGENT_RESOURCE_PATH = ACCOUNT_RESOURCE_PATH + 'agents/:agent_id/' #:nodoc:
76
+ ACCOUNT_APPLICATION_RESOURCE_PATH = ACCOUNT_RESOURCE_PATH + 'applications/:application_id/' #:nodoc:
77
+
78
+ module AccountResource #:nodoc:
79
+ def account_id
80
+ prefix_options[:account_id]
81
+ end
82
+ def account_query_params(extra_params = {})
83
+ {:account_id => account_id}.merge(extra_params)
84
+ end
85
+
86
+ def query_params#:nodoc:
87
+ account_query_params
88
+ end
89
+ end
90
+
91
+ module AgentResource #:nodoc:
92
+ include ActiveResourceAssociations
93
+ end
94
+
95
+ # An application has many:
96
+ # +agents+:: the agent instances associated with this app
97
+ # +threshold_values+:: the health indicators for this application.
98
+ class Application < BaseResource
99
+ include AccountResource
100
+ include AgentResource
101
+
102
+ has_many :agents, :threshold_values
103
+
104
+ self.prefix = ACCOUNT_RESOURCE_PATH
105
+
106
+ def query_params#:nodoc:
107
+ account_query_params(:application_id => id)
108
+ end
109
+
110
+ class Agent < BaseResource
111
+ include AccountResource
112
+ include AgentResource
113
+
114
+ self.prefix = ACCOUNT_APPLICATION_RESOURCE_PATH
115
+
116
+ def query_params#:nodoc:
117
+ super.merge(:application_id => cluster_agent_id)
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ # A threshold value represents a single health indicator for an application such as CPU, memory or response time.
124
+ #
125
+ # ==Fields
126
+ # +name+:: The name of the threshold setting associated with this threshold value.
127
+ # +begin_time+:: Time value indicating start of evaluation period, as a string.
128
+ # +threshold_value+:: A value of 0, 1, 2 or 3 representing gray (not reporting), green, yellow and red
129
+ # +metric_value+:: The metric value associated with this threshold
130
+ class ThresholdValue < BaseResource
131
+ self.prefix = ACCOUNT_APPLICATION_RESOURCE_PATH
132
+
133
+ # attr_reader :name, :begin_time, :metric_value, :threshold_value
134
+
135
+ # Return theshold_value as 0, 1, 2, or 3 representing grey (not reporting)
136
+ # green, yellow, and red, respectively.
137
+ def threshold_value
138
+ super.to_i
139
+ end
140
+
141
+ # Return the actual value of the threshold as a Float
142
+ def metric_value
143
+ super.to_f
144
+ end
145
+ # Returns the color value for this threshold (Gray, Green, Yellow or Red).
146
+ def color_value
147
+ case threshold_value
148
+ when 3 then 'Red'
149
+ when 2 then 'Yellow'
150
+ when 1 then 'Green'
151
+ else 'Gray'
152
+ end
153
+ end
154
+
155
+ def to_s #:nodoc:
156
+ "#{name}: #{color_value} (#{formatted_metric_value})"
157
+ end
158
+ end
159
+
160
+ # An account contains your basic account information.
161
+ #
162
+ # Accounts have many
163
+ # +applications+:: the applications contained within the account
164
+ #
165
+ # Find Accounts
166
+ #
167
+ # NewRelicApi::Account.find(:first) # find account associated with the api key
168
+ # NewRelicApi::Account.find(44) # find individual account by ID
169
+ #
170
+ class Account < BaseResource
171
+ has_many :applications
172
+ has_many :account_views
173
+
174
+ def query_params #:nodoc:
175
+ {:account_id => id}
176
+ end
177
+
178
+ # Returns an account including all of its applications and the threshold values for each application.
179
+ def self.application_health(type = :first)
180
+ find(type, :params => {:include => :application_health})
181
+ end
182
+
183
+ class AccountView < BaseResource
184
+ self.prefix = ACCOUNT_RESOURCE_PATH
185
+
186
+ def query_params(extra_params = {}) #:nodoc:
187
+ {:account_id => account_id}.merge(extra_params)
188
+ end
189
+
190
+ def user
191
+ @attributes['user']
192
+ end
193
+ end
194
+
195
+ class AccountUsage < BaseResource
196
+ end
197
+ end
198
+
199
+ # This model is used to mark production deployments in RPM
200
+ # Only create is supported.
201
+ # == Options
202
+ #
203
+ # Exactly one of the following is required:
204
+ # * <tt>app_name</tt>: The value of app_name in the newrelic.yml file used by the application. This may be different than the label that appears in the RPM UI. You can find the app_name value in RPM by looking at the label settings for your application.
205
+ # * <tt>application_id</tt>: The application id, found in the URL when viewing the application in RPM.
206
+ #
207
+ # Following are optional parameters:
208
+ # * <tt>description</tt>: Text annotation for the deployment &mdash; notes for you
209
+ # * <tt>changelog</tt>: A list of changes for this deployment
210
+ # * <tt>user</tt>: The name of the user/process that triggered this deployment
211
+ #
212
+ # ==Example
213
+ #
214
+ # NewRelicApi::Deployment.create :application_id => 11142007, :description => "Update production", :user => "Big Mike"
215
+ #
216
+ # NewRelicApi::Deployment.create :app_name => "My Application", :description => "Update production", :user => "Big Mike"
217
+ #
218
+ class Deployment < BaseResource
219
+ end
220
+
221
+ class Subscription < BaseResource
222
+ def query_params(extra_params = {}) #:nodoc:
223
+ {:account_id => account_id}.merge(extra_params)
224
+ end
225
+ end
226
+
227
+ class User < BaseResource
228
+ end
229
+
230
+ end
231
+
@@ -0,0 +1,79 @@
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{newrelic_api}
8
+ s.version = "1.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["New Relic"]
12
+ s.date = %q{2011-01-12}
13
+ s.description = %q{Use this gem to access New Relic application information via a REST api}
14
+ s.email = %q{support@newrelic.com}
15
+ s.extra_rdoc_files = [
16
+ "CHANGELOG",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".project",
21
+ "CHANGELOG",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/active_resource_associations.rb",
29
+ "lib/new_relic_api.rb",
30
+ "newrelic_api.gemspec",
31
+ "test/integration/newrelic_api_test.rb",
32
+ "test/test_helper.rb"
33
+ ]
34
+ s.homepage = %q{http://www.github.com/newrelic/newrelic_api}
35
+ s.licenses = ["MIT"]
36
+ s.rdoc_options = ["--line-numbers", "--title", "Documentation and helper code for the New Relic API", "-m", "README.rdoc"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.3.7}
39
+ s.summary = %q{Documentation and helper code for the New Relic API}
40
+ s.test_files = [
41
+ "test/integration/newrelic_api_test.rb",
42
+ "test/test_helper.rb"
43
+ ]
44
+
45
+ if s.respond_to? :specification_version then
46
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
47
+ s.specification_version = 3
48
+
49
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
+ s.add_development_dependency(%q<rails>, ["= 3.0.3"])
51
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
52
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
53
+ s.add_development_dependency(%q<rcov>, [">= 0"])
54
+ s.add_development_dependency(%q<shoulda>, ["~> 2.10.3"])
55
+ s.add_development_dependency(%q<ci_reporter>, ["= 1.6.0"])
56
+ s.add_development_dependency(%q<rdiscount>, [">= 0"])
57
+ s.add_development_dependency(%q<rdoc>, [">= 3.3"])
58
+ else
59
+ s.add_dependency(%q<rails>, ["= 3.0.3"])
60
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
61
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
62
+ s.add_dependency(%q<rcov>, [">= 0"])
63
+ s.add_dependency(%q<shoulda>, ["~> 2.10.3"])
64
+ s.add_dependency(%q<ci_reporter>, ["= 1.6.0"])
65
+ s.add_dependency(%q<rdiscount>, [">= 0"])
66
+ s.add_dependency(%q<rdoc>, [">= 3.3"])
67
+ end
68
+ else
69
+ s.add_dependency(%q<rails>, ["= 3.0.3"])
70
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
71
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
72
+ s.add_dependency(%q<rcov>, [">= 0"])
73
+ s.add_dependency(%q<shoulda>, ["~> 2.10.3"])
74
+ s.add_dependency(%q<ci_reporter>, ["= 1.6.0"])
75
+ s.add_dependency(%q<rdiscount>, [">= 0"])
76
+ s.add_dependency(%q<rdoc>, [">= 3.3"])
77
+ end
78
+ end
79
+
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ require 'zlib'
3
+ require 'new_relic_api'
4
+
5
+ # This test runs against our integration server, which is loaded with fixture data.
6
+ class NewrelicApiTest < ActiveSupport::TestCase
7
+
8
+ # Accounts may be identified either by their ID or by their license key.
9
+ # This is the license key for the "gold" fixture in the New Relic fixture data.
10
+ LICENSE_KEY = '8022da2f6d143de67e056741262a054547b43479'
11
+
12
+ def setup
13
+ NewRelicApi.api_key = LICENSE_KEY
14
+ if ENV['LOCAL']
15
+ # Run your local instance in RAILS_ENV=test to load the fixture data
16
+ NewRelicApi.host = 'localhost'
17
+ NewRelicApi.port = 3000
18
+ else
19
+ NewRelicApi.host = 'integration.newrelic.com'
20
+ end
21
+ NewRelicApi.reset!
22
+ end
23
+
24
+ def test_find_default
25
+ account = NewRelicApi::Account.find(:first)
26
+ assert_equal 'Gold', account.name
27
+ assert_equal LICENSE_KEY, account.license_key
28
+ end
29
+
30
+ def test_account_find
31
+ accounts = NewRelicApi::Account.find(:all)
32
+ assert_equal 1, accounts.length
33
+ assert_equal 'Gold', accounts.first.name
34
+ assert_equal LICENSE_KEY, accounts.first.license_key
35
+ end
36
+
37
+ def test_account_show
38
+ nr_account = NewRelicApi::Account.find(LICENSE_KEY)
39
+ assert_not_nil nr_account
40
+
41
+ account2 = NewRelicApi::Account.find(nr_account.id)
42
+ assert_not_nil account2
43
+ end
44
+
45
+ def test_account_show_applications
46
+ account = NewRelicApi::Account.find(LICENSE_KEY)
47
+ assert_not_nil account
48
+
49
+ apps = account.applications
50
+
51
+ check_applications(apps)
52
+ ui_app = apps.first
53
+
54
+ # Unfortunately, if you ask for a non-existent app, you get a redirect right now.
55
+ assert_raises ActiveResource::Redirection do
56
+ account.applications(9999)
57
+ end
58
+
59
+ ui_app = account.applications(ui_app.id)
60
+ assert_not_nil ui_app
61
+
62
+ threshold_values = ui_app.threshold_values
63
+ assert_equal 9, threshold_values.length
64
+ end
65
+
66
+ def test_application_health
67
+ account = NewRelicApi::Account.application_health
68
+ check_applications(account.applications)
69
+ end
70
+
71
+ def test_application_health_with_no_health
72
+ NewRelicApi.api_key = '9042da2f6d143de67e056741262a051234b434659042'
73
+ account = NewRelicApi::Account.application_health
74
+ assert_equal 1, account.applications.length
75
+ assert_equal 0, account.applications.first.threshold_values.length
76
+ end
77
+
78
+ def test_deployments
79
+ # lookup an app by name
80
+ deployment = NewRelicApi::Deployment.create :appname => 'gold app'
81
+ assert deployment.valid?, deployment.inspect
82
+
83
+ # lookup an app by name
84
+ deployment = NewRelicApi::Deployment.create :application_id => 'gold app'
85
+ assert deployment.valid?, deployment.inspect
86
+
87
+ account = NewRelicApi::Account.find(LICENSE_KEY)
88
+ apps = account.applications
89
+ application_id = apps.first.id
90
+
91
+ # lookup by id won't work with appname
92
+ deployment = NewRelicApi::Deployment.create :appname => application_id
93
+ assert !deployment.valid?, deployment.inspect
94
+
95
+ # lookup by id works with application_id
96
+ deployment = NewRelicApi::Deployment.create :application_id => application_id
97
+ assert deployment.valid?, deployment.inspect
98
+ end
99
+
100
+ def test_restricted_partner_account
101
+ NewRelicApi.api_key = '9042da2f6d143de67e056741262a051234b43475'
102
+ NewRelicApi.reset!
103
+
104
+ account = NewRelicApi::Account.find('9042da2f6d143de67e056741262a051234b43475')
105
+ assert_equal "Clouds 'R' Us", account.name
106
+ end
107
+
108
+ protected
109
+ def check_applications(apps)
110
+ app_names = apps.collect { |app| app.name }
111
+
112
+ assert_equal 1, app_names.length
113
+ assert_equal 'gold app', app_names.first
114
+
115
+ apps.each do |app|
116
+ threshold_values = app.threshold_values
117
+
118
+ assert_equal 9, threshold_values.length
119
+ threshold_values.each do |val|
120
+ assert [0, 1, 2, 3].include?(val.threshold_value), val.threshold_value
121
+ assert ['Gray', 'Green', 'Yellow', 'Red'].include?(val.color_value), val.color_value
122
+
123
+ assert_not_nil val.formatted_metric_value
124
+
125
+ assert_not_nil val.metric_value
126
+ #> 0 || val.name == 'Errors', val.name
127
+ end
128
+ end
129
+ end
130
+
131
+ end