marginalia 1.1.5 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of marginalia might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +14 -3
- data/Gemfile +5 -0
- data/README.md +10 -7
- data/lib/marginalia.rb +0 -1
- data/lib/marginalia/comment.rb +13 -3
- data/lib/marginalia/railtie.rb +13 -17
- data/marginalia.gemspec +1 -1
- data/test/query_comments_test.rb +93 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5352b63598e762229b9f6a9a7b4b0b27dc42a277
|
4
|
+
data.tar.gz: d45c0855bf418e0dd277e553b5fe45d47b6d3a57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7895a8c8318f85bfb18aa2ba90f8223eaacd54b190d6adc45aff3f139c3ed6a494858c644095b2edcf608f42f9d0c5e4c48bbf432ac0a1c523b7d3c411e2ce1f
|
7
|
+
data.tar.gz: 8e5493b2233a05245de9f6c4b1d346b08cbe3dd6de0021e037a73e1cea35da8599469198802c459306bbd0168974ebc210d1cf8d62f88d48a61e9df7bfa1ed33
|
data/.travis.yml
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
language: ruby
|
2
|
+
|
2
3
|
rvm:
|
3
4
|
- 1.9.3
|
4
5
|
- 2.0.0
|
5
|
-
- 2.1
|
6
|
+
- 2.1
|
7
|
+
|
8
|
+
sudo: false
|
9
|
+
|
6
10
|
script: bundle exec rake db:reset test:all
|
11
|
+
|
7
12
|
env:
|
8
13
|
- "RAILS_VERSION=3.1.12"
|
9
|
-
- "RAILS_VERSION=3.2.
|
10
|
-
- "RAILS_VERSION=4.0.
|
14
|
+
- "RAILS_VERSION=3.2.19"
|
15
|
+
- "RAILS_VERSION=4.0.8"
|
16
|
+
- "RAILS_VERSION=4.1.8"
|
17
|
+
- "RAILS_VERSION=4.2.0"
|
18
|
+
- "RAILS_VERSION=3.2.19 TEST_RAILS_API=true"
|
19
|
+
- "RAILS_VERSION=4.0.8 TEST_RAILS_API=true"
|
20
|
+
- "RAILS_VERSION=4.1.8 TEST_RAILS_API=true"
|
21
|
+
- "RAILS_VERSION=4.2.0 TEST_RAILS_API=true"
|
data/Gemfile
CHANGED
@@ -3,6 +3,7 @@ source "https://rubygems.org"
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
version = ENV["RAILS_VERSION"] || "4.0.2"
|
6
|
+
rails_api = ENV["TEST_RAILS_API"] == "true"
|
6
7
|
|
7
8
|
rails = case version
|
8
9
|
when "master"
|
@@ -12,3 +13,7 @@ else
|
|
12
13
|
end
|
13
14
|
|
14
15
|
gem "rails", rails
|
16
|
+
|
17
|
+
if rails_api
|
18
|
+
gem "rails-api", "~> 0.2.1"
|
19
|
+
end
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# marginalia [![Build Status](https://
|
1
|
+
# marginalia [![Build Status](https://travis-ci.org/basecamp/marginalia.svg?branch=master)](https://travis-ci.org/basecamp/marginalia)
|
2
2
|
|
3
3
|
Attach comments to your ActiveRecord queries. By default, it adds the application, controller, and action names as a
|
4
4
|
comment at the end of each query.
|
@@ -13,24 +13,24 @@ For example, once enabled, your logs will look like:
|
|
13
13
|
/*application:BCX,controller:project_imports,action:show*/
|
14
14
|
|
15
15
|
You can also use these query comments along with a tool like [pt-query-digest](http://www.percona.com/doc/percona-toolkit/2.1/pt-query-digest.html#query-reviews)
|
16
|
-
to automate identification of controllers and actions that are hotspots
|
16
|
+
to automate identification of controllers and actions that are hotspots for slow queries.
|
17
17
|
|
18
18
|
This gem was created at 37signals. You can read more about how we use it [on
|
19
19
|
our blog](http://37signals.com/svn/posts/3130-tech-note-mysql-query-comments-in-rails).
|
20
20
|
|
21
21
|
This has been tested and used in production with both the mysql and mysql2 gems,
|
22
|
-
tested on Rails 2.3.5 through
|
22
|
+
tested on Rails 2.3.5 through 4.1.x. It has also been tested for sqlite3 and postgres.
|
23
23
|
|
24
24
|
Patches are welcome for other database adapters.
|
25
25
|
|
26
26
|
## Installation
|
27
27
|
|
28
|
-
### For Rails 3.x:
|
28
|
+
### For Rails 3.x and 4.x:
|
29
29
|
|
30
30
|
# Gemfile
|
31
31
|
gem 'marginalia'
|
32
32
|
|
33
|
-
#config/application.rb
|
33
|
+
# config/application.rb
|
34
34
|
require 'marginalia/railtie'
|
35
35
|
|
36
36
|
|
@@ -91,6 +91,8 @@ default. In addition, implementation is provided for:
|
|
91
91
|
* `:line` (for file and line number calling query). :line supports
|
92
92
|
a configuration by setting a regexp in `Marginalia::Comment.lines_to_ignore`
|
93
93
|
to exclude parts of the stacktrace from inclusion in the line comment.
|
94
|
+
* `:controller_with_namespace` to include the full classname (including namespace)
|
95
|
+
of the controller.
|
94
96
|
|
95
97
|
Pull requests for other included comment components are welcome.
|
96
98
|
|
@@ -99,9 +101,10 @@ Pull requests for other included comment components are welcome.
|
|
99
101
|
Start by bundling and creating the test database:
|
100
102
|
|
101
103
|
bundle
|
102
|
-
rake db:create
|
104
|
+
rake db:mysql:create
|
105
|
+
rake db:postgresql:create
|
103
106
|
|
104
|
-
Then, running `rake` will run the tests on
|
107
|
+
Then, running `rake` will run the tests on all the database adapters (`mysql`, `mysql2`, `postgresql` and `sqlite`):
|
105
108
|
|
106
109
|
rake
|
107
110
|
|
data/lib/marginalia.rb
CHANGED
@@ -6,7 +6,6 @@ module Marginalia
|
|
6
6
|
|
7
7
|
module ActiveRecordInstrumentation
|
8
8
|
def self.included(instrumented_class)
|
9
|
-
Marginalia::Comment.components = [:application, :controller, :action]
|
10
9
|
instrumented_class.class_eval do
|
11
10
|
if instrumented_class.method_defined?(:execute)
|
12
11
|
alias_method :execute_without_marginalia, :execute
|
data/lib/marginalia/comment.rb
CHANGED
@@ -3,6 +3,7 @@ require 'socket'
|
|
3
3
|
module Marginalia
|
4
4
|
module Comment
|
5
5
|
mattr_accessor :components, :lines_to_ignore
|
6
|
+
Marginalia::Comment.components ||= [:application, :controller, :action]
|
6
7
|
|
7
8
|
def self.update!(controller = nil)
|
8
9
|
@controller = controller
|
@@ -13,10 +14,10 @@ module Marginalia
|
|
13
14
|
self.components.each do |c|
|
14
15
|
component_value = self.send(c)
|
15
16
|
if component_value.present?
|
16
|
-
ret <<
|
17
|
-
ret << c.to_s << ':' << component_value.to_s
|
17
|
+
ret << "#{c.to_s}:#{component_value.to_s},"
|
18
18
|
end
|
19
19
|
end
|
20
|
+
ret.chop!
|
20
21
|
ret
|
21
22
|
end
|
22
23
|
|
@@ -26,7 +27,7 @@ module Marginalia
|
|
26
27
|
|
27
28
|
private
|
28
29
|
def self.application
|
29
|
-
if defined?
|
30
|
+
if defined?(Rails.application)
|
30
31
|
Marginalia.application_name ||= Rails.application.class.name.split("::").first
|
31
32
|
else
|
32
33
|
Marginalia.application_name ||= "rails"
|
@@ -39,6 +40,10 @@ module Marginalia
|
|
39
40
|
@controller.controller_name if @controller.respond_to? :controller_name
|
40
41
|
end
|
41
42
|
|
43
|
+
def self.controller_with_namespace
|
44
|
+
@controller.class.name if @controller
|
45
|
+
end
|
46
|
+
|
42
47
|
def self.action
|
43
48
|
@controller.action_name if @controller.respond_to? :action_name
|
44
49
|
end
|
@@ -71,6 +76,11 @@ module Marginalia
|
|
71
76
|
Process.pid
|
72
77
|
end
|
73
78
|
|
79
|
+
def self.request_id
|
80
|
+
if @controller.respond_to?(:request) && @controller.request.respond_to?(:uuid)
|
81
|
+
@controller.request.uuid
|
82
|
+
end
|
83
|
+
end
|
74
84
|
end
|
75
85
|
|
76
86
|
end
|
data/lib/marginalia/railtie.rb
CHANGED
@@ -24,7 +24,7 @@ module Marginalia
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.insert_into_action_controller
|
27
|
-
|
27
|
+
controller_instrumentation = <<-EOS
|
28
28
|
def record_query_comment
|
29
29
|
Marginalia::Comment.update!(self)
|
30
30
|
yield
|
@@ -32,40 +32,36 @@ module Marginalia
|
|
32
32
|
Marginalia::Comment.clear!
|
33
33
|
end
|
34
34
|
around_filter :record_query_comment
|
35
|
+
EOS
|
36
|
+
ActionController::Base.class_eval(controller_instrumentation)
|
37
|
+
if defined? ActionController::API
|
38
|
+
ActionController::API.class_eval(controller_instrumentation)
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
38
42
|
def self.insert_into_active_record
|
39
43
|
if defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
40
|
-
|
41
|
-
|
42
|
-
include Marginalia::ActiveRecordInstrumentation
|
43
|
-
end
|
44
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.module_eval do
|
45
|
+
include Marginalia::ActiveRecordInstrumentation
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
47
49
|
if defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
|
48
|
-
|
49
|
-
|
50
|
-
include Marginalia::ActiveRecordInstrumentation
|
51
|
-
end
|
50
|
+
ActiveRecord::ConnectionAdapters::MysqlAdapter.module_eval do
|
51
|
+
include Marginalia::ActiveRecordInstrumentation
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
55
|
# SQL queries made through PostgreSQLAdapter#exec_delete will not be annotated.
|
56
56
|
if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
|
57
|
-
|
58
|
-
|
59
|
-
include Marginalia::ActiveRecordInstrumentation
|
60
|
-
end
|
57
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.module_eval do
|
58
|
+
include Marginalia::ActiveRecordInstrumentation
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
64
62
|
if defined? ActiveRecord::ConnectionAdapters::SQLite3Adapter
|
65
|
-
|
66
|
-
|
67
|
-
include Marginalia::ActiveRecordInstrumentation
|
68
|
-
end
|
63
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.module_eval do
|
64
|
+
include Marginalia::ActiveRecordInstrumentation
|
69
65
|
end
|
70
66
|
end
|
71
67
|
end
|
data/marginalia.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.test_files = `git ls-files -- {test}/*`.split("\n")
|
9
9
|
gem.name = "marginalia"
|
10
10
|
gem.require_paths = ["lib"]
|
11
|
-
gem.version = "1.
|
11
|
+
gem.version = "1.2.0"
|
12
12
|
gem.license = "MIT"
|
13
13
|
|
14
14
|
gem.add_runtime_dependency "actionpack", ">= 2.3"
|
data/test/query_comments_test.rb
CHANGED
@@ -1,10 +1,41 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
require '
|
2
|
+
require 'rails/version'
|
3
|
+
|
4
|
+
def using_rails_api?
|
5
|
+
ENV["TEST_RAILS_API"] == true
|
6
|
+
end
|
7
|
+
|
8
|
+
def request_id_available?
|
9
|
+
Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('3.2')
|
10
|
+
end
|
11
|
+
|
12
|
+
require "minitest/autorun"
|
3
13
|
require 'mocha/test_unit'
|
4
14
|
require 'logger'
|
5
15
|
require 'pp'
|
6
16
|
require 'active_record'
|
7
17
|
require 'action_controller'
|
18
|
+
|
19
|
+
if request_id_available?
|
20
|
+
require 'action_dispatch/middleware/request_id'
|
21
|
+
end
|
22
|
+
|
23
|
+
if using_rails_api?
|
24
|
+
require 'rails-api/action_controller/api'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Shim for compatibility with older versions of MiniTest
|
28
|
+
MiniTest::Test = MiniTest::Unit::TestCase unless defined?(MiniTest::Test)
|
29
|
+
|
30
|
+
# From version 4.1, ActiveRecord expects `Rails.env` to be
|
31
|
+
# defined if `Rails` is defined
|
32
|
+
if defined?(Rails) && !defined?(Rails.env)
|
33
|
+
module Rails
|
34
|
+
def self.env
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
8
39
|
require 'marginalia'
|
9
40
|
RAILS_ROOT = File.expand_path(File.dirname(__FILE__))
|
10
41
|
|
@@ -25,6 +56,22 @@ class PostsController < ActionController::Base
|
|
25
56
|
end
|
26
57
|
end
|
27
58
|
|
59
|
+
module API
|
60
|
+
module V1
|
61
|
+
class PostsController < ::PostsController
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if using_rails_api?
|
67
|
+
class PostsApiController < ActionController::API
|
68
|
+
def driver_only
|
69
|
+
ActiveRecord::Base.connection.execute "select id from posts"
|
70
|
+
head :no_content
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
28
75
|
unless Post.table_exists?
|
29
76
|
ActiveRecord::Schema.define do
|
30
77
|
create_table "posts", :force => true do |t|
|
@@ -34,7 +81,8 @@ end
|
|
34
81
|
|
35
82
|
Marginalia::Railtie.insert
|
36
83
|
|
37
|
-
|
84
|
+
|
85
|
+
class MarginaliaTest < MiniTest::Test
|
38
86
|
def setup
|
39
87
|
@queries = []
|
40
88
|
ActiveSupport::Notifications.subscribe "sql.active_record" do |*args|
|
@@ -65,20 +113,33 @@ class MarginaliaTest < Test::Unit::TestCase
|
|
65
113
|
def test_query_commenting_on_mysql_driver_with_action
|
66
114
|
PostsController.action(:driver_only).call(@env)
|
67
115
|
assert_match %r{select id from posts /\*application:rails,controller:posts,action:driver_only\*/$}, @queries.first
|
116
|
+
|
117
|
+
if using_rails_api?
|
118
|
+
PostsApiController.action(:driver_only).call(@env)
|
119
|
+
assert_match %r{select id from posts /\*application:rails,controller:posts_api,action:driver_only\*/$}, @queries.second
|
120
|
+
end
|
68
121
|
end
|
69
122
|
|
70
123
|
def test_configuring_application
|
71
124
|
Marginalia.application_name = "customapp"
|
72
125
|
PostsController.action(:driver_only).call(@env)
|
73
|
-
|
74
126
|
assert_match %r{/\*application:customapp,controller:posts,action:driver_only\*/$}, @queries.first
|
127
|
+
|
128
|
+
if using_rails_api?
|
129
|
+
PostsApiController.action(:driver_only).call(@env)
|
130
|
+
assert_match %r{/\*application:customapp,controller:posts_api,action:driver_only\*/$}, @queries.second
|
131
|
+
end
|
75
132
|
end
|
76
133
|
|
77
134
|
def test_configuring_query_components
|
78
135
|
Marginalia::Comment.components = [:controller]
|
79
136
|
PostsController.action(:driver_only).call(@env)
|
80
|
-
|
81
137
|
assert_match %r{/\*controller:posts\*/$}, @queries.first
|
138
|
+
|
139
|
+
if using_rails_api?
|
140
|
+
PostsApiController.action(:driver_only).call(@env)
|
141
|
+
assert_match %r{/\*controller:posts_api\*/$}, @queries.second
|
142
|
+
end
|
82
143
|
end
|
83
144
|
|
84
145
|
def test_last_line_component
|
@@ -104,11 +165,39 @@ class MarginaliaTest < Test::Unit::TestCase
|
|
104
165
|
Marginalia::Comment.components = [:hostname, :pid]
|
105
166
|
PostsController.action(:driver_only).call(@env)
|
106
167
|
assert_match %r{/\*hostname:#{Socket.gethostname},pid:#{Process.pid}\*/$}, @queries.first
|
168
|
+
end
|
107
169
|
|
170
|
+
def test_controller_with_namespace
|
171
|
+
Marginalia::Comment.components = [:controller_with_namespace]
|
172
|
+
API::V1::PostsController.action(:driver_only).call(@env)
|
173
|
+
assert_match %r{/\*controller_with_namespace:API::V1::PostsController}, @queries.first
|
174
|
+
end
|
175
|
+
|
176
|
+
if request_id_available?
|
177
|
+
def test_request_id
|
178
|
+
@env["action_dispatch.request_id"] = "some-uuid"
|
179
|
+
Marginalia::Comment.components = [:request_id]
|
180
|
+
PostsController.action(:driver_only).call(@env)
|
181
|
+
assert_match %r{/\*request_id:some-uuid.*}, @queries.first
|
182
|
+
|
183
|
+
if using_rails_api?
|
184
|
+
PostsApiController.action(:driver_only).call(@env)
|
185
|
+
assert_match %r{/\*request_id:some-uuid.*}, @queries.second
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
else
|
190
|
+
def test_request_id_is_noop_on_old_rails
|
191
|
+
@env["action_dispatch.request_id"] = "some-uuid"
|
192
|
+
Marginalia::Comment.components = [:request_id]
|
193
|
+
PostsController.action(:driver_only).call(@env)
|
194
|
+
assert_match %r{^select id from posts$}, @queries.first
|
195
|
+
end
|
108
196
|
end
|
109
197
|
|
110
198
|
def teardown
|
111
199
|
Marginalia.application_name = nil
|
200
|
+
Marginalia::Comment.lines_to_ignore = nil
|
112
201
|
Marginalia::Comment.components = [:application, :controller, :action]
|
113
202
|
ActiveSupport::Notifications.unsubscribe "sql.active_record"
|
114
203
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marginalia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Noah Lorang
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-01-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: actionpack
|