scout 5.4.4.alpha → 5.4.5.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -4,3 +4,6 @@ pkg/*
4
4
  **/.DS_Store
5
5
  .idea
6
6
  working_dir/
7
+ .bundle
8
+ .rvmrc
9
+ Gemfile.lock
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in scout.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem "newrelic_rpm"
8
+ gem "activerecord", "2.2.2"
9
+ gem "mysql"
10
+ end
data/Rakefile CHANGED
@@ -5,3 +5,7 @@ require "bundler/gem_tasks"
5
5
  # rake build # Builds gem into the pkg directory
6
6
  # rake install # Build and install the current version into system gems
7
7
  # rake release # Create, tag, build, and publish the current version to rubygems.org
8
+
9
+ task :test do
10
+ require "test/scout_test"
11
+ end
@@ -15,40 +15,51 @@ module Scout
15
15
  @history = Hash.new
16
16
  @logger = logger
17
17
 
18
- @plugins = []
18
+ @plugin_hashes = []
19
19
 
20
20
  Pusher.app_id = '11495'
21
21
  Pusher.key = 'a95aa7293cd158100246'
22
22
  Pusher.secret = '9c13ccfe325fe3ae682d'
23
23
 
24
- debug "plugin_ids = #{plugin_ids.inspect}"
25
- debug "streaming_key = #{streaming_key}"
26
-
27
24
  streamer_start_time = Time.now
28
25
 
26
+ info("Streamer PID=#{$$} starting")
27
+
29
28
  hostname=Socket.gethostname
30
29
  # load history
31
30
  load_history
32
31
 
33
32
  # get the array of plugins, AKA the plugin plan
34
33
  @plugin_plan = Array(@history["old_plugins"])
35
-
36
- # iterate through the plan and compile each plugin. We only compile plugins once at the beginning of the run
37
- @plugin_plan.each do |plugin|
38
- begin
39
- compile_plugin(plugin) # this is what adds to the @plugin array
40
- rescue Exception
41
- error("Encountered an error: #{$!.message}")
42
- puts $!.backtrace.join('\n')
34
+ info("Starting streamer with key=#{streaming_key} and plugin_ids: #{plugin_ids.inspect}. #{@history_file} includes plugin ids #{@plugin_plan.map{|p|p['id']}.inspect}")
35
+
36
+ # Compile instances of the plugins specified in the passed plugin_ids
37
+ plugin_ids.each_with_index do |plugin_id,i|
38
+ plugin_data=@plugin_plan.find{|plugin| plugin['id'] && plugin['id'].to_i == plugin_id}
39
+ if plugin_data
40
+ begin
41
+ plugin=get_instance_of(plugin_data, plugin_id)
42
+ info("#{i+1}) plugin_id=#{plugin_id} - instance of #{plugin.class.name} created for #{plugin_data['name']}" )
43
+ if plugin.is_a?(Plugin) # safety check that it's an instance of Plugin
44
+ @plugin_hashes.push(:instance=>plugin, :id=>plugin_id, :name=>plugin_data['name'])
45
+ end
46
+ rescue Exception
47
+ error("Encountered an error compiling: #{$!.message}")
48
+ error $!.backtrace.join('\n')
49
+ end
50
+ else
51
+ info("#{i+1}) plugin_id=#{plugin_id} specified in #{plugin_ids.inspect} but not found in #{@history_file}")
43
52
  end
44
53
  end
45
54
 
55
+ info "Finished compilation. #{@plugin_plan.size} plugins; #{@plugin_hashes.size} instances instantiated"
56
+
46
57
  # main loop. Continue running until global $continue_streaming is set to false OR we've been running for MAX DURATION
58
+ iteration=1 # use this to log the data at a couple points
47
59
  while(streamer_start_time+MAX_DURATION > Time.now && $continue_streaming) do
48
60
  plugins=[]
49
- @plugins.each_with_index do |plugin,i|
50
- # ignore plugins whose ids are not in the plugin_ids array -- this also ignores local plugins
51
- next if !(@plugin_plan[i]['id'] && plugin_ids.include?(@plugin_plan[i]['id'].to_i))
61
+ @plugin_hashes.each_with_index do |plugin_hash,i|
62
+ plugin=plugin_hash[:instance]
52
63
  start_time=Time.now
53
64
  plugin.reset!
54
65
  plugin.run
@@ -56,8 +67,8 @@ module Scout
56
67
 
57
68
  plugins << {:duration=>duration,
58
69
  :fields=>plugin.reports.inject{|memo,hash|memo.merge(hash)},
59
- :name=>@plugin_plan[i]["name"],
60
- :id=>@plugin_plan[i]["id"]}
70
+ :name=>plugin_hash[:name],
71
+ :id=>plugin_hash[:id]}
61
72
  end
62
73
 
63
74
  bundle={:hostname=>hostname,
@@ -72,6 +83,11 @@ module Scout
72
83
  error "Error pushing data: #{e.message}"
73
84
  end
74
85
 
86
+ if iteration == 2 || iteration == 100
87
+ info "Run #{iteration} data dump:"
88
+ info bundle.to_json
89
+ end
90
+
75
91
  if false
76
92
  # debugging
77
93
  File.open(File.join(File.dirname(@history_file),"debug.txt"),"w") do |f|
@@ -81,27 +97,18 @@ module Scout
81
97
  end
82
98
 
83
99
  sleep(SLEEP)
100
+ iteration+=1
84
101
  end
102
+
103
+ info("Streamer PID=#{$$} ending.")
85
104
  end
86
105
 
87
106
 
88
107
  private
89
108
 
90
- #def post_bundle(bundle)
91
- # post( urlify(:stream),
92
- # "Unable to stream to server.",
93
- # bundle.to_json,
94
- # "Content-Type" => "application/json")
95
- #rescue Exception
96
- # error "Unable to stream to server."
97
- # debug $!.class.to_s
98
- # debug $!.message
99
- # debug $!.backtrace.join("\n")
100
- #end
101
-
102
- # sets up the @plugins array
103
- def compile_plugin(plugin)
104
- plugin_id = plugin['id']
109
+ # plugin is a hash of plugin data from the history file (id, name, code, etc).
110
+ # This plugin returns an instantiated instance of the plugin
111
+ def get_instance_of(plugin, plugin_id)
105
112
 
106
113
  # take care of plugin overrides
107
114
  local_path = File.join(File.dirname(@history_file), "#{plugin_id}.rb")
@@ -111,27 +118,30 @@ module Scout
111
118
  code_to_run=plugin['code'] || ""
112
119
  end
113
120
 
114
- id_and_name = "#{plugin['id']}-#{plugin['name']}".sub(/\A-/, "")
121
+ id_and_name = "#{plugin_id}-#{plugin['name']}".sub(/\A-/, "")
115
122
  last_run = @history["last_runs"][id_and_name] ||
116
123
  @history["last_runs"][plugin['name']]
117
124
  memory = @history["memory"][id_and_name] ||
118
125
  @history["memory"][plugin['name']]
119
126
  options=(plugin['options'] || Hash.new)
120
127
  options.merge!(:tuner_days=>"")
128
+
121
129
  code_class=Plugin.extract_code_class(code_to_run)
122
- begin
130
+
131
+ # eval the plugin code if it's not already defined
132
+ if !Plugin.const_defined?(code_class)
123
133
  eval(code_to_run, TOPLEVEL_BINDING, plugin['path'] || plugin['name'] )
124
- klass=Plugin.const_get(code_class)
125
- info "Added a #{klass.name} plugin, id = #{plugin_id}"
126
- @plugins << klass.load(last_run, (memory || Hash.new), options)
134
+ end
127
135
 
128
- # turn certain methods into null-ops, so summaries aren't generated. Note that this is ad-hoc, and not future-proof.
129
- if klass.name=="RailsRequests"; def klass.analyze;end;end
130
- if klass.name=="ApacheAnalyzer"; def klass.generate_log_analysis;end;end
136
+ # now that we know the class is defined, reference its class
137
+ klass=Scout::Plugin.const_get(code_class)
131
138
 
132
- rescue Exception
133
- error "Plugin would not compile: #{$!.message}"
134
- end
139
+ # turn certain methods into null-ops, so summaries aren't generated. Note that this is ad-hoc, and not future-proof.
140
+ if klass.name=="RailsRequests"; def klass.analyze;end;end
141
+ if klass.name=="ApacheAnalyzer"; def klass.generate_log_analysis;end;end
142
+
143
+ # finally, return an instance of the plugin
144
+ klass.load(last_run, (memory || Hash.new), options)
135
145
  end
136
146
 
137
147
 
@@ -156,7 +166,5 @@ module Scout
156
166
  end
157
167
  end
158
168
 
159
- def growl(message)`growlnotify -m '#{message.gsub("'","\'")}'`;end
160
-
161
169
  end
162
170
  end
@@ -3,12 +3,12 @@ module Scout
3
3
 
4
4
  # args are: server, key, history, plugin_ids, streaming_key, log
5
5
  def start(args)
6
- puts "StreamerControl#start PID=#{pid}"
6
+ #puts "StreamerControl#start PID=#{pid}"
7
7
  server,key,history,plugin_ids,streaming_key,log = args
8
- $continue_streaming = true #
8
+ $continue_streaming = true #needed for streamer to loop
9
9
 
10
10
  @scout = Scout::Streamer.new(server, key, history, plugin_ids, streaming_key, log)
11
- puts "StreamerControl - done. Removing pid_file at #{pid_file} containing PID=#{pid}"
11
+ # puts "StreamerControl - done. Removing pid_file at #{pid_file} containing PID=#{pid}"
12
12
  File.unlink(pid_file) if File.exists?(pid_file) # a better way of doing this?
13
13
  end
14
14
 
data/lib/scout/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Scout
2
- VERSION = "5.4.4.alpha"
2
+ VERSION = "5.4.5.alpha"
3
3
  end
data/test/scout_test.rb CHANGED
@@ -5,6 +5,7 @@
5
5
  #
6
6
  $VERBOSE=nil
7
7
  $LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
8
+ $LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/..' )
8
9
  require 'test/unit'
9
10
  require 'lib/scout'
10
11
  require "pty"
@@ -392,66 +393,58 @@ mybar=100
392
393
  File.open(local_path,"w"){|f|f.write(code)}
393
394
 
394
395
  scout(@client.key)
395
-
396
396
  assert_equal plugin_count+1, @client.reload.plugins.count, "there should be one additional plugin records -- created from the local plugin"
397
-
398
397
  File.delete(local_path)
399
398
  end
400
399
 
400
+ # Streamer tests
401
401
 
402
+ # includes two plugins of the same class
402
403
  def test_streamer_plugin_compilation
403
- # redefine the trigger! method, so the streamer doesn't loop indefinitely. We can't just mock it, because
404
- # we need to set the $continue_streaming=false
405
- Pusher::Channel.module_eval do
406
- alias orig_trigger! trigger!
407
- def trigger!(event_name, data, socket=nil)
408
- $streamer_data = data
409
- $continue_streaming=false
404
+ mock_pusher do
405
+ plugins=[]
406
+ plugins << create_plugin(@client, "AclPlugin_1", PLUGIN_FIXTURES[:acl][:code], PLUGIN_FIXTURES[:acl][:sig])
407
+ plugins << create_plugin(@client, "XYZ Plugin", PLUGIN_FIXTURES[:xyz][:code], PLUGIN_FIXTURES[:xyz][:sig])
408
+ plugins << create_plugin(@client, "AclPlugin_2", PLUGIN_FIXTURES[:acl][:code], PLUGIN_FIXTURES[:acl][:sig])
409
+
410
+ scout(@client.key) # to write the initial history file. Sinatra MUST be running
411
+ $continue_streaming = true # so the streamer will run once
412
+ streamer=Scout::Streamer.new("http://none", "bogus_client_key", PATH_TO_DATA_FILE, [@client.plugins.first.id]+plugins.map(&:id), "bogus_streaming_key",nil) # for debugging, make last arg Logger.new(STDOUT)
413
+ res = $streamer_data # $streamer_data via the mock_streamer call
414
+
415
+ assert res.is_a?(Hash)
416
+ assert res[:plugins].is_a?(Array)
417
+ assert_equal 4, res[:plugins].size
418
+ assert_equal 2, res[:plugins][0][:fields][:load]
419
+ assert_equal 1, res[:plugins][1][:fields][:value]
420
+ assert_equal 2, res[:plugins][2][:fields][:value]
421
+ assert_equal 1, res[:plugins][3][:fields][:value]
422
+ end # end of mock_pusher
423
+ end
424
+
425
+ def test_streamer_with_local_plugin
426
+ local_path=File.join(AGENT_DIR,"my_local_plugin.rb")
427
+ code=<<-EOC
428
+ class LocalPluginTest < Scout::Plugin
429
+ def build_report; report(:answer=>42);end
410
430
  end
411
- end
412
- plugins=[]
413
- acl_code="class AclPlugin < Scout::Plugin;def build_report; report(:value=>1);end;end"
414
- acl_sig=<<EOS
415
- QT/IYlR+/3h0YwBAHJeFz4HRFlisocVGorafNYJSYJC5RaUKqxu3dM+bOU4P
416
- mQ5SmAt1mtXD5BJy2MeHam7Y8HAiWJbDBB318feZrC6xI2amu1b1/YMUyY8y
417
- fMXS9z8J+ABsFIyV26av1KLxU1EHxi9iKxPwMg0HKJhTBStX4uIyncr/+ZSS
418
- QKywEwPIPihFFyh9B2Z5WVSHtGcZG9CXDa20hrbQoNutOTniTkr00evBItYL
419
- FN4L0F0ApIjTTkZW2vjzNR59j8HfZ7zrPfy33VhJkyAS0o9nQt5v0J5wKHj1
420
- c3egj/Ffn/zSWZ1cTf3VSpfrGKUAlyB9KphZeYv2Og==
421
- EOS
422
- plugins << create_plugin(@client, "AclPlugin_1", acl_code, acl_sig)
423
-
424
- code="class XYZPlugin < Scout::Plugin;def build_report; report(:value=>2);end;end"
425
- sig=<<EOS
426
- 6cNcDCM2GWcoT1Iqri+XFPgAiMxQaf0b8kOi4KKafNVD94cPkcy6OknNeQUM
427
- v6GYcfGCAsiZvnjl/2wsqjvrAl/zyuSW/s5YLsjxca1LEvhkyxbpnDGuj32k
428
- 3IuWKQ6JuEbmPXPP1aFsosOm7dbTCrjEn1fDQWAzmfCwznHV3MiqzvPD2D9g
429
- 7gtxXcblNP6hm7A6AlBzP0hwYORR//gpLLGtmT5ewltHUj9aSUY0GQle3lvH
430
- /uzBDoV1x6mEYR2jPO5QQxL3BvTBvpC06ec8M/ZWbO9IwA7/DOs+vYfngxlp
431
- jbtpAK9QCaAalKy/Z29os/7aViHy9z9IVCpC/z3MDA==
432
- EOS
433
- plugins << create_plugin(@client, "XYZ Plugin", code, sig)
434
-
435
- plugins << create_plugin(@client, "AclPlugin_2", acl_code, acl_sig)
436
-
437
- scout(@client.key) # to write the initial history file. Sinatra MUST be running
438
- $continue_streaming = true # so the streamer will run once
439
- streamer=Scout::Streamer.new("http://none", "bogus_client_key", PATH_TO_DATA_FILE, [@client.plugins.first.id]+plugins.map(&:id), "bogus_streaming_key",nil) # for debugging, make last arg Logger.new(STDOUT)
440
- res = $streamer_data # $streamer_data is set in the Channel.trigger! method we temporarily defined above
431
+ EOC
432
+ File.open(local_path,"w"){|f|f.write(code)}
433
+ scout(@client.key)
441
434
 
442
- assert res.is_a?(Hash)
443
- assert res[:plugins].is_a?(Array)
444
- assert_equal 4, res[:plugins].size
445
- assert_equal 2, res[:plugins][0][:fields][:load]
446
- assert_equal 1, res[:plugins][1][:fields][:value]
447
- assert_equal 2, res[:plugins][2][:fields][:value]
448
- assert_equal 1, res[:plugins][3][:fields][:value]
435
+ mock_pusher do
436
+ $continue_streaming = true # so the streamer will run once
437
+ streamer=Scout::Streamer.new("http://none", "bogus_client_key", PATH_TO_DATA_FILE, [@client.plugins.first.id], "bogus_streaming_key",nil) # for debugging, make last arg Logger.new(STDOUT)
438
+ res = $streamer_data # $streamer_data via the mock_streamer call
449
439
 
450
- Pusher::Channel.module_eval do
451
- alias trigger! orig_trigger!
452
- end
440
+ assert res.is_a?(Hash)
441
+ assert res[:plugins].is_a?(Array)
442
+ assert_equal 1, res[:plugins].size
443
+ assert_equal 2, res[:plugins][0][:fields][:load]
444
+ end # end of mock_pusher
453
445
  end
454
446
 
447
+
455
448
  # test streamer starting and stopping
456
449
  def test_streamer_process_management
457
450
  streamer_pid_file = File.join(AGENT_DIR, "scout_streamer.pid")
@@ -460,13 +453,14 @@ EOS
460
453
 
461
454
  assert !File.exist?(streamer_pid_file)
462
455
 
463
- assert @client.update_attribute(:streamer_command, "start,abc,1,3")
456
+ assert @client.update_attribute(:streamer_command, "start,A0000000000123,1,3")
464
457
  scout(@client.key)
465
458
  assert File.exist?(streamer_pid_file)
466
459
  process_id = File.read(streamer_pid_file).to_i
467
460
  assert process_running?(process_id)
468
461
  assert_nil @client.reload.streamer_command
469
462
 
463
+ sleep 2
470
464
  assert @client.update_attribute(:streamer_command, "stop")
471
465
  scout(@client.key)
472
466
  assert !File.exist?(streamer_pid_file)
@@ -578,7 +572,7 @@ EOS
578
572
  end
579
573
  end
580
574
 
581
- # see scout's rake plugin:sign task to create the signatre
575
+ # see scout's rake plugin:sign task to create the signature
582
576
  def create_plugin(client,name, code, signature)
583
577
  p=client.plugins.create(:name=>name)
584
578
  PluginMeta.create(:plugin=>p)
@@ -591,6 +585,49 @@ EOS
591
585
  p
592
586
  end
593
587
 
588
+ # this with a block to mock the pusher call. You can access the streamer data through the global $streamer_data
589
+ # Must be called with a code block
590
+ def mock_pusher
591
+ # redefine the trigger! method, so the streamer doesn't loop indefinitely. We can't just mock it, because
592
+ # we need to set the $continue_streaming=false
593
+ Pusher::Channel.module_eval do
594
+ alias orig_trigger! trigger!
595
+ def trigger!(event_name, data, socket=nil)
596
+ $streamer_data = data
597
+ $continue_streaming=false
598
+ end
599
+ end
600
+ yield # must be called with a block
601
+ Pusher::Channel.module_eval do
602
+ alias trigger! orig_trigger!
603
+ end
604
+ end
605
+
606
+
607
+ # Use these to create plugins as needed
608
+ PLUGIN_FIXTURES={
609
+ :acl=>{:code=>"class AclPlugin < Scout::Plugin;def build_report; report(:value=>1);end;end",
610
+ :sig=><<EOS
611
+ QT/IYlR+/3h0YwBAHJeFz4HRFlisocVGorafNYJSYJC5RaUKqxu3dM+bOU4P
612
+ mQ5SmAt1mtXD5BJy2MeHam7Y8HAiWJbDBB318feZrC6xI2amu1b1/YMUyY8y
613
+ fMXS9z8J+ABsFIyV26av1KLxU1EHxi9iKxPwMg0HKJhTBStX4uIyncr/+ZSS
614
+ QKywEwPIPihFFyh9B2Z5WVSHtGcZG9CXDa20hrbQoNutOTniTkr00evBItYL
615
+ FN4L0F0ApIjTTkZW2vjzNR59j8HfZ7zrPfy33VhJkyAS0o9nQt5v0J5wKHj1
616
+ c3egj/Ffn/zSWZ1cTf3VSpfrGKUAlyB9KphZeYv2Og==
617
+ EOS
618
+ },
619
+ :xyz=>{:code=>"class XYZPlugin < Scout::Plugin;def build_report; report(:value=>2);end;end",
620
+ :sig=><<EOS
621
+ 6cNcDCM2GWcoT1Iqri+XFPgAiMxQaf0b8kOi4KKafNVD94cPkcy6OknNeQUM
622
+ v6GYcfGCAsiZvnjl/2wsqjvrAl/zyuSW/s5YLsjxca1LEvhkyxbpnDGuj32k
623
+ 3IuWKQ6JuEbmPXPP1aFsosOm7dbTCrjEn1fDQWAzmfCwznHV3MiqzvPD2D9g
624
+ 7gtxXcblNP6hm7A6AlBzP0hwYORR//gpLLGtmT5ewltHUj9aSUY0GQle3lvH
625
+ /uzBDoV1x6mEYR2jPO5QQxL3BvTBvpC06ec8M/ZWbO9IwA7/DOs+vYfngxlp
626
+ jbtpAK9QCaAalKy/Z29os/7aViHy9z9IVCpC/z3MDA==
627
+ EOS
628
+ }
629
+ } # end of PLUGIN_FIXTURES
630
+
594
631
  end
595
632
 
596
633
  # Connect to AR before running
metadata CHANGED
@@ -1,39 +1,40 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: scout
3
- version: !ruby/object:Gem::Version
4
- version: 5.4.4.alpha
5
- prerelease: 6
3
+ version: !ruby/object:Gem::Version
4
+ version: 5.4.5.alpha
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Andre Lewis
9
8
  - Derek Haynes
10
9
  - James Edward Gray II
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2011-12-09 00:00:00.000000000 Z
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
13
+
14
+ date: 2011-12-13 00:00:00 -08:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
17
18
  name: elif
18
- requirement: &70156034409200 !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
21
- - - ! '>='
22
- - !ruby/object:Gem::Version
23
- version: '0'
24
19
  type: :runtime
25
- prerelease: false
26
- version_requirements: *70156034409200
27
- description: ! 'Scout makes monitoring and reporting on your web applications as flexible
28
- and simple as possible.
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: "0"
26
+ version:
27
+ description: |
28
+ Scout makes monitoring and reporting on your web applications as flexible and simple as possible.
29
29
 
30
- '
31
30
  email: support@scoutapp.com
32
- executables:
31
+ executables:
33
32
  - scout
34
33
  extensions: []
34
+
35
35
  extra_rdoc_files: []
36
- files:
36
+
37
+ files:
37
38
  - .gitignore
38
39
  - CHANGELOG
39
40
  - Gemfile
@@ -219,31 +220,34 @@ files:
219
220
  - vendor/signature/spec/signature_spec.rb
220
221
  - vendor/signature/spec/spec_helper.rb
221
222
  - vendor/util/lib/core_extensions.rb
223
+ has_rdoc: true
222
224
  homepage: http://scoutapp.com
223
225
  licenses: []
226
+
224
227
  post_install_message:
225
228
  rdoc_options: []
226
- require_paths:
229
+
230
+ require_paths:
227
231
  - lib
228
- required_ruby_version: !ruby/object:Gem::Requirement
229
- none: false
230
- requirements:
231
- - - ! '>='
232
- - !ruby/object:Gem::Version
233
- version: '0'
234
- required_rubygems_version: !ruby/object:Gem::Requirement
235
- none: false
236
- requirements:
237
- - - ! '>'
238
- - !ruby/object:Gem::Version
232
+ required_ruby_version: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: "0"
237
+ version:
238
+ required_rubygems_version: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - ">"
241
+ - !ruby/object:Gem::Version
239
242
  version: 1.3.1
243
+ version:
240
244
  requirements: []
245
+
241
246
  rubyforge_project: scout
242
- rubygems_version: 1.8.10
247
+ rubygems_version: 1.3.5
243
248
  signing_key:
244
249
  specification_version: 3
245
- summary: Web-based monitoring, reporting, and alerting for your servers, clusters,
246
- and applications.
247
- test_files:
250
+ summary: Web-based monitoring, reporting, and alerting for your servers, clusters, and applications.
251
+ test_files:
248
252
  - test/plugins/disk_usage.rb
249
253
  - test/scout_test.rb