trashed 2.0.5 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
- metadata.gz: abfbb3ba8576bac0d578d9821479635dda52e57b
4
- data.tar.gz: b5439fd5e664b3f439860b6fd6dd548248d1594c
3
+ metadata.gz: 8a76c1137b987b5c2e00ce832d90a32ed952d72b
4
+ data.tar.gz: 0530e17d53650ef1da7787f8f658b2eb93ecbaf0
5
5
  SHA512:
6
- metadata.gz: 7748860b9937a18abcffb575cb51a2cfb0ed352b9d1ffb824dceafa67a47c22afbfd4bfd1d4e89974f20e5137996cd4ae65cc7285bc3e9c7eef117fb92a8cbf9
7
- data.tar.gz: 6af120ce83a1048254fc0df2d41f1cef0c32bfd99c9ea81eb5bd1ef063562c447f32bf28e137e23d92f8e712f11536bc4f85b5d49c7d7f9451c86edd2e306349
6
+ metadata.gz: 1e39ad89bdd197f0fffaf9367778d32c48fe2bfa55e70fc11c648837979eadccc94014d5bc0a237ed97b68bc7901460bad8d166caf915a84880638d47b28e1a3
7
+ data.tar.gz: b1d891fe71584f900ba80adcd3d0a4a73472b1b3a46173341a10c678fa546eb21c314ed4581c8574000ffb621cfff5c096181f5594a12d9ac9436b4799eb5ed1
@@ -0,0 +1,11 @@
1
+ module Trashed
2
+ module Instruments
3
+ class ObjectSpaceCounter
4
+ def measure(state, timings, gauges)
5
+ ObjectSpace.count_objects.each do |type, count|
6
+ gauges << [ :"Objects.#{type}", count ]
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Trashed
2
+ module Instruments
3
+ class Ruby18GC
4
+ def initialize
5
+ GC.enable_stats
6
+ end
7
+
8
+ def start(state)
9
+ state.update \
10
+ :'Objects.total' => ObjectSpace.allocated_objects,
11
+ :'GC.count' => GC.collections,
12
+ :'GC.elapsed' => GC.time,
13
+ :'GC.memory' => GC.allocated_size
14
+ end
15
+
16
+ def measure(state, timings, gauges)
17
+ timings.update \
18
+ :'Objects.total' => ObjectSpace.allocated_objects - state[:'Objects.total'],
19
+ :'GC.count' => GC.collections - state[:'GC.count'],
20
+ :'GC.elapsed' => GC.time - state[:'GC.elapsed'],
21
+ :'GC.memory' => GC.allocated_size - state[:'GC.memory']
22
+
23
+ gauges << [ :'Objects.live', ObjectSpace.live_objects ]
24
+ gauges << [ :'GC.growth', GC.growth ]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ module Trashed
2
+ module Instruments
3
+ class Ruby19GC
4
+ def start(state)
5
+ gc = GC.stat
6
+ state[:'GC.count'] = gc[:count]
7
+ end
8
+
9
+ def measure(state, timings, gauges)
10
+ gc = GC.stat
11
+ timings[:'GC.count'] = gc[:count] - state.delete(:'GC.count')
12
+ gauges.concat gc.map { |k, v| [ :"GC.#{k}", v ] }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module Trashed
2
+ module Instruments
3
+ class Ruby20GC
4
+ def start(state)
5
+ gc = GC.stat
6
+ state.update \
7
+ :'GC.count' => gc[:count],
8
+ :'GC.allocated_objects' => gc[:total_allocated_object],
9
+ :'GC.freed_objects' => gc[:total_freed_object]
10
+ end
11
+
12
+ def measure(state, timings, gauges)
13
+ gc = GC.stat
14
+
15
+ timings.update \
16
+ :'GC.count' => gc[:count] - state.delete(:'GC.count'),
17
+ :'GC.allocated_objects' => gc[:total_allocated_object] - state.delete(:'GC.allocated_objects'),
18
+ :'GC.freed_objects' => gc[:total_freed_object] - state.delete(:'GC.freed_objects')
19
+
20
+ gauges.concat gc.map { |k, v| [ :"GC.#{k}", v ] }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module Trashed
2
+ module Instruments
3
+ class Ruby21GC
4
+ def start(state)
5
+ gc = GC.stat
6
+ state.update \
7
+ :'GC.count' => gc[:count],
8
+ :'GC.major_count' => gc[:major_gc_count],
9
+ :'GC.minor_count' => gc[:minor_gc_count],
10
+ :'GC.allocated_objects' => gc[:total_allocated_object],
11
+ :'GC.freed_objects' => gc[:total_freed_object]
12
+ end
13
+
14
+ def measure(state, timings, gauges)
15
+ gc = GC.stat
16
+
17
+ timings.update \
18
+ :'GC.count' => gc[:count] - state.delete(:'GC.count'),
19
+ :'GC.major_count' => gc[:major_gc_count] - state.delete(:'GC.major_count'),
20
+ :'GC.minor_count' => gc[:minor_gc_count] - state.delete(:'GC.minor_count'),
21
+ :'GC.allocated_objects' => gc[:total_allocated_object] - state.delete(:'GC.allocated_objects'),
22
+ :'GC.freed_objects' => gc[:total_freed_object] - state.delete(:'GC.freed_objects')
23
+
24
+ gauges.concat gc.map { |k, v| [ :"GC.#{k}", v ] }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ module Trashed
2
+ module Instruments
3
+ class RubyGCProfiler
4
+ def initialize
5
+ @has_raw_data = GC::Profiler.respond_to?(:raw_data)
6
+ end
7
+
8
+ def start(state)
9
+ GC::Profiler.enable
10
+ GC::Profiler.clear
11
+ end
12
+
13
+ def measure(state, timings, gauges)
14
+ timings[:'GC.time'] = GC::Profiler.total_time
15
+
16
+ if @has_raw_data
17
+ GC::Profiler.raw_data.each do |data|
18
+ gauges.concat data.map { |k, v| [ :"GC.Profiler.#{k}", v ] }
19
+ end
20
+ end
21
+
22
+ GC::Profiler.disable
23
+ GC::Profiler.clear
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ module Trashed
2
+ module Instruments
3
+ class Stopwatch
4
+ def initialize(timepiece = Timepiece)
5
+ @timepiece = timepiece
6
+ @has_cpu_time = timepiece.respond_to?(:cpu)
7
+ end
8
+
9
+ def start(state)
10
+ state[:'Time.wall'] = @timepiece.wall
11
+ state[:'Time.cpu'] = @timepiece.cpu if @has_cpu_time
12
+ end
13
+
14
+ def measure(state, timings, gauges)
15
+ wall_elapsed = @timepiece.wall - state.delete(:'Time.wall')
16
+ timings[:'Time.wall'] = wall_elapsed
17
+ if @has_cpu_time
18
+ cpu_elapsed = @timepiece.cpu - state.delete(:'Time.cpu')
19
+ timings[:'Time.cpu'] = cpu_elapsed
20
+ timings[:'Time.idle'] = wall_elapsed - cpu_elapsed
21
+ end
22
+ end
23
+ end
24
+
25
+ module Timepiece
26
+ def self.wall
27
+ (::Time.now.to_f * 1000).to_i
28
+ end
29
+
30
+ # Ruby 2.1+
31
+ if Process.respond_to?(:clock_gettime)
32
+ def self.cpu
33
+ Process.clock_gettime Process::CLOCK_PROCESS_CPUTIME_ID, :millisecond
34
+ end
35
+
36
+ # ruby-prof installed
37
+ elsif defined? RubyProf::Measure::ProcessTime
38
+ def self.cpu
39
+ (RubyProf::Measure::Process.measure * 1000).to_i
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
data/lib/trashed/meter.rb CHANGED
@@ -1,40 +1,58 @@
1
1
  module Trashed
2
2
  class Meter
3
- attr_reader :counters, :gauges
3
+ attr_reader :instruments
4
4
 
5
- def initialize(&block)
6
- @counters, @gauges = {}, {}
7
- instance_eval(&block) if block_given?
5
+ def initialize
6
+ @instruments = []
7
+ @needs_start = []
8
8
  end
9
9
 
10
- def counts(name, &block) @counters[name] = block end
11
- def count; read @counters end
10
+ # Counters increase, so we measure before/after differences.
11
+ # Time elapsed, memory growth, objects allocated, etc.
12
+ def counts(name, &block)
13
+ instrument ChangeInstrument.new(name, block)
14
+ end
15
+
16
+ # Gauges measure point-in-time values.
17
+ # Heap size, live objects, GC count, etc.
18
+ def gauges(name, &block)
19
+ instrument GaugeInstrument.new(name, block)
20
+ end
12
21
 
13
- def gauges(name, &block) @gauges[name] = block end
14
- def gauge; read @gauges end
22
+ def instrument(instrument)
23
+ @instruments << instrument
24
+ @needs_start << instrument if instrument.respond_to?(:start)
25
+ end
15
26
 
16
- def instrument
17
- before = count
18
- yield
19
- delta before, count
27
+ def instrument!(state, timings, gauges)
28
+ @needs_start.each { |i| i.start state }
29
+ yield.tap do
30
+ @instruments.reverse_each { |i| i.measure state, timings, gauges }
31
+ end
20
32
  end
21
33
 
22
- private
34
+ class ChangeInstrument
35
+ def initialize(name, probe)
36
+ @name, @probe = name, probe
37
+ end
23
38
 
24
- def delta(before, after)
25
- delta = {}
26
- after.each { |k, v| delta[k] = v - before[k] }
27
- delta
39
+ def start(state)
40
+ state[@name] = @probe.call
41
+ end
42
+
43
+ def measure(state, timings, gauges)
44
+ timings[@name] = @probe.call - state[@name]
45
+ end
28
46
  end
29
47
 
30
- def read(measures)
31
- data = {}
32
- measures.each do |name, measure|
33
- measure.call.each do |key, value|
34
- data["#{name}.#{key}"] = value
35
- end
48
+ class GaugeInstrument
49
+ def initialize(name, probe)
50
+ @name, @probe = name, probe
51
+ end
52
+
53
+ def measure(state, timings, gauges)
54
+ gauges << [ @name, @probe.call ]
36
55
  end
37
- data
38
56
  end
39
57
  end
40
58
  end
data/lib/trashed/rack.rb CHANGED
@@ -1,64 +1,37 @@
1
- module Trashed
2
- module Rack
3
- class MeasureResourceUsage
4
- def initialize(app, options = {})
5
- @app = app
6
- @debug, @logger, @statsd, @sample_rate = options.values_at(:debug, :logger, :statsd, :sample_rate)
7
- @sample_rate ||= 0.1
8
-
9
- @request_namespaces, @sampler_namespaces = options.values_at(:statsd_request_namespaces, :statsd_sampler_namespaces)
10
- end
11
-
12
- def call(env)
13
- response = nil
14
- instrument(env) { response = @app.call(env) }
15
- response
16
- end
17
-
18
- def instrument(env, &block)
19
- change = ResourceUsage.instrument(&block)
20
- usage = ResourceUsage.gauge
21
- record env, change, usage
22
- end
23
-
24
- def record(env, change, usage)
25
- record_env env, change, usage
26
- record_logger env, change, usage if @logger
27
- record_statsd env, change, usage if @statsd
28
- end
1
+ require 'trashed/resource_usage'
29
2
 
30
- def record_env(env, change, usage)
31
- env['trashed.change'] = change
32
- env['trashed.usage'] = usage
33
- end
3
+ module Trashed
4
+ class Rack
5
+ STATE, TIMINGS, GAUGES = 'trashed.state', 'trashed.timings', 'trashed.gauges'
34
6
 
35
- def record_logger(env, change, usage)
36
- @logger.info "Rack handled in %dms (GC runs: %d)" % change.values_at('Time.wall', 'GC.count')
37
- record_debug_logger env, change, usage if @debug
38
- end
7
+ def initialize(app, reporter, options = {})
8
+ @reporter = reporter
9
+ @meters = Array(options.fetch(:meters, [ResourceUsage]))
10
+ @logger, @statsd, @sample_rate = options.values_at(:logger, :statsd_instance, :sample_rate)
11
+ @sample_rate ||= 1.0
39
12
 
40
- def record_debug_logger(env, change, usage)
41
- @logger.debug "Changes: #{change.to_yaml}"
42
- @logger.debug "Usage: #{usage.to_yaml}"
43
- end
13
+ @request_namespaces = options[:statsd_request_namespaces]
14
+ @sampler_namespaces = options[:statsd_sampler_namespaces]
44
15
 
45
- def record_statsd(env, change, usage)
46
- record_statsd_timing change, :'Rack.Request.All'
47
- record_statsd_timing usage, :'Rack.Server.All'
16
+ # Wrap the app up in the meters.
17
+ @app = build_instrumented_app(app, @meters)
18
+ end
48
19
 
49
- Array(@request_namespaces.call(env)).each do |namespace|
50
- record_statsd_timing change, "Rack.Request.#{namespace}"
51
- end if @request_namespaces
20
+ def call(env)
21
+ env[STATE] = {}
22
+ env[TIMINGS] = {}
23
+ env[GAUGES] = []
52
24
 
53
- Array(@sampler_namespaces.call(env)).each do |namespace|
54
- record_statsd_timing usage, "Rack.Server.#{namespace}"
55
- end if @sampler_namespaces
56
- end
25
+ @app.call(env).tap { @reporter.report env }
26
+ end
57
27
 
58
- def record_statsd_timing(data, namespace = nil)
59
- data.each do |name, value|
60
- name = "#{namespace}.#{name}" if namespace
61
- @statsd.timing name, value, @sample_rate
28
+ private
29
+ def build_instrumented_app(app, meters)
30
+ meters.inject app do |wrapped, meter|
31
+ lambda do |env|
32
+ meter.instrument! env[STATE], env[TIMINGS], env[GAUGES] do
33
+ wrapped.call env
34
+ end
62
35
  end
63
36
  end
64
37
  end
@@ -1,61 +1,18 @@
1
- require 'trashed'
2
1
  require 'rails/railtie'
3
- require 'active_support/ordered_options'
2
+ require 'trashed/rack'
3
+ require 'trashed/reporter'
4
4
 
5
5
  module Trashed
6
6
  class Railtie < ::Rails::Railtie
7
- config.trashed = ActiveSupport::OrderedOptions.new
8
- config.trashed.statsd = ActiveSupport::OrderedOptions.new
7
+ config.trashed = Trashed::Reporter.new
9
8
 
10
9
  initializer 'trashed' do |app|
11
- # Debug data sent to statsd. Class-level config only :/
12
- Statsd.logger = app.config.trashed.logger if app.config.trashed.debug
13
-
14
- app.config.trashed.sample_rate ||= 0.1
15
- app.config.trashed.logger = Rails.logger
16
- app.config.trashed.statsd = connect_to_statsd(app.config.trashed.statsd)
17
-
18
- app.config.trashed.statsd_request_namespaces = lambda do |env|
19
- # Rails 3.2. Record request controller, action, and format.
20
- if controller = env['action_controller.instance']
21
- name = controller.controller_name
22
- action = controller.action_name
23
- format = controller.request.format.try(:to_sym)
24
- [ "Controllers.#{name}",
25
- "Formats.#{format}",
26
- "Actions.#{name}.#{action}.#{format}" ]
27
- end
28
- end
29
-
30
- hostname = `hostname -s`.chomp
31
- app.config.trashed.statsd_sampler_namespaces = lambda do |env|
32
- # Rails 3.2. Record hostname.
33
- [ "Hosts.#{hostname}" ]
34
- end
35
- end
36
-
37
- initializer 'trashed.middleware', :after => 'trashed', :before => 'trashed.newrelic' do |app|
38
- app.middleware.insert_after 'Rack::Runtime', Trashed::Rack::MeasureResourceUsage, app.config.trashed
39
- end
40
-
41
- initializer 'trashed.newrelic', :after => 'newrelic_rpm.start_plugin' do |app|
42
- if defined?(NewRelic::Control) && NewRelic::Control.instance.agent_enabled?
43
- require 'trashed/new_relic'
44
- Trashed::NewRelic.sample ResourceUsage, app.config.trashed
45
- end
46
- end
47
-
48
- def connect_to_statsd(options)
49
10
  require 'statsd'
50
11
 
51
- case options
52
- when Statsd
53
- options
54
- when Hash
55
- Statsd.new(options[:host], options[:port]).tap do |statsd|
56
- statsd.namespace = options[:namespace]
57
- end
58
- end
12
+ app.config.trashed.sample_rate ||= 1.0
13
+ app.config.trashed.logger ||= Rails.logger
14
+
15
+ app.middleware.insert_after 'Rack::Runtime', Trashed::Rack, app.config.trashed
59
16
  end
60
17
  end
61
18
  end
@@ -0,0 +1,48 @@
1
+ require 'trashed/rack'
2
+
3
+ module Trashed
4
+ class Reporter
5
+ attr_accessor :logger, :statsd, :sample_rate
6
+ attr_accessor :timing_dimensions, :gauge_dimensions
7
+
8
+ DEFAULT_DIMENSIONS = [ :All ]
9
+
10
+ def initialize
11
+ @logger = nil
12
+ @statsd = nil
13
+ @sample_rate = 1.0
14
+ @timing_dimensions = ->(env) { DEFAULT_DIMENSIONS }
15
+ @gauge_dimensions = ->(env) { DEFAULT_DIMENSIONS }
16
+ end
17
+
18
+ def report(env)
19
+ report_logger env if @logger
20
+ report_statsd env if @statsd
21
+ end
22
+
23
+ def report_logger(env)
24
+ elapsed = env[Trashed::Rack::TIMINGS].assoc(:'Time.wall')
25
+ gc_runs = env[Trashed::Rack::TIMINGS].assoc(:'GC.count')
26
+ if elapsed && gc_runs
27
+ @logger.info "Rack handled in %dms (GC runs: %d)" % [elapsed[1], gc_runs[1]]
28
+ end
29
+ end
30
+
31
+ def report_statsd(env)
32
+ @statsd.batch do |statsd|
33
+ send_to_statsd statsd, :timing, env[Trashed::Rack::TIMINGS], :'Rack.Request', @timing_dimensions.call(env)
34
+ send_to_statsd statsd, :gauge, env[Trashed::Rack::GAUGES], :'Rack.Server', @gauge_dimensions.call(env)
35
+ end
36
+ end
37
+
38
+ def send_to_statsd(statsd, method, measurements, namespace, dimensions)
39
+ measurements.each do |metric, value|
40
+ if value.is_a? Numeric
41
+ Array(dimensions || :All).each do |dimension|
42
+ statsd.send method, :"#{namespace}.#{dimension}.#{metric}", value, @sample_rate
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,48 +1,46 @@
1
- module Trashed
2
- ResourceUsage = Meter.new do
1
+ require 'trashed/meter'
3
2
 
4
- # Wall clock time, in milliseconds since epoch
5
- counts :Time do
6
- { :wall => (Time.now.to_f * 1000).to_i }
7
- end
3
+ module Trashed
4
+ ResourceUsage = Meter.new.tap do |meter|
5
+ # Wall clock time in milliseconds since epoch.
6
+ # Includes CPU and idle time on Ruby 2.1+.
7
+ require 'trashed/instruments/stopwatch'
8
+ meter.instrument Trashed::Instruments::Stopwatch.new
8
9
 
9
10
  # RailsBench GC patch / REE 1.8
10
11
  if GC.respond_to? :enable_stats
11
- GC.enable_stats
12
-
13
- counts :Objects do
14
- { :total => ObjectSpace.allocated_objects }
15
- end
16
-
17
- gauges :Objects do
18
- { :live => ObjectSpace.live_objects }
19
- end
20
-
21
- counts :GC do
22
- { :count => GC.collections, :elapsed => GC.time, :memory => GC.allocated_size }
23
- end
24
-
25
- gauges :GC do
26
- { :growth => GC.growth }
27
- end
12
+ require 'trashed/instruments/ree_gc'
13
+ meter.instrument Trashed::Instruments::Ruby18GC.new
14
+ end
28
15
 
29
16
  # Ruby 1.9+
30
- elsif ObjectSpace.respond_to? :count_objects
31
- counts :Objects do
32
- { :total => ObjectSpace.count_objects[:TOTAL] }
33
- end
34
-
35
- gauges :Objects do
36
- ObjectSpace.count_objects
37
- end
17
+ if ObjectSpace.respond_to? :count_objects
18
+ require 'trashed/instruments/object_space_counter'
19
+ meter.instrument Trashed::Instruments::ObjectSpaceCounter.new
20
+ end
38
21
 
39
- counts :GC do
40
- { :count => GC.stat[:count] }
22
+ # Ruby 1.9+
23
+ if GC.respond_to?(:stat)
24
+ case
25
+ # Ruby 2.1+
26
+ when GC.stat[:major_gc_count]
27
+ require 'trashed/instruments/ruby21_gc'
28
+ meter.instrument Trashed::Instruments::Ruby21GC.new
29
+ # Ruby 2.0+
30
+ when GC.stat[:total_allocated_object]
31
+ require 'trashed/instruments/ruby20_gc'
32
+ meter.instrument Trashed::Instruments::Ruby20GC.new
33
+ # Ruby 1.9
34
+ else
35
+ require 'trashed/instruments/ruby19_gc'
36
+ meter.instrument Trashed::Instruments::Ruby19GC.new
41
37
  end
38
+ end
42
39
 
43
- gauges :GC do
44
- GC.stat
45
- end
40
+ # Ruby 1.9+
41
+ if defined? GC::Profiler
42
+ require 'trashed/instruments/ruby_gc_profiler'
43
+ meter.instrument Trashed::Instruments::RubyGCProfiler.new
46
44
  end
47
45
  end
48
46
  end
data/lib/trashed.rb CHANGED
@@ -1,5 +1,2 @@
1
- module Trashed
2
- require 'trashed/meter'
3
- require 'trashed/resource_usage'
4
- require 'trashed/rack'
5
- end
1
+ require 'trashed/rack'
2
+ require 'trashed/railtie' if defined? ::Rails::Railtie
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trashed
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Kemper
@@ -14,37 +14,65 @@ dependencies:
14
14
  name: statsd-ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: '0.4'
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - ! '>='
25
39
  - !ruby/object:Gem::Version
26
- version: '0.4'
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '5.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '5.3'
27
55
  description:
28
- email: jeremy@bitsweat.net
56
+ email: jeremykemper@gmail.com
29
57
  executables: []
30
58
  extensions: []
31
59
  extra_rdoc_files: []
32
60
  files:
33
- - ./MIT-LICENSE
34
- - ./README.md
35
- - ./Rakefile
36
61
  - ./init.rb
37
62
  - ./lib/trashed.rb
63
+ - ./lib/trashed/instruments/object_space_counter.rb
64
+ - ./lib/trashed/instruments/ree_gc.rb
65
+ - ./lib/trashed/instruments/ruby19_gc.rb
66
+ - ./lib/trashed/instruments/ruby20_gc.rb
67
+ - ./lib/trashed/instruments/ruby21_gc.rb
68
+ - ./lib/trashed/instruments/ruby_gc_profiler.rb
69
+ - ./lib/trashed/instruments/stopwatch.rb
38
70
  - ./lib/trashed/meter.rb
39
- - ./lib/trashed/new_relic.rb
40
71
  - ./lib/trashed/rack.rb
41
72
  - ./lib/trashed/railtie.rb
73
+ - ./lib/trashed/reporter.rb
42
74
  - ./lib/trashed/resource_usage.rb
43
- - ./test/lib/trashed/test_helper.rb
44
- - ./test/meter_test.rb
45
- - ./test/rack_test.rb
46
- - ./trashed.gemspec
47
- homepage: https://github.com/37signals/trashed
75
+ homepage: https://github.com/basecamp/trashed
48
76
  licenses: []
49
77
  metadata: {}
50
78
  post_install_message:
@@ -66,6 +94,5 @@ rubyforge_project:
66
94
  rubygems_version: 2.2.2
67
95
  signing_key:
68
96
  specification_version: 4
69
- summary: ! 'Keep tabs on Ruby garbage collection: object counts, allocated bytes,
70
- GC time.'
97
+ summary: Report per-request object allocations, GC time, and more to StatsD
71
98
  test_files: []
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2009 37signals, LLC
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md DELETED
@@ -1,34 +0,0 @@
1
- ## Trashed
2
- # Keep an eye on resource usage.
3
-
4
-
5
- - Logs per-request object counts, heap growth, and GC time.
6
- - Sends periodic resource usage snapshots to StatsD & NewRelic.
7
- - Requires Ruby 1.9 or REE.
8
-
9
-
10
- ## Setup
11
-
12
- ### Rails 3
13
-
14
- On Rails 3, add this to the top of `config/application.rb`:
15
-
16
- require 'trashed/railtie'
17
-
18
- And in the body of your app config:
19
-
20
- module YourApp
21
- class Application < Rails::Application
22
- config.trashed[:statsd] = YourApp.statsd
23
-
24
-
25
- ### Rails 2
26
-
27
- On Rails 2, add the middleware to `config/environment.rb`:
28
-
29
- Rails::Initializer.run do |config|
30
- config.middleware.use Trashed::Rack::MeasureResourceUsage, :statsd => YourApp.statsd
31
-
32
- And set up the sampler in `config/initializers/trashed.rb`:
33
-
34
- Trashed::Newrelic.sample Trashed::ResourceUsage, :statsd => YourApp.statsd
data/Rakefile DELETED
@@ -1,22 +0,0 @@
1
- require 'rake/testtask'
2
- require 'rdoc/task'
3
-
4
- desc 'Default: run unit tests'
5
- task :default => :test
6
-
7
- desc 'Run unit tests'
8
- Rake::TestTask.new :test do |t|
9
- t.libs << 'test/lib'
10
- t.pattern = 'test/**/*_test.rb'
11
- t.verbose = true
12
- end
13
-
14
- desc 'Generate RDoc documentation'
15
- Rake::RDocTask.new :rdoc do |rdoc|
16
- rdoc.rdoc_dir = 'rdoc'
17
- rdoc.title = 'Trashed'
18
- rdoc.options << '--line-numbers' << '--inline-source'
19
- rdoc.rdoc_files.include('MIT-LICENSE')
20
- rdoc.rdoc_files.include('README')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
@@ -1,47 +0,0 @@
1
- module Trashed
2
- module NewRelic
3
- def self.sample(meter, options = {})
4
- ::NewRelic::Agent.instance.stats_engine.add_sampler Sampler.new(meter, options)
5
- end
6
-
7
- class Sampler
8
- attr_accessor :stats_engine
9
-
10
- def initialize(meter, options = {})
11
- @meter = meter
12
- @label = options[:label] || 'Custom/%s'
13
- @statsd = options[:statsd]
14
- end
15
-
16
- def poll
17
- record @meter.count
18
- record @meter.gauge
19
- end
20
-
21
- def record(data)
22
- data.each do |name, value|
23
- record_newrelic name, value
24
- record_statsd name, value if @statsd
25
- end
26
- end
27
-
28
- private
29
-
30
- def record_statsd(name, value)
31
- @statsd.timing name, value
32
- end
33
-
34
- def record_newrelic(name, value)
35
- stats_for(label_for(name)).record_data_point(value)
36
- end
37
-
38
- def stats_for(metric)
39
- stats_engine.get_stats(metric, false)
40
- end
41
-
42
- def label_for(name)
43
- @label % name.gsub('.', '/')
44
- end
45
- end
46
- end
47
- end
@@ -1,3 +0,0 @@
1
- require 'trashed'
2
- require 'minitest/unit'
3
- MiniTest::Unit.autorun
data/test/meter_test.rb DELETED
@@ -1,15 +0,0 @@
1
- require 'trashed/test_helper'
2
-
3
- class MeterTest < MiniTest::Unit::TestCase
4
- def test_count
5
- time = Trashed::ResourceUsage.count['Time.wall']
6
- refute_nil time
7
- assert_in_delta time, (Time.now.to_f * 1000), 1000
8
- end
9
-
10
- def test_instrument
11
- elapsed = Trashed::ResourceUsage.instrument { nil }['Time.wall']
12
- refute_nil elapsed
13
- assert_in_delta elapsed, 0, 1000
14
- end
15
- end
data/test/rack_test.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'trashed/test_helper'
2
-
3
- class RackTest < MiniTest::Unit::TestCase
4
- Hello = lambda { |env| [200, {}, %w(hello)] }
5
-
6
- def test_instruments_app_and_stores_in_env
7
- env = {}
8
-
9
- response = Trashed::Rack::MeasureResourceUsage.new(Hello).call(env)
10
-
11
- refute_nil env['trashed.change']
12
- refute_nil env['trashed.usage']
13
-
14
- elapsed = env['trashed.change']['Time.wall']
15
- refute_nil elapsed
16
- assert_in_delta elapsed, 0, 1000
17
- end
18
- end
data/trashed.gemspec DELETED
@@ -1,12 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'trashed'
3
- s.version = '2.0.5'
4
- s.author = 'Jeremy Kemper'
5
- s.email = 'jeremy@bitsweat.net'
6
- s.homepage = 'https://github.com/37signals/trashed'
7
- s.summary = 'Keep tabs on Ruby garbage collection: object counts, allocated bytes, GC time.'
8
-
9
- s.add_dependency 'statsd-ruby', '>= 0.4'
10
-
11
- s.files = Dir["#{File.dirname(__FILE__)}/**/*"]
12
- end