rails_metrics 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +3 -0
- data/Gemfile +9 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +58 -0
- data/Rakefile +58 -0
- data/TODO.rdoc +1 -0
- data/app/controllers/rails_metrics_controller.rb +78 -0
- data/app/helpers/rails_metrics_helper.rb +161 -0
- data/app/views/layouts/rails_metrics.html.erb +21 -0
- data/app/views/rails_metrics/_request.html.erb +21 -0
- data/app/views/rails_metrics/_row.html.erb +23 -0
- data/app/views/rails_metrics/all.html.erb +25 -0
- data/app/views/rails_metrics/chart.html.erb +49 -0
- data/app/views/rails_metrics/index.html.erb +21 -0
- data/app/views/rails_metrics/show.html.erb +41 -0
- data/config/routes.rb +7 -0
- data/lib/generators/rails_metrics_generator.rb +40 -0
- data/lib/rails_metrics.rb +112 -0
- data/lib/rails_metrics/async_consumer.rb +54 -0
- data/lib/rails_metrics/engine.rb +29 -0
- data/lib/rails_metrics/middleware.rb +27 -0
- data/lib/rails_metrics/orm/active_record.rb +66 -0
- data/lib/rails_metrics/payload_parser.rb +131 -0
- data/lib/rails_metrics/store.rb +132 -0
- data/lib/rails_metrics/version.rb +3 -0
- data/public/images/rails_metrics/arrow_down.png +0 -0
- data/public/images/rails_metrics/arrow_up.png +0 -0
- data/public/images/rails_metrics/cancel.png +0 -0
- data/public/images/rails_metrics/chart_pie.png +0 -0
- data/public/images/rails_metrics/page_white_delete.png +0 -0
- data/public/images/rails_metrics/page_white_go.png +0 -0
- data/public/images/rails_metrics/tick.png +0 -0
- data/public/javascripts/rails_metrics/g.pie-min.js +6 -0
- data/public/javascripts/rails_metrics/g.raphael-min.js +5 -0
- data/public/javascripts/rails_metrics/raphael-min.js +5 -0
- data/public/stylesheets/rails_metrics.css +135 -0
- data/test/dummy/app/controllers/application_controller.rb +4 -0
- data/test/dummy/app/controllers/users_controller.rb +43 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/metric.rb +3 -0
- data/test/dummy/app/models/notification.rb +7 -0
- data/test/dummy/app/models/user.rb +2 -0
- data/test/dummy/config/application.rb +52 -0
- data/test/dummy/config/boot.rb +9 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +19 -0
- data/test/dummy/config/environments/production.rb +33 -0
- data/test/dummy/config/environments/test.rb +29 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookie_verification_secret.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +15 -0
- data/test/dummy/config/routes.rb +60 -0
- data/test/dummy/db/migrate/20100106152343_create_metrics.rb +17 -0
- data/test/dummy/db/migrate/20100108120821_create_users.rb +13 -0
- data/test/integration/instrumentation_test.rb +100 -0
- data/test/integration/navigation_test.rb +103 -0
- data/test/orm/active_record_test.rb +51 -0
- data/test/payload_parser_test.rb +36 -0
- data/test/rails_metrics_test.rb +43 -0
- data/test/store_test.rb +81 -0
- data/test/support/helpers.rb +16 -0
- data/test/support/instrumentation.rb +18 -0
- data/test/support/mock_store.rb +34 -0
- data/test/support/webrat/integrations/rails.rb +31 -0
- data/test/test_helper.rb +32 -0
- metadata +118 -0
data/CHANGELOG.rdoc
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2010 Engine Yard. http://www.engineyard.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
== RailsMetrics
|
2
|
+
|
3
|
+
RailsMetrics is an engine that hooks into your application to listen ActiveSupport::Notifications and show you statistics about them. RailsMetrics uses threads to save those notifications in the database through an in-process Queue. You can see charts based on each request and see what queries, actions, templates rendering, etc. are slow.
|
4
|
+
|
5
|
+
So far RailsMetrics supports only ActiveRecord as ORM but adding other datastore should be easy (take a look at lib/rails_metrics/orm/active_record.rb). Due to the threaded behavior in RailsMetrics, you cannot use SQLite as database, however MySQL and PostgreSQL work fine.
|
6
|
+
|
7
|
+
There's an example application at http://github.com/engineyard/rails_metrics_example .
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
Installing RailsMetrics is simple. Since it's a Rails::Engine, you need to install it as gem:
|
12
|
+
|
13
|
+
gem install rails_metrics
|
14
|
+
|
15
|
+
Then add it to your gemfile. So far, I recommend you to install it only on development:
|
16
|
+
|
17
|
+
group :development do
|
18
|
+
gem "rails_metrics"
|
19
|
+
end
|
20
|
+
|
21
|
+
Finally, create your model using the built-in generator:
|
22
|
+
|
23
|
+
rails g rails_metrics Metric
|
24
|
+
|
25
|
+
You can choose another name than Metric as your rails metrics store. Run the created migration, restart your server and now you should be able to access "/rails_metrics". Navigate on your application and head back to "/rails_metrics" to see the stored data.
|
26
|
+
|
27
|
+
== Configuration
|
28
|
+
|
29
|
+
There are three parameters you can add to your application to configure RailsMetrics. The first one is to set the RailsMetrics store, which is done automatically when you use the generator:
|
30
|
+
|
31
|
+
config.rails_metrics.set_store = lambda { ::Metric }
|
32
|
+
|
33
|
+
The other parameters allows you to ignore an specific notification, based on a given block
|
34
|
+
or on its name. Let's suppose you have a plugin in your application which is yielding an useless notification. You can silence it by doing:
|
35
|
+
|
36
|
+
config.rails_metrics.ignore_patterns << /verbose_plugin/
|
37
|
+
|
38
|
+
If you need to ignore a notification based on its payload, it's also easy:
|
39
|
+
|
40
|
+
config.rails_metrics.ignore_lambdas[:verbose_plugin] = lambda { |name, payload|
|
41
|
+
payload[:some_value] =~ /some_expression/
|
42
|
+
}
|
43
|
+
|
44
|
+
== TODO
|
45
|
+
|
46
|
+
Please refer to TODO file.
|
47
|
+
|
48
|
+
== Maintainers
|
49
|
+
|
50
|
+
* José Valim (http://github.com/josevalim)
|
51
|
+
|
52
|
+
== Bugs and Feedback
|
53
|
+
|
54
|
+
If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.
|
55
|
+
|
56
|
+
http://github.com/engineyard/rails_metrics/issues
|
57
|
+
|
58
|
+
MIT License. Copyright 2010 Engine Yard. http://www.engineyard.com
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require "rake"
|
4
|
+
require "rake/testtask"
|
5
|
+
require "rake/rdoctask"
|
6
|
+
require "fileutils"
|
7
|
+
require File.expand_path("../lib/rails_metrics/version", __FILE__)
|
8
|
+
|
9
|
+
desc "Default: run unit tests"
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
desc "Prepare environment for tests"
|
13
|
+
task :prepare do
|
14
|
+
FileUtils.cd File.expand_path("../test/dummy", __FILE__)
|
15
|
+
system("rake db:create:all")
|
16
|
+
system("rake db:migrate")
|
17
|
+
system("rake db:test:clone")
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Start the server for the dummy application used in tests"
|
21
|
+
task :server do
|
22
|
+
exec("test/dummy/script/rails server")
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Test RailsMetrics"
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << "test"
|
28
|
+
t.pattern = "test/**/*_test.rb"
|
29
|
+
t.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Generate documentation for RailsMetrics"
|
33
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
34
|
+
rdoc.rdoc_dir = "rdoc"
|
35
|
+
rdoc.title = "RailsMetrics"
|
36
|
+
rdoc.options << "--line-numbers" << "--inline-source"
|
37
|
+
rdoc.rdoc_files.include("README.rdoc")
|
38
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
39
|
+
end
|
40
|
+
|
41
|
+
begin
|
42
|
+
require "jeweler"
|
43
|
+
Jeweler::Tasks.new do |s|
|
44
|
+
s.name = "rails_metrics"
|
45
|
+
s.version = RailsMetrics::VERSION
|
46
|
+
s.summary = "Metrics measurement for your app on top of ActiveSupport::Notifications"
|
47
|
+
s.email = "contact@engineyard.com"
|
48
|
+
s.homepage = "http://github.com/engineyard"
|
49
|
+
s.description = "Metrics measurement for your app on top of ActiveSupport::Notifications"
|
50
|
+
s.authors = ["José Valim"]
|
51
|
+
s.files = FileList["[A-Z]*", "{app,config,lib,public}/**/*"]
|
52
|
+
s.files.exclude("public/javascripts/rails_metrics.js")
|
53
|
+
end
|
54
|
+
|
55
|
+
Jeweler::GemcutterTasks.new
|
56
|
+
rescue LoadError
|
57
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
|
58
|
+
end
|
data/TODO.rdoc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* Allow to set the maximum number of requests to store
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class RailsMetricsController < ApplicationController
|
2
|
+
respond_to :html
|
3
|
+
|
4
|
+
# GET /rails_metrics
|
5
|
+
def index
|
6
|
+
@metrics = order_scopes(RailsMetrics.store.requests)
|
7
|
+
@metrics_count = @metrics.count
|
8
|
+
@metrics = with_pagination(@metrics)
|
9
|
+
respond_with(@metrics)
|
10
|
+
end
|
11
|
+
|
12
|
+
# GET /rails_metrics/1/chart
|
13
|
+
def chart
|
14
|
+
@metrics = RailsMetrics.store.earliest.by_request_id(params[:id]).all
|
15
|
+
@request = RailsMetrics.store.mount_tree(@metrics.reverse)
|
16
|
+
respond_with(@metrics)
|
17
|
+
end
|
18
|
+
|
19
|
+
# GET /rails_metrics
|
20
|
+
def all
|
21
|
+
@metrics = all_scopes(RailsMetrics.store)
|
22
|
+
@metrics_count = @metrics.count
|
23
|
+
@metrics = with_pagination(@metrics)
|
24
|
+
respond_with(@metrics)
|
25
|
+
end
|
26
|
+
|
27
|
+
# GET /rails_metrics/1
|
28
|
+
def show
|
29
|
+
@metric = find_store(params[:id])
|
30
|
+
respond_with(@metric)
|
31
|
+
end
|
32
|
+
|
33
|
+
# DELETE /rails_metrics/1
|
34
|
+
def destroy
|
35
|
+
@metric = find_store(params[:id])
|
36
|
+
@metric.destroy
|
37
|
+
flash[:notice] = "Metric ##{@metric.id} was deleted with success."
|
38
|
+
respond_with(@metric, :location => rails_metrics_path)
|
39
|
+
end
|
40
|
+
|
41
|
+
# DELETE /rails_metrics/destroy_all
|
42
|
+
def destroy_all
|
43
|
+
count = all_scopes(RailsMetrics.store).delete_all
|
44
|
+
flash[:notice] = "All #{count} selected metrics were deleted."
|
45
|
+
redirect_to rails_metrics_path
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def with_pagination(scope)
|
51
|
+
@limit = (params[:limit].presence || 50).to_i
|
52
|
+
@offset = (params[:offset].presence || 0).to_i
|
53
|
+
scope.limit(@limit).offset(@offset).all
|
54
|
+
end
|
55
|
+
|
56
|
+
def by_scopes(store)
|
57
|
+
@by_name = params[:by_name].presence
|
58
|
+
store = store.by_name(@by_name) if @by_name
|
59
|
+
store
|
60
|
+
end
|
61
|
+
|
62
|
+
def order_scopes(store)
|
63
|
+
@order_by = (valid_order_by? ? params[:order_by] : :latest).to_sym
|
64
|
+
store = store.send(@order_by)
|
65
|
+
end
|
66
|
+
|
67
|
+
def all_scopes(store)
|
68
|
+
order_scopes(by_scopes(store))
|
69
|
+
end
|
70
|
+
|
71
|
+
def valid_order_by?
|
72
|
+
RailsMetrics::Store::VALID_ORDERS.include?(params[:order_by])
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_store(id)
|
76
|
+
RailsMetrics.store.find(id)
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module RailsMetricsHelper
|
2
|
+
module Pagination
|
3
|
+
# Returns information about pagination
|
4
|
+
def pagination_info
|
5
|
+
maximum = [@metrics_count, @offset + @limit].min
|
6
|
+
"#{@offset + 1} - #{maximum} of #{@metrics_count}"
|
7
|
+
end
|
8
|
+
|
9
|
+
# Shows per page links
|
10
|
+
def show_per_page(values)
|
11
|
+
values.map do |i|
|
12
|
+
link_to_unless(@limit == i, i.to_s, url_for(params.merge(:limit => i)))
|
13
|
+
end.join(" | ").html_safe
|
14
|
+
end
|
15
|
+
|
16
|
+
# Shows previous link for pagination
|
17
|
+
def previous_link
|
18
|
+
link = url_for(params.merge(:offset => [0, @offset - @limit].max))
|
19
|
+
link_to_if(@offset > 0, "Previous", link)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Show next link for pagination
|
23
|
+
def next_link
|
24
|
+
link = url_for(params.merge(:offset => @offset + @limit))
|
25
|
+
link_to_if(@offset + @limit < @metrics_count, "Next", link)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Add pagination to footlinks
|
29
|
+
def paginate!
|
30
|
+
content_for :rails_metrics_footlinks do
|
31
|
+
content_tag(:p, [previous_link, pagination_info, next_link].join(" | ")) <<
|
32
|
+
content_tag(:p, "Show per page: #{show_per_page [10, 25, 50, 100]}")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module PayloadInspect
|
38
|
+
# Inspect payload to show more human readable information.
|
39
|
+
def payload_inspect(hash)
|
40
|
+
hash = hash.sort {|a,b| a[0].to_s <=> b[0].to_s }
|
41
|
+
content = []
|
42
|
+
|
43
|
+
hash.each do |key, value|
|
44
|
+
content << (content_tag(:b, key.to_s.humanize).safe_concat("<br />") << pretty_inspect(value))
|
45
|
+
end
|
46
|
+
|
47
|
+
content.map!{ |c| content_tag(:p, c) }
|
48
|
+
content.join("\n").html_safe
|
49
|
+
end
|
50
|
+
|
51
|
+
# Inspect a value using a more readable format.
|
52
|
+
def pretty_inspect(object)
|
53
|
+
case object
|
54
|
+
when String
|
55
|
+
object
|
56
|
+
when Array
|
57
|
+
"[#{object.map(&:inspect).join(", ")}]"
|
58
|
+
when Hash
|
59
|
+
hash = object.map { |k,v| " #{k.inspect} => #{pretty_inspect(v)}" }.join(",\n")
|
60
|
+
if object.size == 1
|
61
|
+
"{ #{hash[2..-1]} }"
|
62
|
+
else
|
63
|
+
"{\n#{hash}\n}"
|
64
|
+
end
|
65
|
+
else
|
66
|
+
object.inspect
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module Scoping
|
72
|
+
# Returns information about scope
|
73
|
+
def scopes_info
|
74
|
+
filters = []
|
75
|
+
filters << "name" if @by_name
|
76
|
+
filters.map!{ |i| content_tag(:b, i) }
|
77
|
+
|
78
|
+
content = []
|
79
|
+
content << "filtered by #{filters.to_sentence}" unless filters.empty?
|
80
|
+
content << "ordered by <b>#{@order_by.to_s.humanize.downcase}</b>"
|
81
|
+
content.to_sentence.html_safe
|
82
|
+
end
|
83
|
+
|
84
|
+
# Link to set a by_scope using the given content. If no value is given,
|
85
|
+
# the content is used as link value as well.
|
86
|
+
def link_to_set_by_scope(metric, what)
|
87
|
+
value = metric.send(what)
|
88
|
+
return value if instance_variable_get(:"@by_#{what}")
|
89
|
+
link_to value, url_for_scope(:"by_#{what}" => value, :action => "all"), :title => value
|
90
|
+
end
|
91
|
+
|
92
|
+
# Link to clear a by_scope using a cancel image.
|
93
|
+
def link_to_clear_by_scope(what)
|
94
|
+
return unless instance_variable_get(:"@by_#{what}")
|
95
|
+
link_to_set_scope_with_image("rails_metrics/cancel.png",
|
96
|
+
"Remove #{what.to_s.humanize.inspect} filter", :"by_#{what}" => nil)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Link to order by scopes by using two arrows, one up and other down
|
100
|
+
def link_to_order_by_scopes(up, down)
|
101
|
+
link_to_set_scope_with_image("rails_metrics/arrow_up.png", "Order by #{up}", :order_by => up) <<
|
102
|
+
link_to_set_scope_with_image("rails_metrics/arrow_down.png", "Order by #{down}", :order_by => down)
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
|
107
|
+
def url_for_scope(hash) #:nodoc:
|
108
|
+
url_for(params.except(:limit, :offset, :id).merge!(hash))
|
109
|
+
end
|
110
|
+
|
111
|
+
def link_to_set_scope_with_image(src, title, scope) #:nodoc:
|
112
|
+
image = image_tag(src, :title => title, :alt => title)
|
113
|
+
link = url_for_scope(scope)
|
114
|
+
link_to image, link, :title => title
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module Links
|
119
|
+
# Links to image inside rails_metrics if the given path it's not the current page using the given title.
|
120
|
+
def link_to_image_unless_current(icon, path, title)
|
121
|
+
return if current_page?(path)
|
122
|
+
image = image_tag("rails_metrics/#{icon}.png", :title => title, :alt => title)
|
123
|
+
link_to image, path, :title => title
|
124
|
+
end
|
125
|
+
|
126
|
+
# Add action icons to the current page.
|
127
|
+
def add_action_links!(metric)
|
128
|
+
concat link_to_image_unless_current(:chart_pie, chart_rails_metric_path(metric.request_id), "Chart")
|
129
|
+
concat link_to_image_unless_current(:page_white_go, rails_metric_path(metric), "Show")
|
130
|
+
form_tag(rails_metric_path(metric), :method => :delete) do
|
131
|
+
image_submit_tag "rails_metrics/page_white_delete.png", :onclick => "return confirm('Are you sure?')", :alt => "Delete", :title => "Delete"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def nagivation_links
|
136
|
+
@navigation_links ||= begin
|
137
|
+
links = []
|
138
|
+
links << link_to("All metrics", all_rails_metrics_path)
|
139
|
+
links << link_to("Requests", rails_metrics_path)
|
140
|
+
links << link_to("Back", :back)
|
141
|
+
links.join(" | ").html_safe
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
include Pagination
|
147
|
+
include PayloadInspect
|
148
|
+
include Scoping
|
149
|
+
include Links
|
150
|
+
|
151
|
+
# Returns pagination and scopes information
|
152
|
+
def pagination_and_scopes_info(countable)
|
153
|
+
countable = countable.to_s.pluralize unless @metrics_count == 1
|
154
|
+
"Showing #{pagination_info} #{countable} ".html_safe << scopes_info
|
155
|
+
end
|
156
|
+
|
157
|
+
# Create a table row using rails_metrics_#{id} as row id and odd and even as classes.
|
158
|
+
def rails_metrics_table_row_for(metric, &block)
|
159
|
+
content_tag(:tr, :id => "rails_metric_#{metric.id}", :class => cycle("odd", "even"), &block)
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>RailsMetrics: <%= controller.action_name %></title>
|
5
|
+
<%= stylesheet_link_tag 'rails_metrics' %>
|
6
|
+
<%= javascript_include_tag 'rails_metrics/raphael-min', 'rails_metrics/g.raphael-min', 'rails_metrics/g.pie-min', :cache => "rails_metrics" %>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<%= content_tag(:div, content_tag(:p, notice), :class => :notice) if notice.present? %>
|
10
|
+
<div id="rails_metrics_header">
|
11
|
+
<h1><%= link_to "RailsMetrics", rails_metrics_path %></h1>
|
12
|
+
<div><%= yield :rails_metrics_header %></div>
|
13
|
+
<p><%= nagivation_links %></p>
|
14
|
+
</div>
|
15
|
+
<%= yield %>
|
16
|
+
<div id="rails_metrics_footlinks">
|
17
|
+
<%= yield :rails_metrics_footlinks %>
|
18
|
+
<p><%= nagivation_links %></p>
|
19
|
+
</div>
|
20
|
+
</body>
|
21
|
+
</html>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<% rails_metrics_table_row_for metric do %>
|
2
|
+
<td class="when">
|
3
|
+
<%= metric.started_at.strftime("%d %b %H:%M:%S") %>
|
4
|
+
</td>
|
5
|
+
|
6
|
+
<td class="method">
|
7
|
+
<%= metric.payload[:method] %>
|
8
|
+
</td>
|
9
|
+
|
10
|
+
<td class="path">
|
11
|
+
<%= metric.payload[:path] %>
|
12
|
+
</td>
|
13
|
+
|
14
|
+
<td class="duration">
|
15
|
+
<%= "%.1f" % metric.duration_in_ms %> ms
|
16
|
+
</td>
|
17
|
+
|
18
|
+
<td class="actions">
|
19
|
+
<% add_action_links!(metric) %>
|
20
|
+
</td>
|
21
|
+
<% end %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<% rails_metrics_table_row_for metric do %>
|
2
|
+
<% unless (skip_timestamps ||= false) %>
|
3
|
+
<td class="started_at">
|
4
|
+
<%= metric.started_at.strftime("%d %b %H:%M:%S") %>
|
5
|
+
</td>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<td class="name">
|
9
|
+
<%= link_to_set_by_scope metric, :name %>
|
10
|
+
</td>
|
11
|
+
|
12
|
+
<td class="duration">
|
13
|
+
<%= "%.1f" % metric.duration_in_ms %> <%= "(#{"%.1f" % metric.exclusive_duration_in_ms})" if metric.children.any? %> ms
|
14
|
+
</td>
|
15
|
+
|
16
|
+
<td class="payload">
|
17
|
+
<%= payload_inspect(metric.payload) %>
|
18
|
+
</td>
|
19
|
+
|
20
|
+
<td class="actions">
|
21
|
+
<% add_action_links!(metric) %>
|
22
|
+
</td>
|
23
|
+
<% end %>
|