remnant 0.2.4 → 0.3.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.
- data/lib/remnant/base.rb +36 -3
- data/lib/remnant/database/query.rb +19 -0
- data/lib/remnant/database.rb +49 -0
- data/lib/remnant/discover.rb +15 -2
- data/lib/remnant/rails.rb +34 -0
- data/lib/remnant/template/rendering.rb +42 -0
- data/lib/remnant/template/trace.rb +49 -0
- data/lib/remnant/template.rb +39 -0
- data/lib/remnant/version.rb +1 -1
- data/lib/remnant.rb +8 -0
- metadata +7 -2
data/lib/remnant/base.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
class Remnant
|
2
2
|
module ClassMethods
|
3
|
+
def color(default = false, heading = false)
|
4
|
+
return "\033[0m" if default
|
5
|
+
return "\033[0;01;33m" if heading
|
6
|
+
|
7
|
+
@current_color ||= "\033[0;01;36m"
|
8
|
+
@next_color ||= "\033[0;01;35m"
|
9
|
+
|
10
|
+
@current_color, @next_color = @next_color, @current_color
|
11
|
+
@current_color
|
12
|
+
end
|
13
|
+
|
3
14
|
def configure(&block)
|
4
15
|
configuration.instance_eval(&block)
|
5
16
|
end
|
@@ -37,7 +48,7 @@ class Remnant
|
|
37
48
|
end
|
38
49
|
else
|
39
50
|
# always log in development mode
|
40
|
-
Rails.logger.info "--------------Remnants Discovered
|
51
|
+
Rails.logger.info "#{color(false, true)}--------------Remnants Discovered--------------#{color(true)}"
|
41
52
|
|
42
53
|
Remnant::Discover.results.map do |remnant_key, ms|
|
43
54
|
key = [
|
@@ -45,10 +56,30 @@ class Remnant
|
|
45
56
|
remnant_key
|
46
57
|
].compact.join('.')
|
47
58
|
|
48
|
-
Rails.logger.info "#{ms.to_i}ms\t#{key}"
|
59
|
+
Rails.logger.info "#{Remnant.color}#{ms.to_i}ms#{Remnant.color(true)}\t#{key}"
|
60
|
+
end
|
61
|
+
|
62
|
+
if Remnant::Template.enabled?
|
63
|
+
Rails.logger.info ""
|
64
|
+
Rails.logger.info "#{color(false, true)}----- Templates -----#{color(true)}"
|
65
|
+
Remnant::Template.trace.root.children.map do |rendering|
|
66
|
+
Remnant::Template.trace.log(Rails.logger, rendering, 0)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if Remnant::Database.enabled?
|
71
|
+
Rails.logger.info ""
|
72
|
+
Rails.logger.info("#{color(false, true)}---- Database (%.2fms) -----#{color(true)}" % (Remnant::Database.queries.map(&:time).sum * 1000))
|
73
|
+
if Remnant::Database.suppress?
|
74
|
+
Rails.logger.info "queries suppressed in development mode"
|
75
|
+
else
|
76
|
+
Remnant::Database.queries.map do |query|
|
77
|
+
Rails.logger.info("#{color}%.2fms#{color(true)}\t#{query.sql}" % (query.time * 1000))
|
78
|
+
end
|
79
|
+
end
|
49
80
|
end
|
50
81
|
|
51
|
-
Rails.logger.info "
|
82
|
+
Rails.logger.info "#{color(false, true)}-----------------------------------------------#{color(true)}"
|
52
83
|
end
|
53
84
|
|
54
85
|
# run hook if given
|
@@ -56,6 +87,8 @@ class Remnant
|
|
56
87
|
Remnant.configuration.custom_hook.call(Remnant::Discover.results)
|
57
88
|
end
|
58
89
|
|
90
|
+
Remnant::Database.reset
|
91
|
+
Remnant::Template.reset
|
59
92
|
Remnant::Discover.results.clear
|
60
93
|
end
|
61
94
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Remnant
|
2
|
+
class Database
|
3
|
+
class Query
|
4
|
+
attr_reader :sql
|
5
|
+
attr_reader :time
|
6
|
+
attr_reader :backtrace
|
7
|
+
|
8
|
+
def initialize(sql, time, backtrace = [])
|
9
|
+
@sql = sql
|
10
|
+
@time = time
|
11
|
+
@backtrace = backtrace
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspectable?
|
15
|
+
sql.strip =~ /^SELECT /i
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Remnant
|
2
|
+
class Database
|
3
|
+
module ClassMethods
|
4
|
+
def disable!
|
5
|
+
@enabled = false
|
6
|
+
end
|
7
|
+
|
8
|
+
def enable!
|
9
|
+
@enabled = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def enabled?
|
13
|
+
@enabled
|
14
|
+
end
|
15
|
+
|
16
|
+
def unsuppress!
|
17
|
+
@suppress = false
|
18
|
+
end
|
19
|
+
|
20
|
+
def suppress?
|
21
|
+
@suppress || true
|
22
|
+
end
|
23
|
+
|
24
|
+
def record(sql, backtrace = [], &block)
|
25
|
+
return block.call unless Remnant::Database.enabled?
|
26
|
+
|
27
|
+
start_time = Time.now
|
28
|
+
result = block.call
|
29
|
+
queries << Remnant::Database::Query.new(sql, Time.now - start_time, backtrace)
|
30
|
+
|
31
|
+
return result
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset
|
35
|
+
@suppress = true
|
36
|
+
Thread.current['remnant.database.queries'] = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def queries
|
40
|
+
Thread.current['remnant.database.queries'] ||= []
|
41
|
+
end
|
42
|
+
|
43
|
+
def total_time
|
44
|
+
@total_time ||= (queries.inject(0) {|memo, query| memo + query.time}) * 1000
|
45
|
+
end
|
46
|
+
end
|
47
|
+
extend ClassMethods
|
48
|
+
end
|
49
|
+
end
|
data/lib/remnant/discover.rb
CHANGED
@@ -3,7 +3,10 @@ class Remnant
|
|
3
3
|
module ClassMethods
|
4
4
|
def find(key, klass, method, instance = true)
|
5
5
|
rediscover(key, klass, method, instance) if ActiveSupport::Dependencies.will_unload?(klass)
|
6
|
+
_inject(key, klass, method, instance)
|
7
|
+
end
|
6
8
|
|
9
|
+
def _inject(key, klass, method, instance)
|
7
10
|
klass.class_eval <<-EOL, __FILE__, __LINE__
|
8
11
|
#{"class << self" unless instance}
|
9
12
|
def #{method}_with_remnant(*args, &block)
|
@@ -17,6 +20,11 @@ class Remnant
|
|
17
20
|
EOL
|
18
21
|
end
|
19
22
|
|
23
|
+
def find_with(klass, &block)
|
24
|
+
rediscover(klass, block) if ActiveSupport::Dependencies.will_unload?(klass)
|
25
|
+
block.call
|
26
|
+
end
|
27
|
+
|
20
28
|
def measure(key, &block)
|
21
29
|
if Remnant::Discover.running.include?(key)
|
22
30
|
yield
|
@@ -51,8 +59,13 @@ class Remnant
|
|
51
59
|
end
|
52
60
|
|
53
61
|
def rediscover!
|
54
|
-
remnants_to_rediscover.map do |
|
55
|
-
|
62
|
+
remnants_to_rediscover.map do |remnant|
|
63
|
+
if remnant.size == 4
|
64
|
+
key, klass_name, method, instance = remnant
|
65
|
+
_inject(key, klass_name.constantize, method, instance)
|
66
|
+
else
|
67
|
+
remant.first.call
|
68
|
+
end
|
56
69
|
end
|
57
70
|
end
|
58
71
|
end
|
data/lib/remnant/rails.rb
CHANGED
@@ -38,6 +38,40 @@ class Remnant
|
|
38
38
|
Remnant::Discover.find('view', ActionController::Base, :render)
|
39
39
|
Remnant::Discover.find('filters', ActionController::Filters::AfterFilter, :call)
|
40
40
|
|
41
|
+
#
|
42
|
+
# Template rendering
|
43
|
+
#
|
44
|
+
if defined?(ActionView) && defined?(ActionView::Template)
|
45
|
+
Remnant::Discover.find_with(ActionView::Template) do
|
46
|
+
ActionView::Template.class_eval do
|
47
|
+
def render_template_with_remnant(*args, &block)
|
48
|
+
::Remnant::Template.record(path_without_format_and_extension) do
|
49
|
+
render_template_without_remnant(*args, &block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
alias_method_chain :render_template, :remnant
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# database query time
|
60
|
+
#
|
61
|
+
if ::Rails::VERSION::MAJOR == 2
|
62
|
+
Remnant::Discover.find_with(ActiveRecord::ConnectionAdapters::AbstractAdapter) do
|
63
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
|
64
|
+
def log_with_remnant(sql, name, &block)
|
65
|
+
::Remnant::Database.record(sql, Kernel.caller) do
|
66
|
+
log_without_remnant(sql, name, &block)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
alias_method_chain :log, :remnant
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
41
75
|
# last hook into request cycle for sending results
|
42
76
|
::ActionController::Dispatcher.class_eval do
|
43
77
|
def call_with_remnant_discovery(*args, &block) #:nodoc:
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Remnant
|
2
|
+
class Template
|
3
|
+
class Rendering
|
4
|
+
attr_accessor :name
|
5
|
+
attr_accessor :start_time
|
6
|
+
attr_accessor :end_time
|
7
|
+
attr_accessor :parent
|
8
|
+
attr_accessor :children
|
9
|
+
|
10
|
+
def initialize(name)
|
11
|
+
@name = name
|
12
|
+
@children = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add(rendering)
|
16
|
+
@children << rendering
|
17
|
+
rendering.parent = self
|
18
|
+
end
|
19
|
+
|
20
|
+
def time
|
21
|
+
@end_time - @start_time
|
22
|
+
end
|
23
|
+
|
24
|
+
def exclusive_time
|
25
|
+
time - child_time
|
26
|
+
end
|
27
|
+
|
28
|
+
def child_time
|
29
|
+
children.inject(0.0) {|memo, c| memo + c.time}
|
30
|
+
end
|
31
|
+
|
32
|
+
def results
|
33
|
+
@results ||= {name.to_s => {
|
34
|
+
'time' => time * 1000.0,
|
35
|
+
'exclusive' => exclusive_time * 1000.0,
|
36
|
+
'children' => children.map(&:results)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class Remnant
|
3
|
+
class Template
|
4
|
+
class Trace
|
5
|
+
def start(template_name)
|
6
|
+
rendering = Remnant::Template::Rendering.new(template_name)
|
7
|
+
rendering.start_time = Time.now
|
8
|
+
@current.add(rendering)
|
9
|
+
@current = rendering
|
10
|
+
end
|
11
|
+
|
12
|
+
def finished(template_name)
|
13
|
+
@current.end_time = Time.now
|
14
|
+
@current = @current.parent
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@current = root
|
19
|
+
end
|
20
|
+
|
21
|
+
def total_time
|
22
|
+
root.child_time
|
23
|
+
end
|
24
|
+
|
25
|
+
def root
|
26
|
+
@root ||= Remnant::Template::Rendering.new('root')
|
27
|
+
end
|
28
|
+
|
29
|
+
def log(logger, rendering, depth = 0)
|
30
|
+
rendering.results.map do |key, result|
|
31
|
+
|
32
|
+
#
|
33
|
+
line = Remnant.color
|
34
|
+
line += "#{' ' * depth}#{depth != 0 ? '└ ' : ''}"
|
35
|
+
line += "#{result['time'].to_i}ms (#{result['exclusive'].to_i}ms)"
|
36
|
+
line += Remnant.color(true)
|
37
|
+
line += ' ' * ((line.size >= 50 ? 10 : 50 - line.size) - (depth == 0 ? 2 : 0))
|
38
|
+
line += "#{key}"
|
39
|
+
|
40
|
+
logger.info line
|
41
|
+
|
42
|
+
rendering.children.map do |child|
|
43
|
+
log(logger, child, depth + 1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Remnant
|
2
|
+
class Template
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
def disable!
|
6
|
+
@enabled = false
|
7
|
+
end
|
8
|
+
|
9
|
+
def enable!
|
10
|
+
@enabled = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def enabled?
|
14
|
+
@enabled
|
15
|
+
end
|
16
|
+
|
17
|
+
def record(template)
|
18
|
+
return yield unless Remnant::Template.enabled?
|
19
|
+
|
20
|
+
trace.start(template)
|
21
|
+
begin
|
22
|
+
result = yield
|
23
|
+
ensure
|
24
|
+
trace.finished(template)
|
25
|
+
end
|
26
|
+
return result
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset
|
30
|
+
Thread.current['remnant.template.trace'] = Remnant::Template::Trace.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def trace
|
34
|
+
Thread.current['remnant.template.trace'] ||= Remnant::Template::Trace.new
|
35
|
+
end
|
36
|
+
end
|
37
|
+
extend ClassMethods
|
38
|
+
end
|
39
|
+
end
|
data/lib/remnant/version.rb
CHANGED
data/lib/remnant.rb
CHANGED
@@ -3,6 +3,14 @@ require 'statsd'
|
|
3
3
|
require 'remnant/base'
|
4
4
|
require 'remnant/configuration'
|
5
5
|
require 'remnant/discover'
|
6
|
+
|
7
|
+
require 'remnant/template'
|
8
|
+
require 'remnant/template/trace'
|
9
|
+
require 'remnant/template/rendering'
|
10
|
+
|
11
|
+
require 'remnant/database'
|
12
|
+
require 'remnant/database/query'
|
13
|
+
|
6
14
|
require 'remnant/rails'
|
7
15
|
require 'remnant/version'
|
8
16
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remnant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: statsd-ruby
|
@@ -140,9 +140,14 @@ files:
|
|
140
140
|
- lib/remnant.rb
|
141
141
|
- lib/remnant/base.rb
|
142
142
|
- lib/remnant/configuration.rb
|
143
|
+
- lib/remnant/database.rb
|
144
|
+
- lib/remnant/database/query.rb
|
143
145
|
- lib/remnant/discover.rb
|
144
146
|
- lib/remnant/rails.rb
|
145
147
|
- lib/remnant/railtie.rb
|
148
|
+
- lib/remnant/template.rb
|
149
|
+
- lib/remnant/template/rendering.rb
|
150
|
+
- lib/remnant/template/trace.rb
|
146
151
|
- lib/remnant/version.rb
|
147
152
|
- remnant.gemspec
|
148
153
|
- spec/app/some/klass.rb
|