source_route 0.1.8 → 0.2.0
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/Guardfile +23 -0
- data/README.md +3 -6
- data/Rakefile +1 -1
- data/examples/debug_how_logger_object_init_when_rails_start.rb +23 -0
- data/examples/show_init_files_when_rails_server_start.rb +2 -0
- data/examples/show_task_trace_in_rails.rb +1 -1
- data/lib/source_route/core_ext.rb +1 -7
- data/lib/source_route/formats/html.rb +4 -4
- data/lib/source_route/formats/html_semantic.slim +242 -0
- data/lib/source_route/generate_result.rb +120 -57
- data/lib/source_route/jsonify.rb +2 -1
- data/lib/source_route/tp_result.rb +142 -24
- data/lib/source_route/tp_result_chain.rb +26 -32
- data/lib/source_route/version.rb +1 -1
- data/lib/source_route/wrapper.rb +22 -26
- data/lib/source_route.rb +20 -10
- data/source_route.gemspec +4 -1
- data/test/source_route_test.rb +39 -43
- metadata +52 -8
- data/lib/source_route/formats/html_template.slim +0 -229
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a900afbf3890bf31f01041e72ac6a65f61f3a477
|
4
|
+
data.tar.gz: 85e3915fb47c64ac5cbbe9312c2435a4720758f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91e0b7a0a43e00dddf0d1b8f278324c197f9d62179c066d490c8049913c7eb19e32bb500966938ae2914a5b76541caa77e84508da96b9454dd5a667bcfdeb8ec
|
7
|
+
data.tar.gz: bdc789e2660545ec2b6c0aaac975d2b276bbaf618d4414d46a944fafe383eccd8e9ba1cf38b92a6564541d4ff69e2ce246f3a00da3047cf499f63d695db470b7
|
data/Guardfile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(lib) \
|
6
|
+
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
guard :shell do
|
18
|
+
watch(%r{^lib/(.+)/*$}) { `rake` }
|
19
|
+
end
|
20
|
+
|
21
|
+
guard :livereload, grace_period: 0.5, override_url: true do
|
22
|
+
watch(%r{.+\.(css|js|html)})
|
23
|
+
end
|
data/README.md
CHANGED
@@ -62,7 +62,7 @@ It will output the trace when you run the application.
|
|
62
62
|
see more usage in examples.
|
63
63
|
see full usage in examples/study_callback.rb
|
64
64
|
|
65
|
-

|
66
66
|
|
67
67
|
## Why
|
68
68
|
|
@@ -93,12 +93,9 @@ Finally, I expect my working style can changes from searching workaround from in
|
|
93
93
|
|
94
94
|
### TODO
|
95
95
|
|
96
|
-
|
97
|
-
|
98
|
-
Is it possible to easily open only direct child
|
99
|
-
Animation when child was click.
|
96
|
+
Cleanup Code and remove useless comments.
|
100
97
|
|
101
|
-
|
98
|
+
Dynamic indent when new child level comes.
|
102
99
|
|
103
100
|
Add debug option to provide more verbose messages of what has happened
|
104
101
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# usage: cover bin/rails with this file and run bundle exec rails c to start your console then exit your console
|
4
|
+
|
5
|
+
require 'rails'
|
6
|
+
|
7
|
+
require 'source_route'
|
8
|
+
|
9
|
+
SourceRoute.enable do
|
10
|
+
defined_class 'ActiveSupport::Configurable'
|
11
|
+
method_id :logger
|
12
|
+
full_feature 10
|
13
|
+
end
|
14
|
+
|
15
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
16
|
+
|
17
|
+
require_relative '../config/boot'
|
18
|
+
|
19
|
+
require 'rails/commands'
|
20
|
+
|
21
|
+
at_exit do
|
22
|
+
SourceRoute.output_html
|
23
|
+
end
|
@@ -7,17 +7,17 @@ module SourceRoute
|
|
7
7
|
|
8
8
|
def self.slim_render(wrapper)
|
9
9
|
result_config = wrapper.condition.result_config
|
10
|
-
template_path = File.expand_path "../
|
10
|
+
template_path = File.expand_path "../html_semantic.slim", __FILE__
|
11
11
|
slim_template = Slim::Template.new(template_path, pretty: true)
|
12
12
|
|
13
13
|
filename = result_config[:filename] || "#{Time.now.strftime('%H')}-source-route.html"
|
14
14
|
|
15
15
|
if result_config.import_return_to_call and wrapper.condition.has_call_and_return_event
|
16
|
-
wrapper.import_return_value_to_call_chain
|
17
|
-
wrapper.treeize_call_chain
|
16
|
+
wrapper.result_builder.import_return_value_to_call_chain
|
17
|
+
wrapper.result_builder.treeize_call_chain
|
18
18
|
end
|
19
19
|
# TODO: any exception triggered in render method will be absorb totally, how to fix it?
|
20
|
-
html_output_str = slim_template.render(wrapper)
|
20
|
+
html_output_str = slim_template.render(wrapper.result_builder)
|
21
21
|
File.open(filename, 'w') do |f|
|
22
22
|
f << html_output_str
|
23
23
|
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title Source Route Result
|
5
|
+
link rel="stylesheet" href="https://cdn.rawgit.com/Urigo/angular-spinkit/master/build/angular-spinkit.min.css"
|
6
|
+
link rel="stylesheet" href="https://cdn.rawgit.com/mohsen1/json-formatter/master/dist/json-formatter.css"
|
7
|
+
link rel="stylesheet" href="http://oss.maxcdn.com/semantic-ui/2.0.7/semantic.min.css"
|
8
|
+
|
9
|
+
script async=true src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.js"
|
10
|
+
script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"
|
11
|
+
script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"
|
12
|
+
script async=true src="http://oss.maxcdn.com/semantic-ui/2.0.7/semantic.min.js"
|
13
|
+
|
14
|
+
css:
|
15
|
+
.call-level-0 {}
|
16
|
+
.item.trace.call-level-1 { padding-left: 50px }
|
17
|
+
.item.trace.call-level-2 { padding-left: 100px }
|
18
|
+
.item.trace.call-level-3 { padding-left: 150px }
|
19
|
+
.item.trace.call-level-4 { padding-left: 200px }
|
20
|
+
.item.trace.call-level-5 { padding-left: 250px }
|
21
|
+
.item.trace.call-level-6 { padding-left: 300px }
|
22
|
+
.item.trace.call-level-7 { padding-left: 300px }
|
23
|
+
// level more than 7 seems not reasonable
|
24
|
+
|
25
|
+
body(ng-app="SourceRoute" ng-controller="MainCtrl" ng-cloak)
|
26
|
+
|
27
|
+
.ui.menu.pointing.stackable.attached
|
28
|
+
.ui.container
|
29
|
+
.item
|
30
|
+
a.navbar-brand(href="#" ng-click="::resetTraceFilter()") ALL
|
31
|
+
.item(ng-repeat="event in tpEvents" ng-class="{active: event == traceFilter.event}")
|
32
|
+
a(href="#" ng-click="traceFilter.event = event" ng-bind="::event")
|
33
|
+
.item
|
34
|
+
.ui.buttons
|
35
|
+
button.ui.labeled.icon.button.olive(ng-click="outlineTrace()" ng-class="{loading: outlineTraceLoading}")
|
36
|
+
i.angle.double.right.icon
|
37
|
+
span OutLine
|
38
|
+
.or
|
39
|
+
button.ui.right.labeled.icon.button.green(ng-click="expandAllTrace()" ng-class="{loading: expandAllTraceLoading}")
|
40
|
+
i.angle.double.down.icon
|
41
|
+
span Expand
|
42
|
+
.right.menu
|
43
|
+
.item
|
44
|
+
span Trace Count
|
45
|
+
.ui.teal.pointing.left.label(ng-bind="currentCounter()")
|
46
|
+
|
47
|
+
.ui.container
|
48
|
+
.row
|
49
|
+
.ui.relaxed.items(ng-class="{{traceFilter.event}}")
|
50
|
+
.item.trace(ng-repeat="trace in traces | filter:traceFilter:true | filter:childParentFilterFn" ng-class="callLevelClass(trace)" ng-controller="TpTraceCtrl")
|
51
|
+
.content(ng-init="showMoreDetail = false")
|
52
|
+
.ui.segment.left.floated.padded
|
53
|
+
.header
|
54
|
+
span(ng-bind="::tpSelfList[trace.tp_self_refer]")
|
55
|
+
i.circle.icon.grey(style="font-size: 0.3em")
|
56
|
+
span.method-value(ng-bind="::trace.method_id")
|
57
|
+
/ workaround for return_value is 'false' and return_value always to be string when existed
|
58
|
+
.meta(ng-if="trace.hasOwnProperty('return_value')")
|
59
|
+
i.icon.pointing.right.small
|
60
|
+
json-formatter(open="1" json="::trace.return_value")
|
61
|
+
.description
|
62
|
+
.ui.vertical.buttons.basic
|
63
|
+
button.ui.labeled.icon.button(ng-show="::containsDetail(trace)" ng-click="showMoreDetail = !showMoreDetail")
|
64
|
+
i.info.icon
|
65
|
+
span Details
|
66
|
+
button.ui.labeled.icon.button(ng-if="::hasChild()" ng-click="toggleChild()" ng-class="{loading: togglingChild}")
|
67
|
+
i.icon.angle.down(ng-show="trace.childOpened")
|
68
|
+
i.icon.angle.right(ng-hide="trace.childOpened")
|
69
|
+
span Child
|
70
|
+
pulse-spinner(ng-show="togglingChild")
|
71
|
+
|
72
|
+
.details.right.floated(ng-if="showMoreDetail")
|
73
|
+
.ui.segments(style="border-color: blue")
|
74
|
+
.ui.segment(ng-if="::trace.hasOwnProperty('return_value')")
|
75
|
+
.ui.grey.right.ribbon.label Return Value
|
76
|
+
json-formatter(json="::trace.return_value")
|
77
|
+
.ui.segment(ng-if="::containsOtherAttrs(trace)")
|
78
|
+
.ui.orange.right.ribbon.label Trace Attrs
|
79
|
+
json-formatter(open="1" json="::plusTraceAttrs[trace.order_id]")
|
80
|
+
.ui.segment(ng-if="::trace.params_var")
|
81
|
+
.ui.teal.right.ribbon.label Params Var
|
82
|
+
json-formatter(open="1" json="::trace.params_var")
|
83
|
+
.ui.segment(ng-if="::trace.local_var")
|
84
|
+
.ui.teal.right.ribbon.label Local Var
|
85
|
+
json-formatter(open="1" json="::trace.local_var")
|
86
|
+
.ui.segment(ng-if="::trace.instance_var")
|
87
|
+
.ui.blue.right.ribbon.label Instance Var
|
88
|
+
json-formatter(open="1" json="::trace.instance_var")
|
89
|
+
|
90
|
+
script src="https://cdn.rawgit.com/Urigo/angular-spinkit/master/build/angular-spinkit.min.js"
|
91
|
+
script src="https://cdn.rawgit.com/mohsen1/json-formatter/master/dist/json-formatter.js"
|
92
|
+
// script async src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-sanitize.js"
|
93
|
+
|
94
|
+
javascript:
|
95
|
+
sourceRoute = angular.module('SourceRoute', ['jsonFormatter', 'angular-spinkit'])
|
96
|
+
sourceRoute.controller('MainCtrl', function($scope, $filter, $timeout) {
|
97
|
+
|
98
|
+
// setup different color on menu item may not be a good solution
|
99
|
+
// $scope.menuColorList = ['yellow', 'olive', 'green', 'teal', 'violet', 'purple', 'brown']
|
100
|
+
$scope.trimString = function(str, length) {
|
101
|
+
return str.length > length ? str.substring(0, length - 3) + '...' : str;
|
102
|
+
}
|
103
|
+
|
104
|
+
$scope.traces = angular.element("#trace-data").data('trace')
|
105
|
+
$scope.tpSelfList = angular.element("#trace-data").data('tp-self-caches')
|
106
|
+
$scope.tpEvents = angular.element("#trace-data").data('tp-events')
|
107
|
+
$scope.childParentFilter = { hide_trace_ids: [] }
|
108
|
+
|
109
|
+
$scope.childParentFilterFn = function(trace) {
|
110
|
+
if (!trace.hasOwnProperty('parent_ids')) {
|
111
|
+
return true;
|
112
|
+
}
|
113
|
+
if (trace.parent_ids.length == 0) {
|
114
|
+
return true;
|
115
|
+
} else {
|
116
|
+
var shared_hide_parents = _.intersection(trace.parent_ids, $scope.childParentFilter.hide_trace_ids);
|
117
|
+
if (shared_hide_parents.length > 0 ) {
|
118
|
+
return false;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
return true;
|
122
|
+
}
|
123
|
+
|
124
|
+
$scope.expandAllTrace = function() {
|
125
|
+
$scope.expandAllTraceLoading = true
|
126
|
+
$timeout(function() {
|
127
|
+
_.each($scope.traces, function(trace) { trace.childOpened = true; });
|
128
|
+
$scope.childParentFilter.hide_trace_ids = [];
|
129
|
+
$scope.expandAllTraceLoading = false
|
130
|
+
$scope.expandAllTraceLoading = false
|
131
|
+
}, 100)
|
132
|
+
}
|
133
|
+
|
134
|
+
$scope.outlineTrace = function() {
|
135
|
+
$scope.outlineTraceLoading = true
|
136
|
+
$scope.childParentFilter.hide_trace_ids = [];
|
137
|
+
_.chain($scope.traces).filter({parent_length: 0, event: $scope.traceFilter.event})
|
138
|
+
.each(function(trace) {
|
139
|
+
trace.childOpened = false;
|
140
|
+
$scope.childParentFilter.hide_trace_ids.push(trace.order_id) }
|
141
|
+
).value()
|
142
|
+
$scope.outlineTraceLoading = false
|
143
|
+
}
|
144
|
+
|
145
|
+
$scope.traceFilter = {event: $scope.tpEvents[0]}
|
146
|
+
if ($scope.tpEvents.length == 1 && angular.isUndefined($scope.traces[0].event)) {
|
147
|
+
_.each($scope.traces, function(trace) {
|
148
|
+
trace.event = $scope.tpEvents[0]
|
149
|
+
})
|
150
|
+
}
|
151
|
+
|
152
|
+
$scope.definedClasses = _.uniq(_.map($scope.traces, 'defined_class'))
|
153
|
+
|
154
|
+
$scope.callLevelClass = function(trace) {
|
155
|
+
if (trace.parent_length > 7) {
|
156
|
+
return 'call-level-7';
|
157
|
+
} else {
|
158
|
+
return 'call-level-' + trace.parent_length;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
$scope.resetTraceFilter = function() {
|
163
|
+
$scope.traceFilter = {};
|
164
|
+
}
|
165
|
+
|
166
|
+
$scope.currentCounter = function() {
|
167
|
+
return $filter('filter')($scope.traces, $scope.traceFilter, true).length;
|
168
|
+
}
|
169
|
+
|
170
|
+
$scope.containsOtherAttrs = function(trace) {
|
171
|
+
return trace.hasOwnProperty('path') || trace.hasOwnProperty('lineno')
|
172
|
+
}
|
173
|
+
|
174
|
+
$scope.containsDetail = function(trace) {
|
175
|
+
return $scope.containsOtherAttrs(trace) || trace.hasOwnProperty('local_var') ||
|
176
|
+
trace.hasOwnProperty('instance_var')
|
177
|
+
}
|
178
|
+
|
179
|
+
combinedAttrs = function(trace) {
|
180
|
+
var attrs = {}
|
181
|
+
if (trace.hasOwnProperty('lineno') && trace.hasOwnProperty('path')) {
|
182
|
+
attrs.method_defined_on = trace.path + ":" + trace.lineno;
|
183
|
+
} else if (trace.hasOwnProperty('path')) {
|
184
|
+
attrs.method_defined_on = trace.path;
|
185
|
+
}
|
186
|
+
if (trace.hasOwnProperty('defined_class')) {
|
187
|
+
attrs.method_defined_in = trace.defined_class;
|
188
|
+
}
|
189
|
+
return attrs;
|
190
|
+
}
|
191
|
+
|
192
|
+
$scope.plusTraceAttrs = _.map($scope.traces, combinedAttrs)
|
193
|
+
|
194
|
+
$scope.outlineTrace();
|
195
|
+
})
|
196
|
+
|
197
|
+
sourceRoute.controller('TpTraceCtrl', function($scope, $timeout) {
|
198
|
+
|
199
|
+
$scope.toggleChild = function() {
|
200
|
+
$scope.togglingChild = true
|
201
|
+
$timeout(function() {
|
202
|
+
if ($scope.trace.childOpened) {
|
203
|
+
$scope.hideChild();
|
204
|
+
$scope.togglingChild = false
|
205
|
+
} else {
|
206
|
+
$scope.showChild();
|
207
|
+
$scope.togglingChild = false
|
208
|
+
}
|
209
|
+
}, 0)
|
210
|
+
}
|
211
|
+
|
212
|
+
$scope.showChild = function() {
|
213
|
+
$scope.trace.childOpened = true;
|
214
|
+
_.pull($scope.childParentFilter.hide_trace_ids, $scope.trace.order_id);
|
215
|
+
if ($scope.trace.direct_child_order_ids.length > 0) {
|
216
|
+
$scope.childParentFilter.hide_trace_ids.push($scope.trace.direct_child_order_ids);
|
217
|
+
$scope.childParentFilter.hide_trace_ids = _.chain($scope.childParentFilter.hide_trace_ids).flatten().uniq().value();
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
$scope.hideChild = function() {
|
222
|
+
$scope.trace.childOpened = false;
|
223
|
+
$scope.childParentFilter.hide_trace_ids.push($scope.trace.order_id);
|
224
|
+
if ($scope.trace.direct_child_order_ids.length > 0) {
|
225
|
+
_.each($scope.trace.direct_child_order_ids, function(ele) {
|
226
|
+
_.pull($scope.childParentFilter.hide_trace_ids, ele);
|
227
|
+
});
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
$scope.hasChild = function() {
|
232
|
+
return _.find($scope.traces, function(trace) {
|
233
|
+
return _.contains(trace.parent_ids, $scope.trace.order_id)
|
234
|
+
});
|
235
|
+
}
|
236
|
+
})
|
237
|
+
|
238
|
+
.data-collect
|
239
|
+
/ dont use local_trace_data.to_json, because ActiveSupport override it and can introduce unexpected crash for some data
|
240
|
+
#trace-data(data-trace="#{jsonify_tp_result_chain}"
|
241
|
+
data-tp-events="#{jsonify_events}"
|
242
|
+
data-tp-self-caches="#{jsonify_tp_self_caches}")
|
@@ -1,11 +1,23 @@
|
|
1
1
|
module SourceRoute
|
2
|
-
|
2
|
+
# How it work
|
3
|
+
# 0. Config collect route options
|
4
|
+
# 1. Proxy generate TracePoint Filter
|
5
|
+
# 2. Proxy generate TracePoint Monitor Block
|
6
|
+
# 3. Generator collect Wanted TracePoint
|
7
|
+
# 4. Parse and Generate Useful data from wanted TracePoint
|
8
|
+
# 5. Output data with correct format
|
3
9
|
class GenerateResult
|
4
10
|
|
11
|
+
attr_reader :tp_result_chain, :tp_self_caches, :collected_data
|
12
|
+
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
def_delegators :@tp_result_chain, :import_return_value_to_call_chain, :treeize_call_chain, :call_chain, :return_chain, :parent_length_list
|
16
|
+
|
5
17
|
Config = Struct.new(:format, :show_additional_attrs,
|
6
18
|
:include_local_var, :include_instance_var,
|
7
19
|
:filename, :import_return_to_call) do
|
8
|
-
def initialize(f
|
20
|
+
def initialize(f=:test, s=[], ilr=false, iiv=false)
|
9
21
|
super(f, s, ilr, iiv)
|
10
22
|
end
|
11
23
|
end
|
@@ -32,39 +44,48 @@ module SourceRoute
|
|
32
44
|
|
33
45
|
@config = @wrapper.condition.result_config
|
34
46
|
|
35
|
-
@
|
47
|
+
@tp_result_chain = TpResultChain.new
|
48
|
+
|
49
|
+
@tp_self_caches = []
|
50
|
+
@wanted_attributes = {}
|
36
51
|
end
|
37
52
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
53
|
+
# it cached and only calculate once for one trace point block round
|
54
|
+
def self.wanted_attributes(eve)
|
55
|
+
event = eve.to_sym
|
56
|
+
@wanted_attributes.fetch event do
|
57
|
+
attrs = DEFAULT_ATTRS[event] + Array(SourceRoute.wrapper.condition.result_config.show_additional_attrs)
|
58
|
+
attrs.push(:event)
|
59
|
+
@wanted_attributes[event] = attrs.uniq
|
60
|
+
@wanted_attributes[event]
|
61
|
+
end
|
42
62
|
end
|
43
63
|
|
44
|
-
def
|
45
|
-
@
|
46
|
-
collect_tp_data
|
47
|
-
collect_tp_self # NEED more check. Does TracePoint support self for all events?
|
48
|
-
collect_local_var_data if @config[:include_local_var]
|
49
|
-
collect_instance_var_data if @config[:include_instance_var]
|
50
|
-
@collect_data
|
64
|
+
def self.clear_wanted_attributes
|
65
|
+
@wanted_attributes = {}
|
51
66
|
end
|
52
67
|
|
53
68
|
def output(tp_ins)
|
54
|
-
|
55
69
|
format = @config.format
|
56
70
|
format = format.to_sym if format.respond_to? :to_sym
|
57
71
|
|
72
|
+
assign_tp_self_caches(tp_ins)
|
73
|
+
# we cant call method on tp_ins outside of track block,
|
74
|
+
# so we have to run it immediately
|
75
|
+
|
76
|
+
@collected_data = TpResult.new(tp_ins)
|
77
|
+
|
58
78
|
case format
|
59
|
-
when :
|
60
|
-
|
61
|
-
when :console # need @collect_data
|
62
|
-
console_put
|
79
|
+
when :console
|
80
|
+
console_put(tp_ins)
|
63
81
|
when :html
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
|
82
|
+
# we cant generate html right now becase the tp collection is still in process
|
83
|
+
# so we collect tp here
|
84
|
+
@tp_result_chain.push(TpResult.new(tp_ins))
|
85
|
+
when :silence, :none
|
86
|
+
# do nothing at now
|
87
|
+
when :test
|
88
|
+
@tp_result_chain.push(TpResult.new(tp_ins))
|
68
89
|
when :stack_overflow
|
69
90
|
console_stack_overflow
|
70
91
|
when Proc
|
@@ -75,52 +96,94 @@ module SourceRoute
|
|
75
96
|
end
|
76
97
|
end
|
77
98
|
|
78
|
-
|
99
|
+
# def build(trace_point_instance)
|
100
|
+
# TpResult.new(trace_point_instance)
|
101
|
+
# # tp_result.collect_self
|
79
102
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
103
|
+
# # @tp = trace_point_instance
|
104
|
+
# # collect_tp_data
|
105
|
+
# # collect_tp_self # NEED more check. Does TracePoint support self for all events?
|
106
|
+
# # collect_local_var_data if @config[:include_local_var]
|
107
|
+
# # collect_instance_var_data if @config[:include_instance_var]
|
108
|
+
# # @collected_data
|
109
|
+
# end
|
110
|
+
|
111
|
+
# def collect_tp_result
|
112
|
+
# tp_result = TpResult.new(tp)
|
113
|
+
# end
|
88
114
|
|
89
115
|
# include? will evaluate @tp.self, if @tp.self is AR::Relation, it could cause problems
|
90
116
|
# So that's why I use object_id as replace
|
91
|
-
def
|
92
|
-
unless
|
93
|
-
|
117
|
+
def assign_tp_self_caches(tp_ins)
|
118
|
+
unless tp_self_caches.find { |tp_cache| tp_cache.object_id.equal? tp_ins.self.object_id }
|
119
|
+
tp_self_caches.push tp_ins.self
|
94
120
|
end
|
95
|
-
@collect_data[:tp_self] = @wrapper.tp_self_caches.map(&:__id__).index(@tp.self.__id__)
|
96
121
|
end
|
97
122
|
|
98
|
-
def
|
99
|
-
|
123
|
+
def jsonify_events
|
124
|
+
Oj.dump(@wrapper.condition.events.map(&:to_s))
|
125
|
+
end
|
100
126
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@collect_data.merge!(local_var: local_var_hash)
|
107
|
-
end
|
127
|
+
def jsonify_tp_result_chain
|
128
|
+
Oj.dump(tp_result_chain.chain.map(&:to_hash))
|
129
|
+
# tp_result_chain.to_json
|
130
|
+
# json_array = tp_result_chain.map { |result| Jsonify.dump(result) }
|
131
|
+
# '[ ' + json_array.join(',') + ' ]'
|
108
132
|
end
|
109
133
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
instance_var_hash[key] = @tp.self.instance_variable_get(key).source_route_display
|
114
|
-
end
|
115
|
-
if instance_var_hash != {}
|
116
|
-
@collect_data.merge!(instance_var: instance_var_hash)
|
117
|
-
end
|
134
|
+
def jsonify_tp_self_caches
|
135
|
+
Oj.dump(tp_self_caches.clone
|
136
|
+
.map(&:to_s))
|
118
137
|
end
|
119
138
|
|
120
|
-
|
139
|
+
private
|
140
|
+
|
141
|
+
# def collect_tp_data
|
142
|
+
# tp_data = wanted_attributes(@tp.event).inject({}) do |memo, key|
|
143
|
+
# memo[key.to_sym] = @tp.send(key) if @tp.respond_to?(key)
|
144
|
+
# memo
|
145
|
+
# end
|
146
|
+
# @collected_data = TpResult.new(tp_data)
|
147
|
+
# puts @collected_data.inspect if @wrapper.condition.is_debug?
|
148
|
+
# end
|
149
|
+
|
150
|
+
# def collect_tp_self(tp)
|
151
|
+
# unless tp_self_caches.find { |tp_cache| tp_cache.object_id.equal? tp.self.object_id }
|
152
|
+
# tp_self_caches.push tp.self
|
153
|
+
# end
|
154
|
+
# @collected_data[:tp_self_refer] = tp_self_caches.map(&:__id__).index(tp.self.__id__)
|
155
|
+
# end
|
156
|
+
|
157
|
+
# def collect_local_var_data
|
158
|
+
# local_var_hash = {}
|
159
|
+
# # Warn: @tp.binding.eval('local_variables') =! @tp.binding.send('local_variables')
|
160
|
+
# @tp.binding.eval('local_variables').each do |v|
|
161
|
+
# # I need rememeber why i need source_route_display
|
162
|
+
# local_var_hash[v] = @tp.binding.local_variable_get(v).source_route_display
|
163
|
+
# end
|
164
|
+
# if local_var_hash != {}
|
165
|
+
# @collected_data.merge!(local_var: local_var_hash)
|
166
|
+
# end
|
167
|
+
# end
|
168
|
+
|
169
|
+
# def collect_instance_var_data
|
170
|
+
# instance_var_hash = {}
|
171
|
+
# @tp.self.instance_variables.each do |key|
|
172
|
+
# instance_var_hash[key] = @tp.self.instance_variable_get(key).source_route_display
|
173
|
+
# end
|
174
|
+
# if instance_var_hash != {}
|
175
|
+
# @collected_data.merge!(instance_var: instance_var_hash)
|
176
|
+
# end
|
177
|
+
# end
|
178
|
+
|
179
|
+
def console_put(tp)
|
121
180
|
ret = []
|
122
|
-
ret << "#{
|
123
|
-
|
181
|
+
ret << "#{collected_data.defined_class.inspect}##{collected_data.method_id}"
|
182
|
+
left_attrs = self.class.wanted_attributes(tp.event) - [:defined_class, :method_id]
|
183
|
+
left_values = left_attrs.inject({}) do |memo, key|
|
184
|
+
memo[key] = collected_data.send(key)
|
185
|
+
memo
|
186
|
+
end
|
124
187
|
unless left_values == {}
|
125
188
|
ret << left_values
|
126
189
|
end
|
@@ -128,7 +191,7 @@ module SourceRoute
|
|
128
191
|
end
|
129
192
|
|
130
193
|
def console_stack_overflow
|
131
|
-
ap "#{
|
194
|
+
ap "#{collected_data.defined_class.inspect}##{collected_data.method_id}"
|
132
195
|
end
|
133
196
|
|
134
197
|
end # END GenerateResult
|