time_bandits 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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