marginalia 1.7.0 → 1.11.1
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 +5 -5
- checksums.yaml.gz.sig +3 -0
- data/.github/workflows/ci.yml +49 -0
- data/.ruby-version +1 -1
- data/Gemfile +4 -24
- data/README.md +31 -28
- data/Rakefile +0 -5
- data/lib/marginalia/comment.rb +30 -19
- data/lib/marginalia/railtie.rb +11 -16
- data/lib/marginalia/sidekiq_instrumentation.rb +0 -1
- data/lib/marginalia.rb +30 -23
- data/marginalia.gemspec +4 -4
- data/test/query_comments_test.rb +82 -60
- data.tar.gz.sig +0 -0
- metadata +29 -17
- metadata.gz.sig +2 -0
- data/.travis.yml +0 -16
- data/gemfiles/4.2.api.gemfile +0 -9
- data/gemfiles/4.2.gemfile +0 -8
- data/gemfiles/5.0.gemfile +0 -8
- data/gemfiles/5.1.gemfile +0 -8
- data/gemfiles/5.2.gemfile +0 -8
- data/init.rb +0 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b26b4f3d01f3649b2575559ad58cdc8d7efec99e5f7907ecada07248a25b3a53
|
|
4
|
+
data.tar.gz: f0b948325e17595049e27eeb16180e078bad1058172403d218750b8821387459
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b3a2103e22bf2c3a2221b93caf4df7f27bbc90ac865377dd9b49663ce842c070a1712a20388ffcd51221f7a3f906874784c0053aec95bfa154c18dd863c0a40e
|
|
7
|
+
data.tar.gz: d2c54a0bfbc653cdab8391373bcb8aaa663cd782282bbd7421e2860535fe727051499e1696aad7e5c49d34ddbd45aaed5df882f674bed394593739e9c043e6a3
|
checksums.yaml.gz.sig
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
ruby-version: ["2.6", "2.7", "3.0"]
|
|
13
|
+
rails-version: ["5.2.0", "6.0.0", "6.1.0"]
|
|
14
|
+
exclude:
|
|
15
|
+
# Rails 5.2 does not support Ruby 3.0
|
|
16
|
+
- {ruby-version: "3.0", rails-version: "5.2.0"}
|
|
17
|
+
|
|
18
|
+
services:
|
|
19
|
+
mysql:
|
|
20
|
+
image: mysql
|
|
21
|
+
env:
|
|
22
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
23
|
+
ports:
|
|
24
|
+
- 3306:3306
|
|
25
|
+
postgres:
|
|
26
|
+
image: postgres
|
|
27
|
+
env:
|
|
28
|
+
POSTGRES_PASSWORD: password
|
|
29
|
+
POSTGRES_HOST_AUTH_METHOD: trust
|
|
30
|
+
ports:
|
|
31
|
+
- 5432:5432
|
|
32
|
+
|
|
33
|
+
env:
|
|
34
|
+
RAILS_VERSION: ${{ matrix.rails-version }}
|
|
35
|
+
MYSQL_HOST: 127.0.0.1
|
|
36
|
+
PGHOST: 127.0.0.1
|
|
37
|
+
DB_HOST: 127.0.0.1
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v2
|
|
41
|
+
|
|
42
|
+
- uses: ruby/setup-ruby@v1
|
|
43
|
+
with:
|
|
44
|
+
ruby-version: ${{ matrix.ruby-version }}
|
|
45
|
+
bundler-cache: true
|
|
46
|
+
|
|
47
|
+
- name: Run tests
|
|
48
|
+
run: bundle exec rake db:reset test:all
|
|
49
|
+
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.6.8
|
data/Gemfile
CHANGED
|
@@ -2,29 +2,9 @@ source "https://rubygems.org"
|
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
gem 'mysql2', '~> 0.3.13'
|
|
5
|
+
rails_version = ENV["RAILS_VERSION"] || "6.1.0"
|
|
6
|
+
if rails_version == "main"
|
|
7
|
+
gem "rails", github: "rails/rails"
|
|
9
8
|
else
|
|
10
|
-
gem
|
|
11
|
-
end
|
|
12
|
-
gem 'pg', '~> 0.15'
|
|
13
|
-
gem 'sqlite3', '~> 1.3.6'
|
|
14
|
-
|
|
15
|
-
rails = case version
|
|
16
|
-
when "master"
|
|
17
|
-
{:github => "rails/rails"}
|
|
18
|
-
else
|
|
19
|
-
"~> #{version}"
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
gem "rails", rails
|
|
23
|
-
|
|
24
|
-
if ENV["TEST_RAILS_API"] == "true"
|
|
25
|
-
gem "rails-api", "~> 0.2.1"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
if RUBY_VERSION.start_with?('2.3')
|
|
29
|
-
gem 'mysql'
|
|
9
|
+
gem "rails", "~> #{rails_version}"
|
|
30
10
|
end
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# marginalia [](https://github.com/basecamp/marginalia/actions/workflows/ci.yml)
|
|
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.
|
|
@@ -18,43 +18,28 @@ to automate identification of controllers and actions that are hotspots for slow
|
|
|
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
|
-
This has been tested and used in production with
|
|
22
|
-
tested on Rails 2.
|
|
21
|
+
This has been tested and used in production with the mysql2 and pg gems, and is
|
|
22
|
+
tested on Rails 5.2 through 6.1, and Ruby 2.6 through 3.0. It is also tested
|
|
23
|
+
for sqlite3.
|
|
24
|
+
|
|
25
|
+
Rails version support will follow supported versions in the [Ruby on Rails maintenance policy](https://guides.rubyonrails.org/maintenance_policy.html)
|
|
26
|
+
and Ruby support will follow maintained versions in the [Ruby maintenance policy](https://www.ruby-lang.org/en/downloads/branches/).
|
|
23
27
|
|
|
24
28
|
Patches are welcome for other database adapters.
|
|
25
29
|
|
|
26
30
|
## Installation
|
|
27
31
|
|
|
28
|
-
### For Rails 3.x and 4.x:
|
|
29
|
-
|
|
30
32
|
# Gemfile
|
|
31
33
|
gem 'marginalia'
|
|
32
34
|
|
|
33
|
-
### For Rails 2.x:
|
|
34
|
-
|
|
35
|
-
If using cached externals, add to your `config/externals.yml` file.
|
|
36
|
-
|
|
37
|
-
Or, if your prefer using `config.gem`, you can use:
|
|
38
|
-
|
|
39
|
-
config.gem 'marginalia'
|
|
40
|
-
|
|
41
|
-
Finally, if bundled, you'll need to manually run the initialization step in an
|
|
42
|
-
initializer, e.g.:
|
|
43
|
-
|
|
44
|
-
# Gemfile
|
|
45
|
-
gem 'marginalia', :require => false
|
|
46
|
-
|
|
47
|
-
#config/initializers/marginalia.rb
|
|
48
|
-
require 'marginalia'
|
|
49
|
-
Marginalia::Railtie.insert
|
|
50
|
-
|
|
51
35
|
### Customization
|
|
52
36
|
Optionally, you can set the application name shown in the log like so in an initializer (e.g. `config/initializers/marginalia.rb`):
|
|
53
37
|
|
|
54
38
|
Marginalia.application_name = "BCX"
|
|
55
39
|
|
|
56
|
-
|
|
57
|
-
|
|
40
|
+
The name will default to your Rails application name.
|
|
41
|
+
|
|
42
|
+
#### Components
|
|
58
43
|
|
|
59
44
|
You can also configure the components of the comment that will be appended,
|
|
60
45
|
by setting `Marginalia::Comment.components`. By default, this is set to:
|
|
@@ -92,15 +77,23 @@ default. In addition, implementation is provided for:
|
|
|
92
77
|
* `:job` to include the classname of the ActiveJob being performed.
|
|
93
78
|
* `:hostname` to include ```Socket.gethostname```.
|
|
94
79
|
* `:pid` to include current process id.
|
|
95
|
-
|
|
96
|
-
With ActiveRecord >= 3.2.19:
|
|
97
80
|
* `:db_host` to include the configured database hostname.
|
|
98
81
|
* `:socket` to include the configured database socket.
|
|
99
82
|
* `:database` to include the configured database name.
|
|
100
83
|
|
|
101
84
|
Pull requests for other included comment components are welcome.
|
|
102
85
|
|
|
103
|
-
|
|
86
|
+
#### Prepend comments
|
|
87
|
+
|
|
88
|
+
By default marginalia appends the comments at the end of the query. Certain databases, such as MySQL will truncate
|
|
89
|
+
the query text. This is the case for slow query logs and the results of querying some InnoDB internal tables where the
|
|
90
|
+
length of the query is more than 1024 bytes.
|
|
91
|
+
|
|
92
|
+
In order to not lose the marginalia comments from your logs, you can prepend the comments using this option:
|
|
93
|
+
|
|
94
|
+
Marginalia::Comment.prepend_comment = true
|
|
95
|
+
|
|
96
|
+
#### Inline query annotations
|
|
104
97
|
|
|
105
98
|
In addition to the request or job-level component-based annotations,
|
|
106
99
|
Marginalia may be used to add inline annotations to specific queries using a
|
|
@@ -121,6 +114,16 @@ will issue this query:
|
|
|
121
114
|
|
|
122
115
|
Nesting `with_annotation` blocks will concatenate the comment strings.
|
|
123
116
|
|
|
117
|
+
### Caveats
|
|
118
|
+
|
|
119
|
+
#### Prepared statements
|
|
120
|
+
|
|
121
|
+
Be careful when using Marginalia with prepared statements. If you use a component
|
|
122
|
+
like `request_id` then every query will be unique and so ActiveRecord will create
|
|
123
|
+
a new prepared statement for each potentially exhausting system resources.
|
|
124
|
+
[Disable prepared statements](https://guides.rubyonrails.org/configuring.html#configuring-a-postgresql-database)
|
|
125
|
+
if you wish to use components with high cardinality values.
|
|
126
|
+
|
|
124
127
|
## Contributing
|
|
125
128
|
|
|
126
129
|
Start by bundling and creating the test database:
|
data/Rakefile
CHANGED
|
@@ -7,11 +7,6 @@ namespace :test do
|
|
|
7
7
|
desc "test all drivers"
|
|
8
8
|
task :all => [:mysql2, :postgresql, :sqlite]
|
|
9
9
|
|
|
10
|
-
desc "test mysql driver"
|
|
11
|
-
task :mysql do
|
|
12
|
-
sh "DRIVER=mysql bundle exec ruby -Ilib -Itest test/*_test.rb"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
10
|
desc "test mysql2 driver"
|
|
16
11
|
task :mysql2 do
|
|
17
12
|
sh "DRIVER=mysql2 bundle exec ruby -Ilib -Itest test/*_test.rb"
|
data/lib/marginalia/comment.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'socket'
|
|
2
4
|
|
|
3
5
|
module Marginalia
|
|
4
6
|
module Comment
|
|
5
|
-
mattr_accessor :components, :lines_to_ignore
|
|
7
|
+
mattr_accessor :components, :lines_to_ignore, :prepend_comment
|
|
6
8
|
Marginalia::Comment.components ||= [:application, :controller, :action]
|
|
7
9
|
|
|
8
10
|
def self.update!(controller = nil)
|
|
@@ -18,11 +20,11 @@ module Marginalia
|
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def self.construct_comment
|
|
21
|
-
ret =
|
|
23
|
+
ret = String.new
|
|
22
24
|
self.components.each do |c|
|
|
23
25
|
component_value = self.send(c)
|
|
24
26
|
if component_value.present?
|
|
25
|
-
ret << "#{c
|
|
27
|
+
ret << "#{c}:#{component_value},"
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
30
|
ret.chop!
|
|
@@ -102,11 +104,14 @@ module Marginalia
|
|
|
102
104
|
end
|
|
103
105
|
|
|
104
106
|
def self.sidekiq_job
|
|
105
|
-
marginalia_job["class"] if marginalia_job
|
|
107
|
+
marginalia_job["class"] if marginalia_job && marginalia_job.respond_to?(:[])
|
|
106
108
|
end
|
|
107
109
|
|
|
110
|
+
DEFAULT_LINES_TO_IGNORE_REGEX = %r{\.rvm|/ruby/gems/|vendor/|marginalia|rbenv|monitor\.rb.*mon_synchronize}
|
|
111
|
+
|
|
108
112
|
def self.line
|
|
109
|
-
Marginalia::Comment.lines_to_ignore ||=
|
|
113
|
+
Marginalia::Comment.lines_to_ignore ||= DEFAULT_LINES_TO_IGNORE_REGEX
|
|
114
|
+
|
|
110
115
|
last_line = caller.detect do |line|
|
|
111
116
|
line !~ Marginalia::Comment.lines_to_ignore
|
|
112
117
|
end
|
|
@@ -118,7 +123,7 @@ module Marginalia
|
|
|
118
123
|
else
|
|
119
124
|
""
|
|
120
125
|
end
|
|
121
|
-
if last_line.
|
|
126
|
+
if last_line.start_with? root
|
|
122
127
|
last_line = last_line[root.length..-1]
|
|
123
128
|
end
|
|
124
129
|
last_line
|
|
@@ -139,29 +144,35 @@ module Marginalia
|
|
|
139
144
|
end
|
|
140
145
|
end
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
self.connection_config[:socket]
|
|
146
|
-
end
|
|
147
|
+
def self.socket
|
|
148
|
+
if self.connection_config.present?
|
|
149
|
+
self.connection_config[:socket]
|
|
147
150
|
end
|
|
151
|
+
end
|
|
148
152
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
end
|
|
153
|
+
def self.db_host
|
|
154
|
+
if self.connection_config.present?
|
|
155
|
+
self.connection_config[:host]
|
|
153
156
|
end
|
|
157
|
+
end
|
|
154
158
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
end
|
|
159
|
+
def self.database
|
|
160
|
+
if self.connection_config.present?
|
|
161
|
+
self.connection_config[:database]
|
|
159
162
|
end
|
|
163
|
+
end
|
|
160
164
|
|
|
165
|
+
if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('6.1')
|
|
161
166
|
def self.connection_config
|
|
162
167
|
return if marginalia_adapter.pool.nil?
|
|
163
168
|
marginalia_adapter.pool.spec.config
|
|
164
169
|
end
|
|
170
|
+
else
|
|
171
|
+
def self.connection_config
|
|
172
|
+
# `pool` might be a NullPool which has no db_config
|
|
173
|
+
return unless marginalia_adapter.pool.respond_to?(:db_config)
|
|
174
|
+
marginalia_adapter.pool.db_config.configuration_hash
|
|
175
|
+
end
|
|
165
176
|
end
|
|
166
177
|
|
|
167
178
|
def self.inline_annotations
|
data/lib/marginalia/railtie.rb
CHANGED
|
@@ -1,27 +1,22 @@
|
|
|
1
1
|
require 'marginalia'
|
|
2
|
+
require 'rails/railtie'
|
|
2
3
|
|
|
3
4
|
module Marginalia
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ActiveSupport.on_load :active_record do
|
|
10
|
-
Marginalia::Railtie.insert_into_active_record
|
|
11
|
-
end
|
|
5
|
+
class Railtie < Rails::Railtie
|
|
6
|
+
initializer 'marginalia.insert' do
|
|
7
|
+
ActiveSupport.on_load :active_record do
|
|
8
|
+
Marginalia::Railtie.insert_into_active_record
|
|
9
|
+
end
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
ActiveSupport.on_load :action_controller do
|
|
12
|
+
Marginalia::Railtie.insert_into_action_controller
|
|
13
|
+
end
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
end
|
|
15
|
+
ActiveSupport.on_load :active_job do
|
|
16
|
+
Marginalia::Railtie.insert_into_active_job
|
|
20
17
|
end
|
|
21
18
|
end
|
|
22
|
-
end
|
|
23
19
|
|
|
24
|
-
class Railtie
|
|
25
20
|
def self.insert
|
|
26
21
|
insert_into_active_record
|
|
27
22
|
insert_into_action_controller
|
data/lib/marginalia.rb
CHANGED
|
@@ -19,8 +19,8 @@ module Marginalia
|
|
|
19
19
|
else
|
|
20
20
|
is_mysql2 = defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) &&
|
|
21
21
|
ActiveRecord::ConnectionAdapters::Mysql2Adapter == instrumented_class
|
|
22
|
-
# Dont instrument exec_query on mysql2
|
|
23
|
-
unless is_mysql2
|
|
22
|
+
# Dont instrument exec_query on mysql2 as it calls execute internally
|
|
23
|
+
unless is_mysql2
|
|
24
24
|
if instrumented_class.method_defined?(:exec_query)
|
|
25
25
|
alias_method :exec_query_without_marginalia, :exec_query
|
|
26
26
|
alias_method :exec_query, :exec_query_with_marginalia
|
|
@@ -29,9 +29,9 @@ module Marginalia
|
|
|
29
29
|
|
|
30
30
|
is_postgres = defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) &&
|
|
31
31
|
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter == instrumented_class
|
|
32
|
-
# Instrument exec_delete and exec_update
|
|
33
|
-
#
|
|
34
|
-
if is_postgres
|
|
32
|
+
# Instrument exec_delete and exec_update since they don't call
|
|
33
|
+
# execute internally
|
|
34
|
+
if is_postgres
|
|
35
35
|
if instrumented_class.method_defined?(:exec_delete)
|
|
36
36
|
alias_method :exec_delete_without_marginalia, :exec_delete
|
|
37
37
|
alias_method :exec_delete, :exec_delete_with_marginalia
|
|
@@ -49,41 +49,48 @@ module Marginalia
|
|
|
49
49
|
Marginalia::Comment.update_adapter!(self)
|
|
50
50
|
comment = Marginalia::Comment.construct_comment
|
|
51
51
|
if comment.present? && !sql.include?(comment)
|
|
52
|
-
sql =
|
|
52
|
+
sql = if Marginalia::Comment.prepend_comment
|
|
53
|
+
"/*#{comment}*/ #{sql}"
|
|
54
|
+
else
|
|
55
|
+
"#{sql} /*#{comment}*/"
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
inline_comment = Marginalia::Comment.construct_inline_comment
|
|
55
|
-
if inline_comment.present?
|
|
56
|
-
sql =
|
|
59
|
+
if inline_comment.present? && !sql.include?(inline_comment)
|
|
60
|
+
sql = if Marginalia::Comment.prepend_comment
|
|
61
|
+
"/*#{inline_comment}*/ #{sql}"
|
|
62
|
+
else
|
|
63
|
+
"#{sql} /*#{inline_comment}*/"
|
|
64
|
+
end
|
|
57
65
|
end
|
|
58
|
-
sql
|
|
59
|
-
end
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
execute_without_marginalia(annotate_sql(sql), name)
|
|
67
|
+
sql
|
|
63
68
|
end
|
|
64
69
|
|
|
65
|
-
def
|
|
66
|
-
|
|
70
|
+
def execute_with_marginalia(sql, *args)
|
|
71
|
+
execute_without_marginalia(annotate_sql(sql), *args)
|
|
67
72
|
end
|
|
73
|
+
ruby2_keywords :execute_with_marginalia if respond_to?(:ruby2_keywords, true)
|
|
68
74
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
exec_query_without_marginalia(annotate_sql(sql), name, binds, options)
|
|
73
|
-
end
|
|
75
|
+
def exec_query_with_marginalia(sql, *args, **options)
|
|
76
|
+
options[:prepare] ||= false
|
|
77
|
+
exec_query_without_marginalia(annotate_sql(sql), *args, **options)
|
|
74
78
|
end
|
|
75
79
|
|
|
76
|
-
def exec_delete_with_marginalia(sql,
|
|
77
|
-
exec_delete_without_marginalia(annotate_sql(sql),
|
|
80
|
+
def exec_delete_with_marginalia(sql, *args)
|
|
81
|
+
exec_delete_without_marginalia(annotate_sql(sql), *args)
|
|
78
82
|
end
|
|
83
|
+
ruby2_keywords :exec_delete_with_marginalia if respond_to?(:ruby2_keywords, true)
|
|
79
84
|
|
|
80
|
-
def exec_update_with_marginalia(sql,
|
|
81
|
-
exec_update_without_marginalia(annotate_sql(sql),
|
|
85
|
+
def exec_update_with_marginalia(sql, *args)
|
|
86
|
+
exec_update_without_marginalia(annotate_sql(sql), *args)
|
|
82
87
|
end
|
|
88
|
+
ruby2_keywords :exec_update_with_marginalia if respond_to?(:ruby2_keywords, true)
|
|
83
89
|
|
|
84
90
|
def execute_and_clear_with_marginalia(sql, *args, &block)
|
|
85
91
|
execute_and_clear_without_marginalia(annotate_sql(sql), *args, &block)
|
|
86
92
|
end
|
|
93
|
+
ruby2_keywords :execute_and_clear_with_marginalia if respond_to?(:ruby2_keywords, true)
|
|
87
94
|
end
|
|
88
95
|
|
|
89
96
|
module ActionControllerInstrumentation
|
data/marginalia.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |gem|
|
|
2
2
|
gem.authors = ["Noah Lorang", "Nick Quaranto", "Taylor Weibley"]
|
|
3
|
-
gem.email = ["
|
|
3
|
+
gem.email = ["arthurnn@github.com"]
|
|
4
4
|
gem.homepage = "https://github.com/basecamp/marginalia"
|
|
5
5
|
|
|
6
6
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
@@ -8,11 +8,11 @@ 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.11.1"
|
|
12
12
|
gem.license = "MIT"
|
|
13
13
|
|
|
14
|
-
gem.add_runtime_dependency "actionpack", ">= 2
|
|
15
|
-
gem.add_runtime_dependency "activerecord", ">= 2
|
|
14
|
+
gem.add_runtime_dependency "actionpack", ">= 5.2"
|
|
15
|
+
gem.add_runtime_dependency "activerecord", ">= 5.2"
|
|
16
16
|
gem.add_development_dependency "rake"
|
|
17
17
|
gem.add_development_dependency "mysql2"
|
|
18
18
|
gem.add_development_dependency "pg"
|
data/test/query_comments_test.rb
CHANGED
|
@@ -5,16 +5,8 @@ def using_rails_api?
|
|
|
5
5
|
ENV["TEST_RAILS_API"] == true
|
|
6
6
|
end
|
|
7
7
|
|
|
8
|
-
def
|
|
9
|
-
Gem::Version.new(
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def active_job_available?
|
|
13
|
-
Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new('4.2')
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def adapter_pool_available?
|
|
17
|
-
Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('3.2.19')
|
|
8
|
+
def pool_db_config?
|
|
9
|
+
Gem::Version.new(ActiveRecord::VERSION::STRING) >= Gem::Version.new('6.1')
|
|
18
10
|
end
|
|
19
11
|
|
|
20
12
|
require "minitest/autorun"
|
|
@@ -23,16 +15,11 @@ require 'logger'
|
|
|
23
15
|
require 'pp'
|
|
24
16
|
require 'active_record'
|
|
25
17
|
require 'action_controller'
|
|
18
|
+
require 'active_job'
|
|
26
19
|
require 'sidekiq'
|
|
27
20
|
require 'sidekiq/testing'
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
require 'action_dispatch/middleware/request_id'
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
if active_job_available?
|
|
34
|
-
require 'active_job'
|
|
35
|
-
end
|
|
22
|
+
require 'action_dispatch/middleware/request_id'
|
|
36
23
|
|
|
37
24
|
if using_rails_api?
|
|
38
25
|
require 'rails-api/action_controller/api'
|
|
@@ -55,7 +42,7 @@ RAILS_ROOT = File.expand_path(File.dirname(__FILE__))
|
|
|
55
42
|
|
|
56
43
|
ActiveRecord::Base.establish_connection({
|
|
57
44
|
:adapter => ENV["DRIVER"] || "mysql",
|
|
58
|
-
:host => "localhost",
|
|
45
|
+
:host => ENV["DB_HOST"] || "localhost",
|
|
59
46
|
:username => ENV["DB_USERNAME"] || "root",
|
|
60
47
|
:database => "marginalia_test"
|
|
61
48
|
})
|
|
@@ -81,11 +68,9 @@ module API
|
|
|
81
68
|
end
|
|
82
69
|
end
|
|
83
70
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Post.first
|
|
88
|
-
end
|
|
71
|
+
class PostsJob < ActiveJob::Base
|
|
72
|
+
def perform
|
|
73
|
+
Post.first
|
|
89
74
|
end
|
|
90
75
|
end
|
|
91
76
|
|
|
@@ -116,11 +101,15 @@ Marginalia::Railtie.insert
|
|
|
116
101
|
|
|
117
102
|
class MarginaliaTest < MiniTest::Test
|
|
118
103
|
def setup
|
|
104
|
+
# Touch the model to avoid spurious schema queries
|
|
105
|
+
Post.first
|
|
106
|
+
|
|
119
107
|
@queries = []
|
|
120
108
|
ActiveSupport::Notifications.subscribe "sql.active_record" do |*args|
|
|
121
109
|
@queries << args.last[:sql]
|
|
122
110
|
end
|
|
123
111
|
@env = Rack::MockRequest.env_for('/')
|
|
112
|
+
ActiveJob::Base.queue_adapter = :inline
|
|
124
113
|
end
|
|
125
114
|
|
|
126
115
|
def test_double_annotate
|
|
@@ -131,7 +120,6 @@ class MarginaliaTest < MiniTest::Test
|
|
|
131
120
|
end
|
|
132
121
|
|
|
133
122
|
def test_exists
|
|
134
|
-
skip if Gem::Version.new(ActiveRecord::VERSION::STRING) < Gem::Version.new('3.2')
|
|
135
123
|
Post.exists?
|
|
136
124
|
assert_match %r{/\*application:rails\*/$}, @queries.last
|
|
137
125
|
end
|
|
@@ -215,6 +203,16 @@ class MarginaliaTest < MiniTest::Test
|
|
|
215
203
|
assert_match %r{/\*line:.*lib/marginalia/comment.rb:[0-9]+}, @queries.first
|
|
216
204
|
end
|
|
217
205
|
|
|
206
|
+
def test_default_lines_to_ignore_regex
|
|
207
|
+
line = "/gems/a_gem/lib/a_gem.rb:1:in `some_method'"
|
|
208
|
+
call_stack = [line] + caller
|
|
209
|
+
|
|
210
|
+
assert_match(
|
|
211
|
+
call_stack.detect { |line| line !~ Marginalia::Comment::DEFAULT_LINES_TO_IGNORE_REGEX },
|
|
212
|
+
line
|
|
213
|
+
)
|
|
214
|
+
end
|
|
215
|
+
|
|
218
216
|
def test_hostname_and_pid
|
|
219
217
|
Marginalia::Comment.components = [:hostname, :pid]
|
|
220
218
|
PostsController.action(:driver_only).call(@env)
|
|
@@ -227,19 +225,29 @@ class MarginaliaTest < MiniTest::Test
|
|
|
227
225
|
assert_match %r{/\*controller_with_namespace:API::V1::PostsController}, @queries.first
|
|
228
226
|
end
|
|
229
227
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
end
|
|
228
|
+
def test_db_host
|
|
229
|
+
Marginalia::Comment.components = [:db_host]
|
|
230
|
+
API::V1::PostsController.action(:driver_only).call(@env)
|
|
231
|
+
assert_match %r{/\*db_host:#{ENV["DB_HOST"] || "localhost"}}, @queries.first
|
|
232
|
+
end
|
|
236
233
|
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
def test_database
|
|
235
|
+
Marginalia::Comment.components = [:database]
|
|
236
|
+
API::V1::PostsController.action(:driver_only).call(@env)
|
|
237
|
+
assert_match %r{/\*database:marginalia_test}, @queries.first
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
if pool_db_config?
|
|
241
|
+
def test_socket
|
|
242
|
+
# setting socket in configuration would break some connections - mock it instead
|
|
243
|
+
pool = ActiveRecord::Base.connection_pool
|
|
244
|
+
pool.db_config.stubs(:configuration_hash).returns({:socket => "marginalia_socket"})
|
|
245
|
+
Marginalia::Comment.components = [:socket]
|
|
239
246
|
API::V1::PostsController.action(:driver_only).call(@env)
|
|
240
|
-
assert_match %r{/\*
|
|
247
|
+
assert_match %r{/\*socket:marginalia_socket}, @queries.first
|
|
248
|
+
pool.db_config.unstub(:configuration_hash)
|
|
241
249
|
end
|
|
242
|
-
|
|
250
|
+
else
|
|
243
251
|
def test_socket
|
|
244
252
|
# setting socket in configuration would break some connections - mock it instead
|
|
245
253
|
pool = ActiveRecord::Base.connection_pool
|
|
@@ -251,37 +259,34 @@ class MarginaliaTest < MiniTest::Test
|
|
|
251
259
|
end
|
|
252
260
|
end
|
|
253
261
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
assert_match %r{/\*request_id:some-uuid.*}, @queries.first
|
|
262
|
+
def test_request_id
|
|
263
|
+
@env["action_dispatch.request_id"] = "some-uuid"
|
|
264
|
+
Marginalia::Comment.components = [:request_id]
|
|
265
|
+
PostsController.action(:driver_only).call(@env)
|
|
266
|
+
assert_match %r{/\*request_id:some-uuid.*}, @queries.first
|
|
260
267
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
end
|
|
268
|
+
if using_rails_api?
|
|
269
|
+
PostsApiController.action(:driver_only).call(@env)
|
|
270
|
+
assert_match %r{/\*request_id:some-uuid.*}, @queries.second
|
|
265
271
|
end
|
|
272
|
+
end
|
|
266
273
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
+
def test_active_job
|
|
275
|
+
Marginalia::Comment.components = [:job]
|
|
276
|
+
PostsJob.perform_later
|
|
277
|
+
assert_match %{job:PostsJob}, @queries.first
|
|
278
|
+
|
|
279
|
+
Post.first
|
|
280
|
+
refute_match %{job:PostsJob}, @queries.last
|
|
274
281
|
end
|
|
275
282
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
assert_match %{job:PostsJob}, @queries.first
|
|
283
|
+
def test_active_job_with_sidekiq
|
|
284
|
+
Marginalia::Comment.components = [:job, :sidekiq_job]
|
|
285
|
+
PostsJob.perform_later
|
|
286
|
+
assert_match %{job:PostsJob}, @queries.first
|
|
281
287
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
end
|
|
288
|
+
Post.first
|
|
289
|
+
refute_match %{job:PostsJob}, @queries.last
|
|
285
290
|
end
|
|
286
291
|
|
|
287
292
|
def test_sidekiq_job
|
|
@@ -290,13 +295,14 @@ class MarginaliaTest < MiniTest::Test
|
|
|
290
295
|
|
|
291
296
|
# Test harness does not run Sidekiq middlewares by default so include testing middleware.
|
|
292
297
|
Sidekiq::Testing.server_middleware do |chain|
|
|
293
|
-
|
|
298
|
+
chain.add Marginalia::SidekiqInstrumentation::Middleware
|
|
294
299
|
end
|
|
295
300
|
|
|
296
301
|
Sidekiq::Testing.fake!
|
|
297
302
|
PostsSidekiqJob.perform_async
|
|
298
303
|
PostsSidekiqJob.drain
|
|
299
304
|
assert_match %{sidekiq_job:PostsSidekiqJob}, @queries.first
|
|
305
|
+
|
|
300
306
|
Post.first
|
|
301
307
|
refute_match %{sidekiq_job:PostsSidekiqJob}, @queries.last
|
|
302
308
|
end
|
|
@@ -341,6 +347,22 @@ class MarginaliaTest < MiniTest::Test
|
|
|
341
347
|
assert_match %r{/\*; DROP TABLE USERS;\*/$}, @queries.last
|
|
342
348
|
end
|
|
343
349
|
|
|
350
|
+
def test_inline_annotations_are_deduped
|
|
351
|
+
Marginalia.with_annotation("foo") do
|
|
352
|
+
ActiveRecord::Base.connection.execute "select id from posts /*foo*/"
|
|
353
|
+
end
|
|
354
|
+
assert_match %r{select id from posts /\*foo\*/ /\*application:rails\*/$}, @queries.first
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def test_add_comments_to_beginning_of_query
|
|
358
|
+
Marginalia::Comment.prepend_comment = true
|
|
359
|
+
|
|
360
|
+
ActiveRecord::Base.connection.execute "select id from posts"
|
|
361
|
+
assert_match %r{/\*application:rails\*/ select id from posts$}, @queries.first
|
|
362
|
+
ensure
|
|
363
|
+
Marginalia::Comment.prepend_comment = nil
|
|
364
|
+
end
|
|
365
|
+
|
|
344
366
|
def teardown
|
|
345
367
|
Marginalia.application_name = nil
|
|
346
368
|
Marginalia::Comment.lines_to_ignore = nil
|
data.tar.gz.sig
ADDED
|
Binary file
|
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.11.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Noah Lorang
|
|
@@ -9,8 +9,28 @@ authors:
|
|
|
9
9
|
- Taylor Weibley
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
|
-
cert_chain:
|
|
13
|
-
|
|
12
|
+
cert_chain:
|
|
13
|
+
- |
|
|
14
|
+
-----BEGIN CERTIFICATE-----
|
|
15
|
+
MIIDKDCCAhCgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA6MQ0wCwYDVQQDDARzajI2
|
|
16
|
+
MRQwEgYKCZImiZPyLGQBGRYEc2oyNjETMBEGCgmSJomT8ixkARkWA2NvbTAeFw0y
|
|
17
|
+
MTA0MjcwMzIxMjZaFw0yMjA0MjcwMzIxMjZaMDoxDTALBgNVBAMMBHNqMjYxFDAS
|
|
18
|
+
BgoJkiaJk/IsZAEZFgRzajI2MRMwEQYKCZImiZPyLGQBGRYDY29tMIIBIjANBgkq
|
|
19
|
+
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr60Eo/ttCk8GMTMFiPr3GoYMIMFvLak
|
|
20
|
+
xSmTk9YGCB6UiEePB4THSSA5w6IPyeaCF/nWkDp3/BAam0eZMWG1IzYQB23TqIM0
|
|
21
|
+
1xzcNRvFsn0aQoQ00k+sj+G83j3T5OOV5OZIlu8xAChMkQmiPd1NXc6uFv+Iacz7
|
|
22
|
+
kj+CMsI9YUFdNoU09QY0b+u+Rb6wDYdpyvN60YC30h0h1MeYbvYZJx/iZK4XY5zu
|
|
23
|
+
4O/FL2ChjL2CPCpLZW55ShYyrzphWJwLOJe+FJ/ZBl6YXwrzQM9HKnt4titSNvyU
|
|
24
|
+
KzE3L63A3PZvExzLrN9u09kuWLLJfXB2sGOlw3n9t72rJiuBr3/OQQIDAQABozkw
|
|
25
|
+
NzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU99dfRjEKFyczTeIz
|
|
26
|
+
m3ZsDWrNC80wDQYJKoZIhvcNAQELBQADggEBAInkmTwBeGEJ7Xu9jjZIuFaE197m
|
|
27
|
+
YfvrzVoE6Q1DlWXpgyhhxbPIKg2acvM/Z18A7kQrF7paYl64Ti84dC64seOFIBNx
|
|
28
|
+
Qj/lxzPHMBoAYqeXYJhnYIXnvGCZ4Fkic5Bhs+VdcDP/uwYp3adqy+4bT/XDFZQg
|
|
29
|
+
tSjrAOTg3wck5aI+Tz90ONQJ83bnCRr1UPQ0T3PbWMjnNsEa9CAxUB845Sg+9yUz
|
|
30
|
+
Tvf+pbX8JT9rawFDogxPhL7eRAbjg4MH9amp5l8HTVCAsW8vqv7wM4rtMNAaXmik
|
|
31
|
+
LJghfDEf70fTtbs4Zv57pPhn1b7wBNf8fh+TZOlYAA6dFtQXoCwfE6bWgQU=
|
|
32
|
+
-----END CERTIFICATE-----
|
|
33
|
+
date: 2021-08-20 00:00:00.000000000 Z
|
|
14
34
|
dependencies:
|
|
15
35
|
- !ruby/object:Gem::Dependency
|
|
16
36
|
name: actionpack
|
|
@@ -18,28 +38,28 @@ dependencies:
|
|
|
18
38
|
requirements:
|
|
19
39
|
- - ">="
|
|
20
40
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: '2
|
|
41
|
+
version: '5.2'
|
|
22
42
|
type: :runtime
|
|
23
43
|
prerelease: false
|
|
24
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
45
|
requirements:
|
|
26
46
|
- - ">="
|
|
27
47
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: '2
|
|
48
|
+
version: '5.2'
|
|
29
49
|
- !ruby/object:Gem::Dependency
|
|
30
50
|
name: activerecord
|
|
31
51
|
requirement: !ruby/object:Gem::Requirement
|
|
32
52
|
requirements:
|
|
33
53
|
- - ">="
|
|
34
54
|
- !ruby/object:Gem::Version
|
|
35
|
-
version: '2
|
|
55
|
+
version: '5.2'
|
|
36
56
|
type: :runtime
|
|
37
57
|
prerelease: false
|
|
38
58
|
version_requirements: !ruby/object:Gem::Requirement
|
|
39
59
|
requirements:
|
|
40
60
|
- - ">="
|
|
41
61
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '2
|
|
62
|
+
version: '5.2'
|
|
43
63
|
- !ruby/object:Gem::Dependency
|
|
44
64
|
name: rake
|
|
45
65
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -140,25 +160,18 @@ dependencies:
|
|
|
140
160
|
version: '0'
|
|
141
161
|
description: Attach comments to your ActiveRecord queries.
|
|
142
162
|
email:
|
|
143
|
-
- noah@37signals.com
|
|
144
163
|
- arthurnn@github.com
|
|
145
164
|
executables: []
|
|
146
165
|
extensions: []
|
|
147
166
|
extra_rdoc_files: []
|
|
148
167
|
files:
|
|
168
|
+
- ".github/workflows/ci.yml"
|
|
149
169
|
- ".gitignore"
|
|
150
170
|
- ".ruby-version"
|
|
151
|
-
- ".travis.yml"
|
|
152
171
|
- Gemfile
|
|
153
172
|
- LICENSE
|
|
154
173
|
- README.md
|
|
155
174
|
- Rakefile
|
|
156
|
-
- gemfiles/4.2.api.gemfile
|
|
157
|
-
- gemfiles/4.2.gemfile
|
|
158
|
-
- gemfiles/5.0.gemfile
|
|
159
|
-
- gemfiles/5.1.gemfile
|
|
160
|
-
- gemfiles/5.2.gemfile
|
|
161
|
-
- init.rb
|
|
162
175
|
- lib/marginalia.rb
|
|
163
176
|
- lib/marginalia/comment.rb
|
|
164
177
|
- lib/marginalia/railtie.rb
|
|
@@ -184,8 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
184
197
|
- !ruby/object:Gem::Version
|
|
185
198
|
version: '0'
|
|
186
199
|
requirements: []
|
|
187
|
-
|
|
188
|
-
rubygems_version: 2.4.5.1
|
|
200
|
+
rubygems_version: 3.2.25
|
|
189
201
|
signing_key:
|
|
190
202
|
specification_version: 4
|
|
191
203
|
summary: Attach comments to your ActiveRecord queries.
|
metadata.gz.sig
ADDED
data/.travis.yml
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
language: ruby
|
|
2
|
-
sudo: false
|
|
3
|
-
|
|
4
|
-
rvm:
|
|
5
|
-
- 2.2
|
|
6
|
-
- 2.3
|
|
7
|
-
- 2.4
|
|
8
|
-
|
|
9
|
-
script: "bundle exec rake db:reset test:all"
|
|
10
|
-
|
|
11
|
-
gemfile:
|
|
12
|
-
- gemfiles/4.2.gemfile
|
|
13
|
-
- gemfiles/4.2.api.gemfile
|
|
14
|
-
- gemfiles/5.0.gemfile
|
|
15
|
-
- gemfiles/5.1.gemfile
|
|
16
|
-
- gemfiles/5.2.gemfile
|
data/gemfiles/4.2.api.gemfile
DELETED
data/gemfiles/4.2.gemfile
DELETED
data/gemfiles/5.0.gemfile
DELETED
data/gemfiles/5.1.gemfile
DELETED
data/gemfiles/5.2.gemfile
DELETED
data/init.rb
DELETED