time_bandits 0.4.1 → 0.5.0

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.
@@ -8,42 +8,22 @@
8
8
  module TimeBandits
9
9
  module TimeConsumers
10
10
  # provide a time consumer interface to ActiveRecord
11
- module Database
12
- extend self
13
-
14
- def info
15
- Thread.current.thread_variable_get(:time_bandits_database_info) ||
16
- Thread.current.thread_variable_set(:time_bandits_database_info, [0.0, 0, 0])
17
- end
18
-
19
- def info=(info)
20
- Thread.current.thread_variable_set(:time_bandits_database_info, info)
21
- end
11
+ class Database < TimeBandits::TimeConsumers::BaseConsumer
12
+ prefix :db
13
+ fields :time, :calls, :sql_query_cache_hits
14
+ format "ActiveRecord: %.3fms(%dq,%dh)", :time, :calls, :sql_query_cache_hits
22
15
 
23
16
  def reset
24
17
  reset_stats
25
- self.info = [0.0, 0, 0]
18
+ super
26
19
  end
27
20
 
28
21
  def consumed
29
22
  time, calls, hits = reset_stats
30
- i = self.info
31
- i[2] += hits
32
- i[1] += calls
33
- i[0] += time
34
- end
35
-
36
- def runtime
37
- time, calls, hits = *info
38
- sprintf "ActiveRecord: %.3fms(%dq,%dh)", time*1000, calls, hits
39
- end
40
-
41
- def metrics
42
- {
43
- :db_time => info[0]*1000,
44
- :db_calls => info[1],
45
- :db_sql_query_cache_hits => info[2]
46
- }
23
+ i = Database.instance
24
+ i.sql_query_cache_hits += hits
25
+ i.calls += calls
26
+ i.time += time
47
27
  end
48
28
 
49
29
  private
@@ -53,7 +33,7 @@ module TimeBandits
53
33
  hits = s.reset_query_cache_hits
54
34
  calls = s.reset_call_count
55
35
  time = s.reset_runtime
56
- [time.to_f/1000, calls, hits]
36
+ [time, calls, hits]
57
37
  end
58
38
  end
59
39
  end
@@ -49,8 +49,8 @@ module TimeBandits
49
49
  0.0
50
50
  end
51
51
 
52
- def consumed_gc_time
53
- (GC.time - @consumed).to_f / 1_000_000
52
+ def consumed_gc_time # ms
53
+ (GC.time - @consumed).to_f / 1000
54
54
  end
55
55
 
56
56
  def collections
@@ -81,11 +81,7 @@ module TimeBandits
81
81
  end
82
82
  end
83
83
 
84
- if defined?(Rails) && Rails::VERSION::STRING >= "3.0"
85
- GCFORMAT = "GC: %.3f(%d) | HP: %d(%d,%d,%d,%d)"
86
- else
87
- GCFORMAT= "GC: %.3f(%d), HP: %d(%d,%d,%d,%d)"
88
- end
84
+ GCFORMAT = "GC: %.3f(%d) | HP: %d(%d,%d,%d,%d)"
89
85
 
90
86
  def runtime
91
87
  heap_slots = GC.heap_slots
@@ -93,12 +89,12 @@ module TimeBandits
93
89
  allocated_objects = self.allocated_objects
94
90
  allocated_size = self.allocated_size
95
91
  GCHacks.heap_dump if heap_growth > 0 && @@heap_dumps_enabled && defined?(GCHacks)
96
- GCFORMAT % [consumed_gc_time * 1000, collections, heap_growth, heap_slots, allocated_objects, allocated_size, live_data_set_size]
92
+ GCFORMAT % [consumed_gc_time, collections, heap_growth, heap_slots, allocated_objects, allocated_size, live_data_set_size]
97
93
  end
98
94
 
99
95
  def metrics
100
96
  {
101
- :gc_time => consumed_gc_time * 1000,
97
+ :gc_time => consumed_gc_time,
102
98
  :gc_calls => collections,
103
99
  :heap_growth => heap_growth,
104
100
  :heap_size => GC.heap_slots,
@@ -111,12 +107,12 @@ module TimeBandits
111
107
  else
112
108
 
113
109
  def runtime
114
- "GC: %.3f(%d)" % [consumed_gc_time * 1000, collections]
110
+ "GC: %.3f(%d)" % [consumed_gc_time, collections]
115
111
  end
116
112
 
117
113
  def metrics
118
114
  {
119
- :gc_time => consumed_gc_time * 1000,
115
+ :gc_time => consumed_gc_time,
120
116
  :gc_calls => collections
121
117
  }
122
118
  end
@@ -4,26 +4,23 @@
4
4
  # time_bandit TimeBandits::TimeConsumers::MemCache
5
5
  #
6
6
  require 'time_bandits/monkey_patches/memcache-client'
7
+
7
8
  module TimeBandits
8
9
  module TimeConsumers
9
- class MemCache
10
- class << self
11
- def reset
12
- ::MemCache.reset_benchmarks
13
- end
14
-
15
- def consumed
16
- ::MemCache.get_benchmarks.first
17
- end
18
-
19
- def runtime
20
- ::MemCache.cache_runtime
21
- end
10
+ class Memcache < BaseConsumer
11
+ prefix :memcache
12
+ fields :time, :calls, :misses
13
+ format "MC: %.3f(%dr,%dm)", :time, :calls, :misses
22
14
 
23
- def metrics
24
- ::MemCache.metrics
15
+ class Subscriber < ActiveSupport::LogSubscriber
16
+ def get(event)
17
+ i = Memcache.instance
18
+ i.time += event.duration
19
+ i.calls += 1
20
+ i.misses += event.payload[:misses]
25
21
  end
26
22
  end
23
+ Subscriber.attach_to :memcache
27
24
  end
28
25
  end
29
26
  end
@@ -4,26 +4,31 @@
4
4
  # time_bandit TimeBandits::TimeConsumers::Memcached
5
5
  #
6
6
  require 'time_bandits/monkey_patches/memcached'
7
+
7
8
  module TimeBandits
8
9
  module TimeConsumers
9
- class Memcached
10
- class << self
11
- def reset
12
- ::Memcached.reset_benchmarks
13
- end
10
+ class Memcached < BaseConsumer
11
+ prefix :memcache
12
+ fields :time, :calls, :misses, :reads, :writes
13
+ format "MC: %.3f(%dr,%dm,%dw,%dc)", :time, :reads, :misses, :writes, :calls
14
14
 
15
- def consumed
16
- ::Memcached.get_benchmarks.first
15
+ class Subscriber < ActiveSupport::LogSubscriber
16
+ def get(event)
17
+ i = Memcached.instance
18
+ i.time += event.duration
19
+ i.calls += 1
20
+ payload = event.payload
21
+ i.reads += payload[:reads]
22
+ i.misses += payload[:misses]
17
23
  end
18
-
19
- def runtime
20
- ::Memcached.cache_runtime
21
- end
22
-
23
- def metrics
24
- ::Memcached.metrics
24
+ def set(event)
25
+ i = Memcached.instance
26
+ i.time += event.duration
27
+ i.calls += 1
28
+ i.writes += 1
25
29
  end
26
30
  end
31
+ Subscriber.attach_to :memcached
27
32
  end
28
33
  end
29
34
  end
@@ -1,3 +1,3 @@
1
1
  module TimeBandits
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -0,0 +1,18 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+ require 'active_support/testing/declarative'
4
+
5
+ require 'minitest/pride'
6
+
7
+ class Test::Unit::TestCase
8
+ extend ActiveSupport::Testing::Declarative
9
+ end
10
+
11
+ require_relative '../lib/time_bandits'
12
+
13
+ ActiveSupport::LogSubscriber.class_eval do
14
+ # need a logger, otherwise no data will be collected
15
+ def logger
16
+ @logger ||= Logger.new(STDOUT)
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ require_relative '../test_helper'
2
+ require 'active_support/notifications'
3
+ require 'active_support/log_subscriber'
4
+ require 'thread_variables/access'
5
+
6
+ class ActiveSupportNotificationsTest < Test::Unit::TestCase
7
+ class SimpleConsumer < TimeBandits::TimeConsumers::BaseConsumer
8
+ prefix :simple
9
+ fields :time, :calls
10
+ format "Simple: %.1fms(%d calls)", :time, :calls
11
+
12
+ class Subscriber < ActiveSupport::LogSubscriber
13
+ def work(event)
14
+ i = SimpleConsumer.instance
15
+ i.time += event.duration
16
+ i.calls += 1
17
+ end
18
+ end
19
+ Subscriber.attach_to :simple
20
+ end
21
+
22
+ def setup
23
+ TimeBandits.time_bandits = []
24
+ TimeBandits.add SimpleConsumer
25
+ TimeBandits.reset
26
+ end
27
+
28
+ test "getting metrics" do
29
+ assert_equal({:simple_calls => 0, :simple_time => 0}, TimeBandits.metrics)
30
+ end
31
+
32
+ test "formatting" do
33
+ assert_equal "Simple: 0.0ms(0 calls)", TimeBandits.runtime
34
+ end
35
+
36
+ test "foreground work gets accounted for in milliseconds" do
37
+ work
38
+ check_work
39
+ end
40
+
41
+ test "background work is ignored" do
42
+ Thread.new do
43
+ work
44
+ check_work
45
+ end.join
46
+ m = TimeBandits.metrics
47
+ assert_equal 0, m[:simple_calls]
48
+ assert_equal 0, m[:simple_time]
49
+ end
50
+
51
+ private
52
+ def work
53
+ 2.times do
54
+ ActiveSupport::Notifications.instrument("work.simple") { sleep 0.1 }
55
+ end
56
+ end
57
+ def check_work
58
+ m = TimeBandits.metrics
59
+ assert_equal 2, m[:simple_calls]
60
+ assert 200 < m[:simple_time]
61
+ assert 300 > m[:simple_time]
62
+ assert_equal m[:simple_time], TimeBandits.consumed
63
+ end
64
+ end
@@ -0,0 +1,63 @@
1
+ require_relative '../test_helper'
2
+
3
+ class NoTimeBanditsTest < Test::Unit::TestCase
4
+ def setup
5
+ TimeBandits.time_bandits = []
6
+ end
7
+
8
+ test "getting list of all time bandits" do
9
+ assert_equal [], TimeBandits.time_bandits
10
+ test_clean_state
11
+ end
12
+
13
+ test "reset" do
14
+ assert_nothing_raised { TimeBandits.reset }
15
+ test_clean_state
16
+ end
17
+
18
+ test "benchmarking" do
19
+ logger = mock("logger")
20
+ logger.expects(:info)
21
+ TimeBandits.benchmark("foo", logger) { }
22
+ test_clean_state
23
+ end
24
+
25
+ private
26
+ def test_clean_state
27
+ assert_equal Hash.new, TimeBandits.metrics
28
+ assert_equal 0, TimeBandits.consumed
29
+ assert_equal "", TimeBandits.runtime
30
+ end
31
+ end
32
+
33
+ class DummyConsumerTest < Test::Unit::TestCase
34
+ module DummyConsumer
35
+ extend self
36
+ def consumed; 0; end
37
+ def runtime; "Dummy: 0ms"; end
38
+ def metrics; {:dummy_time => 0, :dummy_calls => 0}; end
39
+ def reset; end
40
+ end
41
+
42
+ def setup
43
+ TimeBandits.time_bandits = []
44
+ TimeBandits.add DummyConsumer
45
+ end
46
+
47
+ test "getting list of all time bandits" do
48
+ assert_equal [DummyConsumer], TimeBandits.time_bandits
49
+ end
50
+
51
+ test "adding consumer a second time does not change the list of time bandits" do
52
+ TimeBandits.add DummyConsumer
53
+ assert_equal [DummyConsumer], TimeBandits.time_bandits
54
+ end
55
+
56
+ test "reset" do
57
+ assert_nothing_raised { TimeBandits.reset }
58
+ end
59
+
60
+ test "getting metrics" do
61
+ assert_equal({:dummy_time => 0, :dummy_calls => 0}, TimeBandits.metrics)
62
+ end
63
+ end
@@ -0,0 +1,60 @@
1
+ require_relative '../test_helper'
2
+
3
+ class MemcachedTest < Test::Unit::TestCase
4
+ def setup
5
+ TimeBandits.time_bandits = []
6
+ TimeBandits.add TimeBandits::TimeConsumers::Memcached
7
+ TimeBandits.reset
8
+ @cache = Memcached.new
9
+ end
10
+
11
+ test "getting metrics" do
12
+ nothing_measured = {
13
+ :memcache_time=>0,
14
+ :memcache_calls=>0,
15
+ :memcache_misses=>0,
16
+ :memcache_reads=>0,
17
+ :memcache_writes=>0
18
+ }
19
+ assert_equal nothing_measured, TimeBandits.metrics
20
+ end
21
+
22
+ test "formatting" do
23
+ assert_equal "MC: 0.000(0r,0m,0w,0c)", TimeBandits.runtime
24
+ end
25
+
26
+ test "foreground work gets accounted for" do
27
+ work
28
+ check_work
29
+ end
30
+
31
+ test "background work is ignored" do
32
+ Thread.new do
33
+ work
34
+ check_work
35
+ end.join
36
+ m = TimeBandits.metrics
37
+ assert_equal 0, m[:memcache_calls]
38
+ assert_equal 0, m[:memcache_reads]
39
+ assert_equal 0, m[:memcache_misses]
40
+ assert_equal 0, m[:memcache_writes]
41
+ assert_equal 0, m[:memcache_time]
42
+ end
43
+
44
+ private
45
+ def work
46
+ 2.times do
47
+ @cache.get("foo")
48
+ @cache.set("bar", 1)
49
+ end
50
+ end
51
+ def check_work
52
+ m = TimeBandits.metrics
53
+ assert_equal 4, m[:memcache_calls]
54
+ assert_equal 2, m[:memcache_reads]
55
+ assert_equal 2, m[:memcache_misses]
56
+ assert_equal 2, m[:memcache_writes]
57
+ assert 0 < m[:memcache_time]
58
+ assert_equal m[:memcache_time], TimeBandits.consumed
59
+ end
60
+ end
@@ -20,5 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency("thread_variables")
21
21
  s.add_runtime_dependency("activesupport", [">= 2.3.2"])
22
22
  s.add_development_dependency("rake")
23
+ s.add_development_dependency("mocha")
24
+ s.add_development_dependency("ansi")
23
25
  end
24
26
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_bandits
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kaes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-21 00:00:00.000000000 Z
11
+ date: 2013-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,34 @@ dependencies:
52
52
  type: :development
53
53
  prerelease: false
54
54
  name: rake
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ name: mocha
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ type: :development
81
+ prerelease: false
82
+ name: ansi
55
83
  description: Rails Completed Line on Steroids
56
84
  email:
57
85
  - skaes@railsexpress.de
@@ -65,25 +93,27 @@ files:
65
93
  - README_RAILS2.rdoc
66
94
  - Rakefile
67
95
  - TODO
68
- - init.rb
69
96
  - lib/time_bandits.rb
70
97
  - lib/time_bandits/monkey_patches/action_controller.rb
71
- - lib/time_bandits/monkey_patches/action_controller_rails2.rb
72
98
  - lib/time_bandits/monkey_patches/active_record.rb
73
- - lib/time_bandits/monkey_patches/active_record_rails2.rb
74
99
  - lib/time_bandits/monkey_patches/memcache-client.rb
75
100
  - lib/time_bandits/monkey_patches/memcached.rb
76
101
  - lib/time_bandits/rack/logger.rb
77
102
  - lib/time_bandits/rack/logger40.rb
78
103
  - lib/time_bandits/railtie.rb
104
+ - lib/time_bandits/time_consumers/base_consumer.rb
105
+ - lib/time_bandits/time_consumers/dalli.rb
79
106
  - lib/time_bandits/time_consumers/database.rb
80
- - lib/time_bandits/time_consumers/database_rails2.rb
81
107
  - lib/time_bandits/time_consumers/garbage_collection.rb
82
108
  - lib/time_bandits/time_consumers/jmx.rb
83
109
  - lib/time_bandits/time_consumers/mem_cache.rb
84
110
  - lib/time_bandits/time_consumers/memcached.rb
85
111
  - lib/time_bandits/version.rb
86
112
  - rails/init.rb
113
+ - test/test_helper.rb
114
+ - test/unit/active_support_notifications_test.rb
115
+ - test/unit/base_test.rb
116
+ - test/unit/memcached_test.rb
87
117
  - time_bandits.gemspec
88
118
  homepage: https://github.com/skaes/time_bandits/
89
119
  licenses: []
@@ -108,4 +138,8 @@ rubygems_version: 2.0.5
108
138
  signing_key:
109
139
  specification_version: 4
110
140
  summary: Custom performance logging for Rails
111
- test_files: []
141
+ test_files:
142
+ - test/test_helper.rb
143
+ - test/unit/active_support_notifications_test.rb
144
+ - test/unit/base_test.rb
145
+ - test/unit/memcached_test.rb