time_bandits 0.5.1 → 0.6.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.
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