method_call_tracer 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +16 -11
- data/lib/generators/method_tracer/templates/initializer.rb +3 -3
- data/lib/method_tracer/tracer.rb +27 -9
- data/lib/method_tracer/version.rb +1 -1
- data/run_tests.sh +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: deeb870dcd4aa81de135eb555d0001c94be527f8
|
4
|
+
data.tar.gz: e8a9ac1fcf43516060cbef76292a3d894a4546b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11ca20032353767f513a4b17895ff8d5fd5533680092fe0b5feddb9296fda1846c3a277125c698810e5ea62d62f5c69c2f130f6b8e9243b0f44eda6b474ea74d
|
7
|
+
data.tar.gz: db328e9510208b7ca663bfbcc9d46eef8d946d1751f3fe7c3b8adafb4adc572573221b207a1273792771405c4ed4cda13bdb9f8164c8238e7027314a8ed99d5f
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 1.0.0
|
4
|
+
|
5
|
+
- Accept a second, optional parameter in the initializer so we can short-circuit matching methods based on the class name for performance. This is so useful that the initializer's two arguments are now both keywords, indicating equal importance.
|
6
|
+
- MethodTracer::Tracer no longer creates TracePoints upon initialization. Use the new `#enable` method to begin tracing.
|
7
|
+
- Change output format to be even more machine-readable
|
8
|
+
|
9
|
+
## 0.2.0
|
10
|
+
|
11
|
+
- Rewrite to use Ruby's TracePoint instead of manually unbinding and rebinding methods. This has fewer side effects, but is much slower.
|
12
|
+
|
13
|
+
## 0.1.0
|
14
|
+
|
15
|
+
- Initial release
|
data/README.md
CHANGED
@@ -1,25 +1,34 @@
|
|
1
1
|
# MethodTracer
|
2
2
|
|
3
|
-
MethodTracer is a tool for detecting lines in an application that call certain methods, somewhat akin to the syscall monitoring functionality of strace(1).
|
3
|
+
MethodTracer is a tool for detecting lines in an application that call certain methods, somewhat akin to the syscall monitoring functionality of strace(1).
|
4
4
|
|
5
|
-
|
5
|
+
The most common use case is helping developers and testers focus their efforts when upgrading or changing gems in large applications.
|
6
|
+
|
7
|
+
MethodTracer's output is intended to be easily machine-readable.
|
6
8
|
|
7
9
|
**Note about gem name**: due to a naming collision on rubygems.org, this gem appears there as `method_call_tracer`.
|
8
10
|
|
9
11
|
## Usage
|
10
12
|
|
11
|
-
To attach tracers to methods, instantiate `MethodTracer::Tracer` objects
|
13
|
+
To attach tracers to methods, instantiate `MethodTracer::Tracer` objects and call `#enable`. For Rails applications, this can be done in the provided initializer.
|
14
|
+
|
15
|
+
The methods to be traced are specified by file pattern. You can optionally also specify a (partial) class name to speed up the matching process, which is recommended for performance. The comparison is a simple `String#include?`; no pattern matching is supported.
|
12
16
|
|
13
17
|
```ruby
|
14
|
-
# Trace all methods defined by the system installation of gibbon:
|
15
|
-
MethodTracer::Tracer.new('/var/lib/gems/2.3.0/gems/gibbon-2.2.4/')
|
18
|
+
# Trace all methods defined by the system installation of gibbon that also have "Gibbon" in the class name:
|
19
|
+
MethodTracer::Tracer.new(path: '/var/lib/gems/2.3.0/gems/gibbon-2.2.4/', name: 'Gibbon').enable
|
20
|
+
|
21
|
+
# Trace all methods defined by the system installation of gibbon, regardless of class name:
|
22
|
+
MethodTracer::Tracer.new(path: '/var/lib/gems/2.3.0/gems/gibbon-2.2.4/').enable
|
16
23
|
|
17
|
-
# Trace all methods defined by rbenv's 2.3.3 installation of activerecord:
|
18
|
-
MethodTracer::Tracer.new('/home/eddie/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/activerecord-5.0.7/')
|
24
|
+
# Trace all methods defined by rbenv's 2.3.3 installation of activerecord, regardless of class name:
|
25
|
+
MethodTracer::Tracer.new(path: '/home/eddie/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0/gems/activerecord-5.0.7/').enable
|
19
26
|
```
|
20
27
|
|
21
28
|
With tracers attached, exercise as much of the application as possible. Perhaps run the comprehensive test suite that you of course have.
|
22
29
|
|
30
|
+
Using file paths makes it simple to trace an entire gem because it includes methods defined in the "namespace" of a different gem. For example, if a hypothetical gem `activerecord-extension` defines some methods on the class `ActiveRecord`, we still have the ability to trace only the methods from `activerecord-extension` without capturing the methods from `activerecord`.
|
31
|
+
|
23
32
|
## Configuration
|
24
33
|
|
25
34
|
MethodTracer supports the following configuration options:
|
@@ -28,10 +37,6 @@ MethodTracer supports the following configuration options:
|
|
28
37
|
|
29
38
|
`MethodTracer::Config.output_file`: A filename or `IO` or `StringIO` object where the report output should be sent. Defaults to `$stdout`.
|
30
39
|
|
31
|
-
## Limitations
|
32
|
-
|
33
|
-
MethodTracer theoretically does not interfere with the original behavior of methods being traced. However, certain gems are known to misbehave when the tracing logic is monkeypatched in, and MethodTracer will refuse to trace those gems. Furthermore, any methods defined after the `MethodTracer::Tracer` is instantiated will remain untraced.
|
34
|
-
|
35
40
|
## Installation
|
36
41
|
|
37
42
|
Add this line to your application's Gemfile:
|
@@ -8,6 +8,6 @@ MethodTracer::Config.app_path = Rails.application.paths.path.to_s
|
|
8
8
|
# like `$stdout`.
|
9
9
|
# MethodTracer::Config.output_file = 'output_file_2.log'
|
10
10
|
|
11
|
-
# Create a MethodTracer::
|
12
|
-
# MethodTracer::Tracer.new('/var/lib/gems/2.3.0/gems/gibbon-2.2.4/
|
13
|
-
# MethodTracer::Tracer.new('/var/lib/gems/2.3.0/gems/other_gem-1.0.0/
|
11
|
+
# Create a MethodTracer::Tracer object for every gem to be spied on
|
12
|
+
# MethodTracer::Tracer.new(path: '/var/lib/gems/2.3.0/gems/gibbon-2.2.4/', name: 'Gibbon').enable
|
13
|
+
# MethodTracer::Tracer.new(path: '/var/lib/gems/2.3.0/gems/other_gem-1.0.0/').enable
|
data/lib/method_tracer/tracer.rb
CHANGED
@@ -2,24 +2,26 @@ require 'where_is'
|
|
2
2
|
|
3
3
|
module MethodTracer
|
4
4
|
class Tracer
|
5
|
-
def initialize(
|
6
|
-
@target_path =
|
5
|
+
def initialize(path:, name: nil)
|
6
|
+
@target_path = path
|
7
|
+
@target_name = name
|
8
|
+
end
|
7
9
|
|
10
|
+
def enable
|
8
11
|
@tracer = TracePoint.trace(:call) do |tp|
|
9
12
|
record_call_if_interesting(tp)
|
10
13
|
end
|
11
14
|
end
|
12
15
|
|
13
16
|
def record_call_if_interesting(tp)
|
14
|
-
return unless
|
17
|
+
return unless method_is_interesting?(tp.defined_class, tp.method_id)
|
15
18
|
|
16
19
|
locations = caller_locations.select { |loc| loc.path.start_with?(Config.app_path) }
|
17
20
|
return if locations.empty?
|
18
21
|
|
19
|
-
outfile.write "#{
|
20
|
-
locations.
|
21
|
-
|
22
|
-
end
|
22
|
+
outfile.write "#{tp.defined_class} :#{tp.method_id} "
|
23
|
+
outfile.write locations.map { |loc| "#{loc.path}:#{loc.lineno}" }.join('; ')
|
24
|
+
outfile.write "\n"
|
23
25
|
end
|
24
26
|
|
25
27
|
def outfile
|
@@ -35,12 +37,28 @@ module MethodTracer
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
def
|
40
|
+
def method_is_interesting?(candidate_class, method_id)
|
41
|
+
candidate_name = if candidate_class.instance_of?(Class)
|
42
|
+
candidate_class.name
|
43
|
+
else
|
44
|
+
candidate_class.class.name
|
45
|
+
end
|
46
|
+
|
47
|
+
# short circuit if possible for speed
|
48
|
+
return false if !@target_name.nil? &&
|
49
|
+
!candidate_name.nil? &&
|
50
|
+
!candidate_name.include?(@target_name)
|
51
|
+
|
52
|
+
method_is_defined_in_target_path(candidate_class, method_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_is_defined_in_target_path(candidate_class, method_id)
|
39
56
|
begin
|
40
|
-
location = Where.is(candidate_class)
|
57
|
+
location = Where.is(candidate_class, method_id)
|
41
58
|
rescue NameError
|
42
59
|
return false
|
43
60
|
end
|
61
|
+
|
44
62
|
location[:file].start_with?(@target_path)
|
45
63
|
end
|
46
64
|
end
|
data/run_tests.sh
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: method_call_tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eddie Lebow
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: where_is
|
@@ -50,6 +50,7 @@ extra_rdoc_files: []
|
|
50
50
|
files:
|
51
51
|
- ".gitignore"
|
52
52
|
- ".rubocop.yml"
|
53
|
+
- CHANGELOG.md
|
53
54
|
- Gemfile
|
54
55
|
- README.md
|
55
56
|
- Rakefile
|