tapping_device 0.4.5 → 0.4.6
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 +4 -4
- data/Gemfile.lock +8 -8
- data/README.md +69 -47
- data/lib/tapping_device/payload.rb +18 -4
- data/lib/tapping_device/version.rb +1 -1
- data/lib/tapping_device.rb +7 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee22ec85fa4fc7f9b96a1e13a067a581e4dc6dcd591783019c4bae8e829cda10
|
4
|
+
data.tar.gz: ec3805395e9dc95b31cdb30d9c867877d37aada6c5b12d2ac842e3fdbc9e563d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59c1d8868d94bbea441a64291a77ec1783f146d584234657c8b455073b17a760cda0a035789c8d73d1b6cc9bbfb7a28f1afb619dc026ec1ac970917ca73514a1
|
7
|
+
data.tar.gz: 75b0ba8536f9fdf5f8bce8c990d5094881a2206763ffb8ab19ef9fe549944442a4f42b9dd26d3a2c4564cf1a43dafcb7ff4531c5281fc1488b8d0d725612693c
|
data/Gemfile.lock
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tapping_device (0.4.
|
4
|
+
tapping_device (0.4.6)
|
5
5
|
activerecord (>= 5.2)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (6.0.2)
|
11
|
-
activesupport (= 6.0.2)
|
12
|
-
activerecord (6.0.2)
|
13
|
-
activemodel (= 6.0.2)
|
14
|
-
activesupport (= 6.0.2)
|
15
|
-
activesupport (6.0.2)
|
10
|
+
activemodel (6.0.2.1)
|
11
|
+
activesupport (= 6.0.2.1)
|
12
|
+
activerecord (6.0.2.1)
|
13
|
+
activemodel (= 6.0.2.1)
|
14
|
+
activesupport (= 6.0.2.1)
|
15
|
+
activesupport (6.0.2.1)
|
16
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
17
|
i18n (>= 0.7, < 2)
|
18
18
|
minitest (~> 5.1)
|
@@ -45,7 +45,7 @@ GEM
|
|
45
45
|
rspec-support (3.8.2)
|
46
46
|
sqlite3 (1.4.1)
|
47
47
|
thread_safe (0.3.6)
|
48
|
-
tzinfo (1.2.
|
48
|
+
tzinfo (1.2.6)
|
49
49
|
thread_safe (~> 0.1)
|
50
50
|
zeitwerk (2.2.2)
|
51
51
|
|
data/README.md
CHANGED
@@ -2,10 +2,27 @@
|
|
2
2
|
|
3
3
|

|
4
4
|
|
5
|
+
## Related Posts
|
6
|
+
- [Debug Rails issues effectively with tapping_device](https://dev.to/st0012/debug-rails-issues-effectively-with-tappingdevice-c7c)
|
7
|
+
- [Want to know more about your Rails app? Tap on your objects!](https://dev.to/st0012/want-to-know-more-about-your-rails-app-tap-on-your-objects-bd3)
|
8
|
+
|
9
|
+
## Table of Content
|
10
|
+
- [Introduction](#introduction)
|
11
|
+
- [Track Method Calls](#track-method-calls)
|
12
|
+
- [Track Association Calls](#track-association-calls)
|
13
|
+
- [Track Calls that Generates SQL Queries](#track-calls-that-generates-sql-queries)
|
14
|
+
- [Installation](#installation)
|
15
|
+
- [Usages](#usage)
|
16
|
+
- [Methods](#methods)
|
17
|
+
- [Payload](#payload-of-the-call)
|
18
|
+
- [Options](#options)
|
19
|
+
- [Advance Usages](#advance-usages)
|
20
|
+
|
21
|
+
## Introduction
|
5
22
|
|
6
23
|
`tapping_device` is a gem built on top of Ruby’s `TracePoint` class that allows you to tap method calls of specified objects. The purpose for this gem is to make debugging Rails applications easier. Here are some sample usages:
|
7
24
|
|
8
|
-
### Track
|
25
|
+
### Track Method Calls
|
9
26
|
|
10
27
|
```ruby
|
11
28
|
class PostsController < ApplicationController
|
@@ -13,10 +30,7 @@ class PostsController < ApplicationController
|
|
13
30
|
|
14
31
|
def show
|
15
32
|
@post = Post.find(params[:id])
|
16
|
-
tap_on!(@post)
|
17
|
-
# this equals to `"Method: :#{payload[:method_name]}, line: #{payload[:filepath]}:#{payload[:line_number]}"`
|
18
|
-
puts(payload.method_name_and_location)
|
19
|
-
end
|
33
|
+
tap_on!(@post).and_print(:method_name_and_location)
|
20
34
|
end
|
21
35
|
end
|
22
36
|
```
|
@@ -24,32 +38,30 @@ end
|
|
24
38
|
And you can see these in log:
|
25
39
|
|
26
40
|
```
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
|
42
|
+
user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
|
43
|
+
to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
|
30
44
|
```
|
31
45
|
|
32
46
|
|
33
|
-
### Track
|
47
|
+
### Track Association Calls
|
34
48
|
|
35
49
|
Or you can use `tap_assoc!`. This is very useful for tracking potential n+1 query calls, here’s a sample from my work
|
36
50
|
|
37
51
|
```ruby
|
38
|
-
tap_assoc!(order)
|
39
|
-
puts(payload.method_name_and_location)
|
40
|
-
end
|
52
|
+
tap_assoc!(order).and_print(:method_name_and_location)
|
41
53
|
```
|
42
54
|
|
43
55
|
```
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
56
|
+
payments FROM /RUBY_PATH/gems/2.6.0/gems/jsonapi-resources-0.9.10/lib/jsonapi/resource.rb:124
|
57
|
+
line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:44
|
58
|
+
effective_line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:110
|
59
|
+
amending_orders FROM /MY_PROJECT/app/models/order.rb:385
|
60
|
+
amends_order FROM /MY_PROJECT/app/models/order.rb:432
|
49
61
|
```
|
50
62
|
|
51
63
|
|
52
|
-
### Track
|
64
|
+
### Track Calls that Generates SQL Queries
|
53
65
|
|
54
66
|
`tap_sql!` method helps you track which method calls generate sql queries. This is particularly helpful when tracking calls created from a reused `ActiveRecord::Relation` object.
|
55
67
|
|
@@ -135,9 +147,18 @@ All tapping methods (start with `tap_`) takes a block and yield a `Payload` obje
|
|
135
147
|
- `trace` - stack trace of the call. Default is an empty array unless `with_trace_to` option is set
|
136
148
|
- `tp` - trace point object of this call
|
137
149
|
|
138
|
-
|
139
|
-
|
140
|
-
- `
|
150
|
+
|
151
|
+
#### Symbols for helpers
|
152
|
+
- `FROM` for method call’s location
|
153
|
+
- `<=` for arguments
|
154
|
+
- `=>` for return value
|
155
|
+
- `@` for defined class
|
156
|
+
|
157
|
+
#### Helpers
|
158
|
+
- `method_name_and_location` - `initialize FROM /PROJECT_PATH/tapping_device/spec/payload_spec.rb:7`
|
159
|
+
- `method_name_and_arguments` - `initialize <= {:name=>\"Stan\", :age=>25}`
|
160
|
+
- `method_name_and_return_value` - `ten => 10`
|
161
|
+
- `method_name_and_defined_class` - `initialize @ Student`
|
141
162
|
- `passed_at` -
|
142
163
|
```
|
143
164
|
Passed as 'object' in method ':initialize'
|
@@ -152,6 +173,15 @@ Passed as 'object' in method ':initialize'
|
|
152
173
|
at /Users/st0012/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/actionview-6.0.0/lib/action_view/helpers/tags/label.rb:60
|
153
174
|
```
|
154
175
|
|
176
|
+
- `detail_call_info`
|
177
|
+
|
178
|
+
```
|
179
|
+
initialize @ Student
|
180
|
+
<= {:name=>"Stan", :age=>25}
|
181
|
+
=> 25
|
182
|
+
FROM /Users/st0012/projects/tapping_device/spec/payload_spec.rb:7
|
183
|
+
```
|
184
|
+
|
155
185
|
|
156
186
|
### Options
|
157
187
|
- `with_trace_to: 10` - the number of traces we want to put into `trace`. Default is `nil`, so `trace` would be empty
|
@@ -159,24 +189,21 @@ Passed as 'object' in method ':initialize'
|
|
159
189
|
- `filter_by_paths: [/path/]` - only contain calls from the specified paths
|
160
190
|
|
161
191
|
```ruby
|
162
|
-
tap_on!(@post, exclude_by_paths: [/active_record/])
|
163
|
-
# this equals to `"Method: #{payload[:method_name]} line: #{payload[:filepath]}:#{payload[:line_number]}"`
|
164
|
-
puts(payload.method_name_and_location)
|
165
|
-
end
|
192
|
+
tap_on!(@post, exclude_by_paths: [/active_record/]).and_print(:method_name_and_location)
|
166
193
|
```
|
167
194
|
|
168
195
|
```
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
196
|
+
_read_attribute FROM /RUBY_PATH/gems/2.6.0/gems/activerecord-5.2.0/lib/active_record/attribute_methods/read.rb:40
|
197
|
+
name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
|
198
|
+
_read_attribute FROM /RUBY_PATH/gems/2.6.0/gems/activerecord-5.2.0/lib/active_record/attribute_methods/read.rb:40
|
199
|
+
user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
|
173
200
|
.......
|
174
201
|
|
175
202
|
# versus
|
176
203
|
|
177
|
-
|
178
|
-
|
179
|
-
|
204
|
+
name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
|
205
|
+
user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
|
206
|
+
to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
|
180
207
|
```
|
181
208
|
|
182
209
|
|
@@ -203,10 +230,7 @@ class PostsController < ApplicationController
|
|
203
230
|
before_action :set_post, only: [:show, :edit, :update, :destroy]
|
204
231
|
|
205
232
|
def show
|
206
|
-
tap_on!(@post)
|
207
|
-
# this equals to `"Method: #{payload[:method_name]} line: #{payload[:filepath]}:#{payload[:line_number]}"`
|
208
|
-
puts(payload.method_name_and_location)
|
209
|
-
end
|
233
|
+
tap_on!(@post).and_print(:method_name_and_location)
|
210
234
|
end
|
211
235
|
end
|
212
236
|
```
|
@@ -214,9 +238,9 @@ end
|
|
214
238
|
And you can see these in log:
|
215
239
|
|
216
240
|
```
|
217
|
-
|
218
|
-
|
219
|
-
|
241
|
+
name FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:5
|
242
|
+
user_id FROM /PROJECT_PATH/sample/app/views/posts/show.html.erb:10
|
243
|
+
to_param FROM /RUBY_PATH/gems/2.6.0/gems/actionpack-5.2.0/lib/action_dispatch/routing/route_set.rb:236
|
220
244
|
```
|
221
245
|
|
222
246
|
### `tap_passed!`
|
@@ -255,17 +279,15 @@ Passed as 'record_or_hash_or_array' in method ':polymorphic_method'
|
|
255
279
|
### `tap_assoc!`
|
256
280
|
|
257
281
|
```ruby
|
258
|
-
tap_assoc!(order)
|
259
|
-
puts(payload.method_name_and_location)
|
260
|
-
end
|
282
|
+
tap_assoc!(order).and_print(:method_name_and_location)
|
261
283
|
```
|
262
284
|
|
263
285
|
```
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
286
|
+
payments FROM /RUBY_PATH/gems/2.6.0/gems/jsonapi-resources-0.9.10/lib/jsonapi/resource.rb:124
|
287
|
+
line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:44
|
288
|
+
effective_line_items FROM /MY_PROJECT/app/models/line_item_container_helpers.rb:110
|
289
|
+
amending_orders FROM /MY_PROJECT/app/models/order.rb:385
|
290
|
+
amends_order FROM /MY_PROJECT/app/models/order.rb:432
|
269
291
|
```
|
270
292
|
|
271
293
|
### `tap_sql!`
|
@@ -37,12 +37,26 @@ class TappingDevice
|
|
37
37
|
"#{filepath}:#{line_number}"
|
38
38
|
end
|
39
39
|
|
40
|
-
|
41
|
-
|
40
|
+
SYMBOLS = {
|
41
|
+
location: "FROM",
|
42
|
+
return_value: "=>",
|
43
|
+
arguments: "<=",
|
44
|
+
defined_class: "@"
|
45
|
+
}
|
46
|
+
|
47
|
+
SYMBOLS.each do |name, symbol|
|
48
|
+
define_method "method_name_and_#{name}" do
|
49
|
+
"#{method_name} #{symbol} #{send(name)}"
|
50
|
+
end
|
42
51
|
end
|
43
52
|
|
44
|
-
def
|
45
|
-
|
53
|
+
def detail_call_info
|
54
|
+
<<~MSG
|
55
|
+
#{method_name_and_defined_class}
|
56
|
+
<= #{arguments}
|
57
|
+
=> #{return_value || "nil"}
|
58
|
+
FROM #{location}
|
59
|
+
MSG
|
46
60
|
end
|
47
61
|
end
|
48
62
|
end
|
data/lib/tapping_device.rb
CHANGED
@@ -21,6 +21,7 @@ class TappingDevice
|
|
21
21
|
|
22
22
|
def initialize(options = {}, &block)
|
23
23
|
@block = block
|
24
|
+
@output_block = nil
|
24
25
|
@options = process_options(options)
|
25
26
|
@calls = []
|
26
27
|
@disabled = false
|
@@ -45,6 +46,10 @@ class TappingDevice
|
|
45
46
|
track(record, condition: :tap_associations?)
|
46
47
|
end
|
47
48
|
|
49
|
+
def and_print(payload_method)
|
50
|
+
@output_block = -> (payload) { puts(payload.send(payload_method)) }
|
51
|
+
end
|
52
|
+
|
48
53
|
def set_block(&block)
|
49
54
|
@block = block
|
50
55
|
end
|
@@ -208,6 +213,8 @@ class TappingDevice
|
|
208
213
|
def record_call!(payload)
|
209
214
|
return if @disabled
|
210
215
|
|
216
|
+
@output_block.call(payload) if @output_block
|
217
|
+
|
211
218
|
if @block
|
212
219
|
root_device.calls << @block.call(payload)
|
213
220
|
else
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tapping_device
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- st0012
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|