prosopite 1.0.3 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: faaeeb7c0908320a1eade29fde52c959c756f30d390bf3251427aca0d5737ea4
4
- data.tar.gz: 9843d2c7d5991d992299197b5121a68adc8cd8bc0ba7f4878f89e6eba1c00565
3
+ metadata.gz: 77b0146b180d4bf96cf36dc03c4579f44b7e8aff4693742bfcce6321057027b2
4
+ data.tar.gz: 8203dc334b5787907b5d1d25a29927b228f51c62d3814edfacd22424f0a9d20f
5
5
  SHA512:
6
- metadata.gz: a6e47da136f7e071d1d5466ee2e60fc6f571e8c129ca3f4331a200398b824891ec4dbdadcc7e244f2f51957df386aa3b20bf2b5b7e84a77510e64a3cba6fd465
7
- data.tar.gz: b53e5014b44e8fbef56088cb15e4a6cbf1fc4e596316425cc1c5ce0a09eda29b9aa98ea94900eb3be3c2772bb0c77b7a4433f2650119ef20e4125718a3b8e812
6
+ metadata.gz: 07ec42c20dc33120d6ae393f9272aa9bce89d0c18e29544ddbf9d6da02688b110d85700b4d9913ca1abcb6468f0eb57ba1259ff7990ec80f2600e02321845f63
7
+ data.tar.gz: c8194ba025357e7afba769c163fad93cc2dfc1adf489d497acc9c94efdd5f50949b724517e8d9032b1e7267e3c4075c51ed67e4a6a63de5139ed284b7277fb51
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prosopite (1.0.3)
4
+ prosopite (1.0.7)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -127,11 +127,12 @@ Prosopite auto-detection can be enabled on all controllers:
127
127
  ```ruby
128
128
  class ApplicationController < ActionController::Base
129
129
  unless Rails.env.production?
130
- before_action do
130
+ around_action :n_plus_one_detection
131
+
132
+ def n_plus_one_detection
131
133
  Prosopite.scan
132
- end
133
-
134
- after_action do
134
+ yield
135
+ ensure
135
136
  Prosopite.finish
136
137
  end
137
138
  end
@@ -181,7 +182,13 @@ WARNING: scan/finish should run before/after **each** test and NOT before/after
181
182
  Ignore notifications for call stacks containing one or more substrings:
182
183
 
183
184
  ```ruby
184
- Prosopite.allow_list = ['substring_in_call_stack']
185
+ Prosopite.allow_stack_paths = ['substring_in_call_stack']
186
+ ```
187
+
188
+ Ignore notifications matching a specific SQL query:
189
+
190
+ ```ruby
191
+ Prosopite.ignore_queries = [/regex_match/, "SELECT * from EXACT_STRING_MATCH"]
185
192
  ```
186
193
 
187
194
  ## Scanning code outside controllers or tests
@@ -202,6 +209,23 @@ Prosopite.scan do
202
209
  end
203
210
  ```
204
211
 
212
+ ## Pausing and resuming scans
213
+
214
+ Scans can be paused:
215
+
216
+ ```ruby
217
+ Prosopite.scan
218
+ # <code to scan>
219
+ Prosopite.pause
220
+ # <code that has n+1s>
221
+ Prosopite.resume
222
+ # <code to scan>
223
+ Prosopite.finish
224
+ ```
225
+
226
+ An example of when you might use this is if you are [testing Active Jobs inline](https://guides.rubyonrails.org/testing.html#testing-jobs),
227
+ and don't want to run Prosopite on background job code, just foreground app code. In that case you could write an [Active Job callback](https://edgeguides.rubyonrails.org/active_job_basics.html#callbacks) that pauses the scan while the job is running.
228
+
205
229
  ## Contributing
206
230
 
207
231
  Bug reports and pull requests are welcome on GitHub at https://github.com/charkost/prosopite.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prosopite
4
- VERSION = "1.0.3"
4
+ VERSION = "1.0.7"
5
5
  end
data/lib/prosopite.rb CHANGED
@@ -8,7 +8,14 @@ module Prosopite
8
8
  :stderr_logger,
9
9
  :rails_logger,
10
10
  :prosopite_logger,
11
- :allow_list
11
+ :allow_stack_paths,
12
+ :ignore_queries
13
+
14
+ def allow_list=(value)
15
+ puts "Prosopite.allow_list= is deprecated. Use Prosopite.allow_stack_paths= instead."
16
+
17
+ self.allow_stack_paths = value
18
+ end
12
19
 
13
20
  def scan
14
21
  tc[:prosopite_scan] ||= false
@@ -20,7 +27,7 @@ module Prosopite
20
27
  tc[:prosopite_query_holder] = Hash.new { |h, k| h[k] = [] }
21
28
  tc[:prosopite_query_caller] = {}
22
29
 
23
- @allow_list ||= []
30
+ @allow_stack_paths ||= []
24
31
 
25
32
  tc[:prosopite_scan] = true
26
33
 
@@ -38,6 +45,14 @@ module Prosopite
38
45
  Thread.current
39
46
  end
40
47
 
48
+ def pause
49
+ tc[:prosopite_scan] = false
50
+ end
51
+
52
+ def resume
53
+ scan
54
+ end
55
+
41
56
  def scan?
42
57
  tc[:prosopite_scan]
43
58
  end
@@ -64,10 +79,13 @@ module Prosopite
64
79
  end
65
80
  end
66
81
 
82
+ next unless fingerprints.uniq.size == 1
83
+
67
84
  kaller = tc[:prosopite_query_caller][location_key]
85
+ allow_list = (@allow_stack_paths + DEFAULT_ALLOW_LIST)
86
+ is_allowed = kaller.any? { |f| allow_list.any? { |s| f.include?(s) } }
68
87
 
69
- is_allowed = kaller.any? { |f| @allow_list.concat(DEFAULT_ALLOW_LIST).any? { |s| f.include?(s) } }
70
- if fingerprints.uniq.size == 1 && !is_allowed
88
+ unless is_allowed
71
89
  queries = tc[:prosopite_query_holder][location_key]
72
90
  tc[:prosopite_notifications][queries] = kaller
73
91
  end
@@ -170,6 +188,11 @@ module Prosopite
170
188
  str.split("\n").map { |line| "\e[91m#{line}\e[0m" }.join("\n")
171
189
  end
172
190
 
191
+ def ignore_query?(sql)
192
+ @ignore_queries ||= []
193
+ @ignore_queries.any? { |q| q === sql }
194
+ end
195
+
173
196
  def subscribe
174
197
  @subscribed ||= false
175
198
  return if @subscribed
@@ -177,7 +200,7 @@ module Prosopite
177
200
  ActiveSupport::Notifications.subscribe 'sql.active_record' do |_, _, _, _, data|
178
201
  sql, name = data[:sql], data[:name]
179
202
 
180
- if scan? && name != "SCHEMA" && sql.include?('SELECT') && data[:cached].nil?
203
+ if scan? && name != "SCHEMA" && sql.include?('SELECT') && data[:cached].nil? && !ignore_query?(sql)
181
204
  location_key = Digest::SHA1.hexdigest(caller.join)
182
205
 
183
206
  tc[:prosopite_query_counter][location_key] += 1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prosopite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mpampis Kostas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-25 00:00:00.000000000 Z
11
+ date: 2022-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry