time_bandits 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWEyMTkyMzVmNzk4ZDRmM2ExMzg0NDlmZGM2NDlhZjg5NTM3YjQ1Yg==
4
+ NWQxOTYzZGM3NGMxMGM5NTc0ZmViNTIyMzJhNDA1ODNiNTExMjg0ZA==
5
5
  data.tar.gz: !binary |-
6
- OTA2NjczNzVmZWMxYTMyMGZjZDZiMDU5MmU3YjY3YTQzZjBhOWEyYQ==
6
+ NmQ5MTdiMjNmNWRjNTgzYjA2OTNjM2ExYWI2YzcyNjdiZTI1ZDg1ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MTcwNTMwMDhkYjE2NmFiMDk1NGIwMTk4ZDY5M2RiMWNlMzJiNjJlMWRkNTRl
10
- YTRiMDUwYjdmYjY5OTlmMzZlZDI2NWUyYmYzMzljY2FmNDYwODJkMmE1MWMw
11
- ZTRkMDljMGY5OWQ5YzYzYTNmYWJlNzlmZDYxNjgxODliYWZkYzc=
9
+ NzAxOTQ2ZDBlNzMyN2IzMWYzYTExOTc3MjVkNmE3MWUyYzBmOTAzNjZiZDgw
10
+ NjY0Y2M3NjZmNDA2NzQ1Nzk2MmE4YzAzMmNjY2NkZWNhYWMzZTE1ZGMzYzk3
11
+ NTJhZGZhMzNkZGQ5ZDQ3MGZiMzdhNDEyMGQ3ODAyYjFjZjE3Mjg=
12
12
  data.tar.gz: !binary |-
13
- Mzg0MzRiMWVkMTIxOWQ4MTg5MjU1MTczOWU0ZWFkNDc1NjYxMmI0ZmM3ODY1
14
- NjIyM2U0YjI4ZmU4YjNkMTgyZDdhYTY3ODFjNjBjZjQ3NDQ4NzY0NTU3YWI4
15
- YTg4NDg0MGU5YWVkYmFiNzNjNTdlZmRjNTU2ZDIyNjU5ZjZmYjA=
13
+ MmJjYWFiOGQxNDc1YjA5MWI1OTI1NWZlYTNmOGNlZTc1OWFlNWI1MDkxYmI5
14
+ N2YzNjEyMTRlMjc2MmFmZDFkZjIwNWJhMWE3Y2U0Y2Q2ZTAxN2EyZWIxYjhj
15
+ MDVjNjBkYjBmYjc5OTMwNmQ2ODU5ODM0ZDExZWU5ZjVhZmU5ZWQ=
data/README.rdoc CHANGED
@@ -78,8 +78,20 @@ rvm and the railsexpress rvm patchsets (see https://github.com/skaes/rvm-patchse
78
78
  This plugin started from the code of the 'custom_benchmark' plugin written by tylerkovacs. However, we
79
79
  changed so much of the code that is is practically a full rewrite, hence we changed the name.
80
80
 
81
+ == Running Tests
82
+
83
+ In order for the test to run you need a running memcached and redis-server
84
+
81
85
  == Release Notes
82
86
 
87
+ version 0.5.2
88
+ - added redis time consumer
89
+ - fixed rails 4.0 problems with builtin mem_cache_store
90
+ - now only consumers which measured something are added to the completed line
91
+
92
+ version 0.5.1
93
+ - added license file
94
+
83
95
  version 0.5:
84
96
  - has dropped rails 2 support
85
97
  - relies on ActiveSupport::Notifications
data/lib/time_bandits.rb CHANGED
@@ -14,6 +14,7 @@ module TimeBandits
14
14
  autoload :MemCache, 'time_bandits/time_consumers/mem_cache'
15
15
  autoload :Memcached, 'time_bandits/time_consumers/memcached'
16
16
  autoload :Dalli, 'time_bandits/time_consumers/dalli'
17
+ autoload :Redis, 'time_bandits/time_consumers/redis'
17
18
  end
18
19
 
19
20
  require 'time_bandits/railtie' if defined?(Rails) && Rails::VERSION::STRING >= "3.0"
@@ -34,8 +35,12 @@ module TimeBandits
34
35
  time_bandits.map{|b| b.consumed}.sum
35
36
  end
36
37
 
38
+ def self.runtimes
39
+ time_bandits.map{|b| b.runtime}.reject{|t| t.blank?}
40
+ end
41
+
37
42
  def self.runtime
38
- time_bandits.map{|b| b.runtime}.join("| ")
43
+ runtimes.join(" | ")
39
44
  end
40
45
 
41
46
  def self.metrics
@@ -124,11 +124,7 @@ module ActionController #:nodoc:
124
124
  def log_process_action(payload) #:nodoc:
125
125
  # need to call this to compute DB time/calls
126
126
  TimeBandits.consumed
127
- messages = super
128
- TimeBandits.time_bandits.each do |bandit|
129
- messages << bandit.runtime
130
- end
131
- messages
127
+ super.concat(TimeBandits.runtimes)
132
128
  end
133
129
  end
134
130
 
@@ -0,0 +1,15 @@
1
+ require "active_support/cache"
2
+
3
+ # rails 4 builtin mem_cache_store broke hit reporting for fetch
4
+ class ActiveSupport::Cache::Store
5
+ private
6
+ # only called by fetch
7
+ def find_cached_entry(key, name, options)
8
+ instrument(:read, name, options) do |payload|
9
+ payload[:super_operation] = :fetch if payload
10
+ res = read_entry(key, options)
11
+ payload[:hit] = !!res if payload
12
+ res
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ require 'redis'
2
+ class Redis
3
+ class Client
4
+ alias :old_logging :logging
5
+
6
+ def logging(commands, &block)
7
+ ActiveSupport::Notifications.instrument('request.redis', commands: commands) do
8
+ old_logging(commands, &block)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -51,7 +51,12 @@ module TimeBandits::TimeConsumers
51
51
  end
52
52
 
53
53
  def runtime
54
- self.class.runtime_format % metrics.values_at(*self.class.runtime_keys)
54
+ values = metrics.values_at(*self.class.runtime_keys)
55
+ if values.all?{|v|v==0}
56
+ ""
57
+ else
58
+ self.class.runtime_format % values
59
+ end
55
60
  end
56
61
  end
57
62
  end
@@ -1,8 +1,20 @@
1
+ if Rails::VERSION::STRING >= "4.0"
2
+ require "time_bandits/monkey_patches/active_support_cache_store"
3
+ end
4
+
1
5
  module TimeBandits::TimeConsumers
2
6
  class Dalli < BaseConsumer
3
7
  prefix :memcache
4
8
  fields :time, :calls, :misses, :reads, :writes
5
- format "DALLI: %.3f(%dr,%dm,%dw,%dc)", :time, :reads, :misses, :writes, :calls
9
+ format "Dalli: %.3f(%dr,%dm,%dw,%dc)", :time, :reads, :misses, :writes, :calls
10
+
11
+ if Rails::VERSION::STRING >= "4.0"
12
+ def reset
13
+ # Rails 4 mem_cache_store (which uses dalli internally), unlike dalli_store, is not instrumented by default
14
+ Rails.cache.class.instrument = true
15
+ super
16
+ end
17
+ end
6
18
 
7
19
  class Subscriber < ActiveSupport::LogSubscriber
8
20
  # cache events are: read write fetch_hit generate delete read_multi increment decrement clear
@@ -0,0 +1,43 @@
1
+ # a time consumer implementation for redis
2
+ # install into application_controller.rb with the line
3
+ #
4
+ # time_bandit TimeBandits::TimeConsumers::Redis
5
+ #
6
+ require 'time_bandits/monkey_patches/redis'
7
+
8
+ module TimeBandits
9
+ module TimeConsumers
10
+ class Redis < BaseConsumer
11
+ prefix :redis
12
+ fields :time, :calls
13
+ format "Redis: %.3f(%d)", :time, :calls
14
+
15
+ class Subscriber < ActiveSupport::LogSubscriber
16
+ def request(event)
17
+ i = Redis.instance
18
+ i.time += event.duration
19
+ i.calls += event.payload[:commands].size
20
+
21
+ return unless logger.debug?
22
+
23
+ name = "%s (%.2fms)" % ["Redis", event.duration]
24
+ cmds = event.payload[:commands]
25
+
26
+ # output = " #{color(name, CYAN, true)}"
27
+ output = " #{name}"
28
+
29
+ cmds.each do |cmd, *args|
30
+ if args.present?
31
+ output << " [ #{cmd.to_s.upcase} #{args.join(" ")} ]"
32
+ else
33
+ output << " [ #{cmd.to_s.upcase} ]"
34
+ end
35
+ end
36
+
37
+ debug output
38
+ end
39
+ end
40
+ Subscriber.attach_to(:redis)
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,3 @@
1
1
  module TimeBandits
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
data/test/test_helper.rb CHANGED
@@ -13,6 +13,17 @@ require_relative '../lib/time_bandits'
13
13
  ActiveSupport::LogSubscriber.class_eval do
14
14
  # need a logger, otherwise no data will be collected
15
15
  def logger
16
- @logger ||= Logger.new(STDOUT)
16
+ @logger ||= ::Logger.new("/dev/null")
17
+ end
18
+ end
19
+
20
+ # fake Rails
21
+ module Rails
22
+ extend self
23
+ module VERSION
24
+ STRING = "4.0.0"
25
+ end
26
+ def cache
27
+ @cache ||= ActiveSupport::Cache.lookup_store(:mem_cache_store)
17
28
  end
18
29
  end
@@ -23,6 +23,7 @@ class ActiveSupportNotificationsTest < Test::Unit::TestCase
23
23
  TimeBandits.time_bandits = []
24
24
  TimeBandits.add SimpleConsumer
25
25
  TimeBandits.reset
26
+ @bandit = SimpleConsumer.instance
26
27
  end
27
28
 
28
29
  test "getting metrics" do
@@ -30,7 +31,8 @@ class ActiveSupportNotificationsTest < Test::Unit::TestCase
30
31
  end
31
32
 
32
33
  test "formatting" do
33
- assert_equal "Simple: 0.0ms(0 calls)", TimeBandits.runtime
34
+ @bandit.calls = 1
35
+ assert_equal "Simple: 0.0ms(1 calls)", TimeBandits.runtime
34
36
  end
35
37
 
36
38
  test "foreground work gets accounted for in milliseconds" do
@@ -0,0 +1,63 @@
1
+ require_relative '../test_helper'
2
+
3
+ class DalliTest < Test::Unit::TestCase
4
+ def setup
5
+ TimeBandits.time_bandits = []
6
+ TimeBandits.add TimeBandits::TimeConsumers::Dalli
7
+ TimeBandits.reset
8
+ @cache = Rails.cache
9
+ @bandit = TimeBandits::TimeConsumers::Dalli.instance
10
+ end
11
+
12
+ test "getting metrics" do
13
+ nothing_measured = {
14
+ :memcache_time => 0,
15
+ :memcache_calls => 0,
16
+ :memcache_misses => 0,
17
+ :memcache_reads => 0,
18
+ :memcache_writes => 0
19
+ }
20
+ assert_equal nothing_measured, TimeBandits.metrics
21
+ end
22
+
23
+ test "formatting" do
24
+ @bandit.calls = 3
25
+ assert_equal "Dalli: 0.000(0r,0m,0w,3c)", TimeBandits.runtime
26
+ end
27
+
28
+ test "foreground work gets accounted for" do
29
+ work
30
+ check_work
31
+ end
32
+
33
+ test "background work is ignored" do
34
+ Thread.new do
35
+ work
36
+ check_work
37
+ end.join
38
+ m = TimeBandits.metrics
39
+ assert_equal 0, m[:memcache_calls]
40
+ assert_equal 0, m[:memcache_reads]
41
+ assert_equal 0, m[:memcache_misses]
42
+ assert_equal 0, m[:memcache_writes]
43
+ assert_equal 0, m[:memcache_time]
44
+ end
45
+
46
+ private
47
+ def work
48
+ TimeBandits.reset
49
+ 2.times do
50
+ @cache.read("foo")
51
+ @cache.write("bar", 1)
52
+ end
53
+ end
54
+ def check_work
55
+ m = TimeBandits.metrics
56
+ assert_equal 4, m[:memcache_calls]
57
+ assert_equal 2, m[:memcache_reads]
58
+ assert_equal 2, m[:memcache_misses]
59
+ assert_equal 2, m[:memcache_writes]
60
+ assert 0 < m[:memcache_time]
61
+ assert_equal m[:memcache_time], TimeBandits.consumed
62
+ end
63
+ end
@@ -6,21 +6,23 @@ class MemcachedTest < Test::Unit::TestCase
6
6
  TimeBandits.add TimeBandits::TimeConsumers::Memcached
7
7
  TimeBandits.reset
8
8
  @cache = Memcached.new
9
+ @bandit = TimeBandits::TimeConsumers::Memcached.instance
9
10
  end
10
11
 
11
12
  test "getting metrics" do
12
13
  nothing_measured = {
13
- :memcache_time=>0,
14
- :memcache_calls=>0,
15
- :memcache_misses=>0,
16
- :memcache_reads=>0,
17
- :memcache_writes=>0
14
+ :memcache_time => 0,
15
+ :memcache_calls => 0,
16
+ :memcache_misses => 0,
17
+ :memcache_reads => 0,
18
+ :memcache_writes => 0
18
19
  }
19
20
  assert_equal nothing_measured, TimeBandits.metrics
20
21
  end
21
22
 
22
23
  test "formatting" do
23
- assert_equal "MC: 0.000(0r,0m,0w,0c)", TimeBandits.runtime
24
+ @bandit.calls = 3
25
+ assert_equal "MC: 0.000(0r,0m,0w,3c)", TimeBandits.runtime
24
26
  end
25
27
 
26
28
  test "foreground work gets accounted for" do
@@ -0,0 +1,54 @@
1
+ require_relative '../test_helper'
2
+
3
+ class RedisTest < Test::Unit::TestCase
4
+ def setup
5
+ TimeBandits.time_bandits = []
6
+ TimeBandits.add TimeBandits::TimeConsumers::Redis
7
+ TimeBandits.reset
8
+ @redis = Redis.new
9
+ @bandit = TimeBandits::TimeConsumers::Redis.instance
10
+ end
11
+
12
+ test "getting metrics" do
13
+ nothing_measured = {
14
+ :redis_time => 0,
15
+ :redis_calls => 0
16
+ }
17
+ assert_equal nothing_measured, TimeBandits.metrics
18
+ end
19
+
20
+ test "formatting" do
21
+ @bandit.calls = 3
22
+ assert_equal "Redis: 0.000(3)", TimeBandits.runtime
23
+ end
24
+
25
+ test "foreground work gets accounted for" do
26
+ work
27
+ check_work
28
+ end
29
+
30
+ test "background work is ignored" do
31
+ Thread.new do
32
+ work
33
+ check_work
34
+ end.join
35
+ m = TimeBandits.metrics
36
+ assert_equal 0, m[:redis_calls]
37
+ assert_equal 0, m[:redis_time]
38
+ end
39
+
40
+ private
41
+ def work
42
+ TimeBandits.reset
43
+ 2.times do
44
+ @redis.get("foo")
45
+ @redis.set("bar", 1)
46
+ end
47
+ end
48
+ def check_work
49
+ m = TimeBandits.metrics
50
+ assert_equal 4, m[:redis_calls]
51
+ assert 0 < m[:redis_time]
52
+ assert_equal m[:redis_time], TimeBandits.consumed
53
+ end
54
+ end
data/time_bandits.gemspec CHANGED
@@ -23,5 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.add_development_dependency("rake")
24
24
  s.add_development_dependency("mocha")
25
25
  s.add_development_dependency("ansi")
26
+ s.add_development_dependency("dalli")
27
+ s.add_development_dependency("redis")
26
28
  end
27
29
 
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.5.1
4
+ version: 0.6.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-08-11 00:00:00.000000000 Z
11
+ date: 2013-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,34 @@ dependencies:
80
80
  type: :development
81
81
  prerelease: false
82
82
  name: ansi
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ type: :development
95
+ prerelease: false
96
+ name: dalli
97
+ - !ruby/object:Gem::Dependency
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ type: :development
109
+ prerelease: false
110
+ name: redis
83
111
  description: Rails Completed Line on Steroids
84
112
  email:
85
113
  - skaes@railsexpress.de
@@ -96,8 +124,10 @@ files:
96
124
  - lib/time_bandits.rb
97
125
  - lib/time_bandits/monkey_patches/action_controller.rb
98
126
  - lib/time_bandits/monkey_patches/active_record.rb
127
+ - lib/time_bandits/monkey_patches/active_support_cache_store.rb
99
128
  - lib/time_bandits/monkey_patches/memcache-client.rb
100
129
  - lib/time_bandits/monkey_patches/memcached.rb
130
+ - lib/time_bandits/monkey_patches/redis.rb
101
131
  - lib/time_bandits/rack/logger.rb
102
132
  - lib/time_bandits/rack/logger40.rb
103
133
  - lib/time_bandits/railtie.rb
@@ -108,12 +138,15 @@ files:
108
138
  - lib/time_bandits/time_consumers/jmx.rb
109
139
  - lib/time_bandits/time_consumers/mem_cache.rb
110
140
  - lib/time_bandits/time_consumers/memcached.rb
141
+ - lib/time_bandits/time_consumers/redis.rb
111
142
  - lib/time_bandits/version.rb
112
143
  - rails/init.rb
113
144
  - test/test_helper.rb
114
145
  - test/unit/active_support_notifications_test.rb
115
146
  - test/unit/base_test.rb
147
+ - test/unit/dalli_test.rb
116
148
  - test/unit/memcached_test.rb
149
+ - test/unit/redis_test.rb
117
150
  - time_bandits.gemspec
118
151
  homepage: https://github.com/skaes/time_bandits/
119
152
  licenses:
@@ -143,4 +176,6 @@ test_files:
143
176
  - test/test_helper.rb
144
177
  - test/unit/active_support_notifications_test.rb
145
178
  - test/unit/base_test.rb
179
+ - test/unit/dalli_test.rb
146
180
  - test/unit/memcached_test.rb
181
+ - test/unit/redis_test.rb