source_route 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/README.md +12 -17
- data/lib/source_route.rb +8 -4
- data/lib/source_route/config.rb +17 -6
- data/lib/source_route/formats/html.rb +1 -3
- data/lib/source_route/formats/html_semantic.slim +13 -12
- data/lib/source_route/formats/html_semantic_vue.slim +105 -0
- data/lib/source_route/generate_result.rb +14 -13
- data/lib/source_route/json_overrides/activerecord_associations_association.rb +30 -24
- data/lib/source_route/proxy.rb +5 -5
- data/lib/source_route/rails_plugins/source_track_middleware.rb +7 -8
- data/lib/source_route/tp_result.rb +2 -0
- data/lib/source_route/{tp_result_chain.rb → trace_chain.rb} +2 -2
- data/lib/source_route/{tp_filter.rb → trace_filter.rb} +13 -4
- data/lib/source_route/version.rb +1 -1
- data/source_route.gemspec +0 -1
- data/test/sample_app.rb +9 -0
- data/test/source_route/config_test.rb +9 -7
- data/test/source_route/{tp_filter_test.rb → trace_filter_test.rb} +11 -11
- data/test/source_route_test.rb +39 -27
- metadata +8 -24
- data/lib/source_route/formats/html_semantic.slim.failtry +0 -257
- data/lib/source_route/jsonify.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 744e671ef5af028f1bc8432482de55af9ab6c0a2
|
4
|
+
data.tar.gz: 32c60f705394c3a93d78a0bb27add38648ef36b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7656687526f1f1c241a9a868d5337457466757ab02117fc1a2f5c936c8138eca4760e0693d0c6648c38dd0046b7dcecccabb0bc1421234ffa1303c17e644fbf4
|
7
|
+
data.tar.gz: b9c93cc92da3800396820350d41cf0a1caa8b36f78444899eae3e572d6689ff8393d63d93edd0971dbc8e995137d91470ddb1efccb62328066571e5d7269b32b
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -26,9 +26,9 @@ Or install it yourself as:
|
|
26
26
|
|
27
27
|
SourceRoute.trace(output_format: :console, event: :c_call) { 'abc'.upcase }
|
28
28
|
|
29
|
-
#### In rails console
|
29
|
+
#### In rails console or test code
|
30
30
|
|
31
|
-
SourceRoute.trace(defined_class:
|
31
|
+
SourceRoute.trace(defined_class: 'ActiveRecord::Attribute', output_format: :html) { User.new }
|
32
32
|
|
33
33
|
It will generate a html file, open it and you can get the trace of User.new
|
34
34
|
|
@@ -42,10 +42,11 @@ you will get a different trace file.
|
|
42
42
|
full_feature
|
43
43
|
filename 'tmp/capture_wanted.html'
|
44
44
|
end
|
45
|
-
|
45
|
+
# Following is your code
|
46
|
+
....
|
46
47
|
....
|
47
48
|
....
|
48
|
-
# add it after your tracked code, it
|
49
|
+
# add it after your tracked code, it output the trace into a html file
|
49
50
|
SourceRoute.output_html
|
50
51
|
|
51
52
|
Same as the previous example, you will get a html file showing the code trace.
|
@@ -67,16 +68,7 @@ see full usage in examples/study_callback.rb
|
|
67
68
|
|
68
69
|
## Why
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
To get solution or workaround from google or stack overflow is suitable when I'm a ruby starter or task is urgent. But it's not really helpful to levelup my skills.
|
73
|
-
|
74
|
-
The way how I solve problem define my skills' border and depth. So if I slove problems by search google and stack overflow with workarounds, I mostly just increase my experiences on ruby(rails). But if I solve problems directly, in most case, I can say my skill border extends.
|
75
|
-
|
76
|
-
That's why I create this gem. To solve problems directly, I need to know what happened in call or return traces.
|
77
|
-
Fortunately ruby 2.0 introduce a new feature TracePoint to easily trace inner event. But it's not easily to be used as daily tool. This gem tries to make tracing more readable and easily in our daily work.
|
78
|
-
|
79
|
-
Finally, I expect my working style can changes from searching workaround from internet to reading code trace(then more easily check source) directly. I hope it can help you too.
|
71
|
+
Help me read source code and solve problem directly.
|
80
72
|
|
81
73
|
## Test
|
82
74
|
|
@@ -93,14 +85,17 @@ Finally, I expect my working style can changes from searching workaround from in
|
|
93
85
|
|
94
86
|
### TODO
|
95
87
|
|
96
|
-
|
88
|
+
add syntax to monitor when obj was passed into method
|
97
89
|
|
98
|
-
|
90
|
+
animation when node hide
|
99
91
|
|
100
|
-
|
92
|
+
use concurrent-ruby to speed up
|
101
93
|
|
94
|
+
call and return event combined together is no useful. So traces data structure need changed.
|
102
95
|
Dynamic indent when new child level comes.
|
103
96
|
|
97
|
+
global disable some class from monitor
|
98
|
+
|
104
99
|
Add debug option to provide more verbose messages of what has happened
|
105
100
|
|
106
101
|
if instance val contains symbol as value, the json output will be string. It could be confused others.
|
data/lib/source_route.rb
CHANGED
@@ -8,15 +8,15 @@ require "source_route/core_ext"
|
|
8
8
|
require "source_route/version"
|
9
9
|
require "source_route/config"
|
10
10
|
require "source_route/proxy"
|
11
|
-
require "source_route/jsonify"
|
12
11
|
require "source_route/generate_result"
|
13
12
|
require "source_route/tp_result"
|
14
|
-
require "source_route/
|
15
|
-
require "source_route/
|
13
|
+
require "source_route/trace_chain"
|
14
|
+
require "source_route/trace_filter"
|
16
15
|
require 'source_route/json_overrides/activerecord_associations_association'
|
17
16
|
|
18
17
|
begin
|
19
18
|
if Rails
|
19
|
+
require 'source_route/rails_plugins/source_track_middleware'
|
20
20
|
ActiveSupport.on_load(:after_initialize, yield: true) do
|
21
21
|
# make it respond to to_s. In rails source, almost all of its methods are removed, including to_s.
|
22
22
|
module ActiveSupport
|
@@ -44,7 +44,11 @@ module SourceRoute
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def disable
|
47
|
-
proxy.tp.
|
47
|
+
if proxy.tp.nil?
|
48
|
+
puts 'Error: You try to call disable on nil object, do you define SourceRoute ?'
|
49
|
+
else
|
50
|
+
proxy.tp.disable
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
50
54
|
def enable(match = nil, &block)
|
data/lib/source_route/config.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
module SourceRoute
|
2
|
-
|
3
|
-
|
2
|
+
TRACE_FILTER = [:defined_class, :method_id, :path, :lineno].freeze
|
3
|
+
TRACE_FILTER_METHODS = (TRACE_FILTER + TRACE_FILTER.map { |tpf| "#{tpf}_not".to_sym }).freeze
|
4
4
|
|
5
|
+
# todo: Here is not good. Tried to compatible with different options
|
6
|
+
# but code becomes hard to maintenance
|
5
7
|
class Config
|
6
8
|
|
7
9
|
DIRECT_ATTRS = [:event, :full_feature, :debug,
|
8
10
|
:output_format, :show_additional_attrs,
|
9
11
|
:filename, :include_local_var, :include_instance_var,
|
10
|
-
:import_return_to_call
|
12
|
+
:import_return_to_call, :track_params
|
11
13
|
]
|
12
14
|
|
13
15
|
attr_accessor *DIRECT_ATTRS
|
@@ -38,6 +40,7 @@ module SourceRoute
|
|
38
40
|
def has_call_and_return_event
|
39
41
|
event.include? :return and event.include? :call
|
40
42
|
end
|
43
|
+
|
41
44
|
end # END Config
|
42
45
|
|
43
46
|
class BlockConfigParser
|
@@ -69,12 +72,20 @@ module SourceRoute
|
|
69
72
|
end
|
70
73
|
end
|
71
74
|
|
75
|
+
# Track when the value was passed into method
|
76
|
+
def track_params(value)
|
77
|
+
ret_params[:track_params] = value.object_id
|
78
|
+
ret_params[:show_additional_attrs] = :path
|
79
|
+
ret_params[:include_local_var] = true
|
80
|
+
ret_params[:event] = :call
|
81
|
+
end
|
82
|
+
|
72
83
|
# override
|
73
84
|
def output_format(data = nil, &block)
|
74
85
|
ret_params[:output_format] = block_given? ? block : data
|
75
86
|
end
|
76
87
|
|
77
|
-
|
88
|
+
TRACE_FILTER_METHODS.each do |m|
|
78
89
|
define_method m do |*v|
|
79
90
|
ret_params[m] = v
|
80
91
|
end
|
@@ -85,7 +96,7 @@ module SourceRoute
|
|
85
96
|
module ParamsConfigParser
|
86
97
|
extend self
|
87
98
|
|
88
|
-
|
99
|
+
TRACE_FILTER.each do |m|
|
89
100
|
define_method m do |v|
|
90
101
|
@config.positives[m] = Array(v).flatten.map(&:to_s).join('|')
|
91
102
|
end
|
@@ -99,7 +110,7 @@ module SourceRoute
|
|
99
110
|
@config = Config.new
|
100
111
|
params.each do |k, v|
|
101
112
|
@config.send("#{k}=", v) if Config::DIRECT_ATTRS.include? k.to_sym
|
102
|
-
send(k, v) if (
|
113
|
+
send(k, v) if (TRACE_FILTER_METHODS + [:full_feature]).include? k.to_sym
|
103
114
|
end
|
104
115
|
@config.formulize
|
105
116
|
end
|
@@ -18,9 +18,7 @@ module SourceRoute
|
|
18
18
|
end
|
19
19
|
# TODO: any exception triggered in render method will be absorb totally, how to fix it?
|
20
20
|
html_output_str = slim_template.render(proxy.result_builder)
|
21
|
-
File.
|
22
|
-
f << html_output_str
|
23
|
-
end
|
21
|
+
File.write(filename, html_output_str)
|
24
22
|
end
|
25
23
|
|
26
24
|
end # END Html
|
@@ -3,13 +3,13 @@ html
|
|
3
3
|
head
|
4
4
|
title Source Route Result
|
5
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/raykin/json-formatter/
|
7
|
-
link rel="stylesheet" href="
|
6
|
+
link rel="stylesheet" href="https://cdn.rawgit.com/raykin/json-formatter/master/dist/json-formatter.min.css"
|
7
|
+
link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.6/semantic.min.css"
|
8
8
|
|
9
|
-
script
|
9
|
+
script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.js"
|
10
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.
|
12
|
-
script async=true src="
|
11
|
+
script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"
|
12
|
+
script async=true src="https://cdn.jsdelivr.net/semantic-ui/2.2.6/semantic.min.js"
|
13
13
|
|
14
14
|
css:
|
15
15
|
.call-level-0 {}
|
@@ -57,7 +57,7 @@ html
|
|
57
57
|
a.ui.top.right.attached.label.mini(ng-show="::containsDetail(trace)" ng-click="showMoreDetail = !showMoreDetail")
|
58
58
|
i.sidebar.icon
|
59
59
|
.header
|
60
|
-
span.bold>(ng-bind="::trace.order_id")
|
60
|
+
span.bold.ui.label>(ng-bind="::(trace.order_id || '>')")
|
61
61
|
span(ng-bind="::tpSelfList[trace.tp_self_refer]")
|
62
62
|
i.circle.icon.grey(style="font-size: 0.3em")
|
63
63
|
span.method-value(ng-bind="::trace.method_id")
|
@@ -68,7 +68,7 @@ html
|
|
68
68
|
/ workaround for return_value is 'false' and return_value always to be string when existed
|
69
69
|
.meta(ng-if="trace.hasOwnProperty('return_value')")
|
70
70
|
i.icon.pointing.right.small
|
71
|
-
json-formatter(json="::trace.return_value" title="{{::trace.return_value_class}}" style="display: inline-block")
|
71
|
+
json-formatter(json="::trimString(trace.return_value, 30)" title="{{::trace.return_value_class}}" style="display: inline-block")
|
72
72
|
.description(style="margin-left: 20px")
|
73
73
|
.details.right.floated(ng-if="showMoreDetail")
|
74
74
|
.ui.segments(style="border-color: blue")
|
@@ -89,7 +89,7 @@ html
|
|
89
89
|
json-formatter(open="1" json="::plusTraceAttrs[trace.order_id]" title="TracePoint")
|
90
90
|
|
91
91
|
script src="https://cdn.rawgit.com/Urigo/angular-spinkit/master/build/angular-spinkit.min.js"
|
92
|
-
script src="https://cdn.rawgit.com/raykin/json-formatter/
|
92
|
+
script src="https://cdn.rawgit.com/raykin/json-formatter/master/dist/json-formatter.js"
|
93
93
|
// script async src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-sanitize.js"
|
94
94
|
|
95
95
|
javascript:
|
@@ -179,10 +179,11 @@ html
|
|
179
179
|
|
180
180
|
combinedAttrs = function(trace) {
|
181
181
|
var attrs = {}
|
182
|
+
|
182
183
|
if (trace.hasOwnProperty('lineno') && trace.hasOwnProperty('path')) {
|
183
|
-
attrs.method_defined_on = trace.path + ":" + trace.lineno;
|
184
|
+
attrs.method_defined_on = _.replace(trace.path, /.*gems\//, '') + ":" + trace.lineno;
|
184
185
|
} else if (trace.hasOwnProperty('path')) {
|
185
|
-
attrs.method_defined_on = trace.path;
|
186
|
+
attrs.method_defined_on = _.replace(trace.path, /.*gems\//, '');
|
186
187
|
}
|
187
188
|
if (trace.hasOwnProperty('defined_class')) {
|
188
189
|
attrs.method_defined_in = trace.defined_class;
|
@@ -231,13 +232,13 @@ html
|
|
231
232
|
|
232
233
|
$scope.hasChild = function() {
|
233
234
|
return _.find($scope.traces, function(trace) {
|
234
|
-
return _.
|
235
|
+
return _.includes(trace.parent_ids, $scope.trace.order_id)
|
235
236
|
});
|
236
237
|
}
|
237
238
|
})
|
238
239
|
|
239
240
|
.data-collect
|
240
241
|
/ dont use local_trace_data.to_json, because ActiveSupport override it and can introduce unexpected crash for some data
|
241
|
-
#trace-data(data-trace="#{
|
242
|
+
#trace-data(data-trace="#{jsonify_trace_chain}"
|
242
243
|
data-tp-events="#{jsonify_events}"
|
243
244
|
data-tp-self-caches="#{jsonify_tp_self_caches}")
|
@@ -0,0 +1,105 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title Source Route Result
|
5
|
+
link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.10/semantic.min.css"
|
6
|
+
|
7
|
+
script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.js"
|
8
|
+
script src="https://unpkg.com/vue"
|
9
|
+
script src="https://code.jquery.com/jquery-3.2.1.min.js"
|
10
|
+
script async=true src="https://cdn.jsdelivr.net/semantic-ui/2.2.10/semantic.min.js"
|
11
|
+
|
12
|
+
css:
|
13
|
+
.call-level-0 {}
|
14
|
+
.item.trace.call-level-1 { padding-left: 50px }
|
15
|
+
.item.trace.call-level-2 { padding-left: 100px }
|
16
|
+
.item.trace.call-level-3 { padding-left: 150px }
|
17
|
+
.item.trace.call-level-4 { padding-left: 200px }
|
18
|
+
.item.trace.call-level-5 { padding-left: 250px }
|
19
|
+
.item.trace.call-level-6 { padding-left: 300px }
|
20
|
+
.item.trace.call-level-7 { padding-left: 300px }
|
21
|
+
.trace .main .ui.label .icon {
|
22
|
+
margin-right: 0;
|
23
|
+
}
|
24
|
+
// level more than 7 seems not reasonable
|
25
|
+
|
26
|
+
body
|
27
|
+
|
28
|
+
.ui.menu.pointing.stackable.attached#top-menu
|
29
|
+
.ui.container
|
30
|
+
// .item
|
31
|
+
// a.navbar-brand(href="#" @click="resetTraceFilter()") ALL
|
32
|
+
.item(v-for="event in tpEvents" :class="{active: event == traceFilter.event}")
|
33
|
+
a(href="#" @click="traceFilter.event = event" v-text="event")
|
34
|
+
.item
|
35
|
+
.ui.buttons
|
36
|
+
button.ui.labeled.icon.button.olive(@click="outlineTrace()" :class="{loading: outlineTraceLoading}")
|
37
|
+
i.angle.double.right.icon
|
38
|
+
span OutLine
|
39
|
+
.or
|
40
|
+
button.ui.right.labeled.icon.button.green(@click="expandAllTrace()" :class="{loading: expandAllTraceLoading}")
|
41
|
+
i.angle.double.down.icon
|
42
|
+
span Expand
|
43
|
+
.right.menu
|
44
|
+
.item
|
45
|
+
span Trace Count
|
46
|
+
.ui.teal.left.pointing.label(v-text="currentCounter()")
|
47
|
+
|
48
|
+
.ui.container#traces
|
49
|
+
.row
|
50
|
+
.ui.relaxed.items(:class="{{traceFilter.event}}")
|
51
|
+
// track by trace.order_id doesn't always work. because order_id doesn't always exists
|
52
|
+
.item.trace(v-for="trace in traces | filter:traceFilter:true | filter:childParentFilterFn" :class="callLevelClass(trace)" ng-controller="TpTraceCtrl")
|
53
|
+
.content(ng-init="showMoreDetail = false" style="display: flex; justify-content: space-between; align-items: center;")
|
54
|
+
.ui.segment.padded.main
|
55
|
+
a.ui.top.right.attached.label.mini(v-show="containsDetail(trace)" @click="showMoreDetail = !showMoreDetail")
|
56
|
+
i.sidebar.icon
|
57
|
+
.header
|
58
|
+
span.bold.ui.label>(v-text="(trace.order_id || '>')")
|
59
|
+
span(v-text="tpSelfList[trace.tp_self_refer]")
|
60
|
+
i.circle.icon.grey(style="font-size: 0.3em")
|
61
|
+
span.method-value(v-text="trace.method_id")
|
62
|
+
a.ui.bottom.right.attached.label.mini(v-if="hasChild()" @click="toggleChild()" :class="{loading: togglingChild}")
|
63
|
+
i.icon.angle.down(v-show="trace.childOpened" style="font-size: 10px")
|
64
|
+
i.icon.angle.right(ng-hide="trace.childOpened" style="font-size: 14px")
|
65
|
+
/ pulse-spinner(v-show="togglingChild")
|
66
|
+
/ workaround for return_value is 'false' and return_value always to be string when existed
|
67
|
+
.meta(v-if="trace.hasOwnProperty('return_value')")
|
68
|
+
i.icon.pointing.right.small
|
69
|
+
json-formatter(json="trimString(trace.return_value, 30)" title="{{trace.return_value_class}}" style="display: inline-block")
|
70
|
+
.description(style="margin-left: 20px")
|
71
|
+
.details.right.floated(v-if="showMoreDetail")
|
72
|
+
.ui.segments(style="border-color: blue")
|
73
|
+
.ui.segment(v-if="trace.params_var")
|
74
|
+
.ui.teal.left.ribbon.label Parameters
|
75
|
+
json-formatter(open="1" json="trace.params_var" title="{{trace.params_var_class}}")
|
76
|
+
.ui.segment(v-if="trace.hasOwnProperty('return_value')")
|
77
|
+
.ui.grey.left.ribbon.label Return Value
|
78
|
+
json-formatter(open="1" json="trace.return_value" title="{{trace.return_value_class}}")
|
79
|
+
.ui.segment(v-if="trace.local_var")
|
80
|
+
.ui.teal.left.ribbon.label Local Variables
|
81
|
+
json-formatter(open="1" json="trace.local_var" title="{{trace.local_var_class}}")
|
82
|
+
.ui.segment(v-if="trace.instance_var")
|
83
|
+
.ui.blue.left.ribbon.label Instance Variables
|
84
|
+
json-formatter(open="1" json="trace.instance_var" title="{{trace.instance_var_class}}")
|
85
|
+
.ui.segment(v-if="containsOtherAttrs(trace)")
|
86
|
+
.ui.orange.left.ribbon.label Trace Attributes
|
87
|
+
json-formatter(open="1" json="plusTraceAttrs[trace.order_id]" title="TracePoint")
|
88
|
+
|
89
|
+
javascript:
|
90
|
+
var top_menu = new Vue({
|
91
|
+
el: '#top-menu',
|
92
|
+
data: $("#trace-data").data('tp-events')
|
93
|
+
});
|
94
|
+
|
95
|
+
// var traces = new Vue({
|
96
|
+
// el: '#traces',
|
97
|
+
// data: $("#trace-data").data('trace')
|
98
|
+
|
99
|
+
// });
|
100
|
+
|
101
|
+
.data-collect
|
102
|
+
// dont use local_trace_data.to_json, because ActiveSupport override it and can introduce unexpected crash for some data
|
103
|
+
#trace-data(data-trace="#{jsonify_trace_chain}"
|
104
|
+
data-tp-events="#{jsonify_events}"
|
105
|
+
data-tp-self-caches="#{jsonify_tp_self_caches}")
|
@@ -8,10 +8,10 @@ module SourceRoute
|
|
8
8
|
# 5. Output data with correct format
|
9
9
|
class GenerateResult
|
10
10
|
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :trace_chain, :tp_self_caches, :collected_data
|
12
12
|
|
13
13
|
extend Forwardable
|
14
|
-
def_delegators :@
|
14
|
+
def_delegators :@trace_chain, :import_return_value_to_call_chain, :treeize_call_chain
|
15
15
|
|
16
16
|
# see event description in TracePoint API Doc
|
17
17
|
DEFAULT_ATTRS = {
|
@@ -32,7 +32,7 @@ module SourceRoute
|
|
32
32
|
|
33
33
|
def initialize(proxy)
|
34
34
|
@proxy = proxy
|
35
|
-
@
|
35
|
+
@trace_chain = TraceChain.new
|
36
36
|
@tp_self_caches = []
|
37
37
|
end
|
38
38
|
|
@@ -64,11 +64,11 @@ module SourceRoute
|
|
64
64
|
when :html
|
65
65
|
# we cant generate html right now becase the tp callback is still in process
|
66
66
|
# so we gather data into array
|
67
|
-
@
|
67
|
+
@trace_chain.push(TpResult.new(tp_ins))
|
68
68
|
when :silence, :none
|
69
69
|
# do nothing at now
|
70
70
|
when :test
|
71
|
-
@
|
71
|
+
@trace_chain.push(TpResult.new(tp_ins))
|
72
72
|
when :stack_overflow
|
73
73
|
console_stack_overflow
|
74
74
|
when Proc
|
@@ -88,21 +88,22 @@ module SourceRoute
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def jsonify_events
|
91
|
-
|
91
|
+
JSON.dump(@proxy.config.event.map(&:to_s))
|
92
92
|
end
|
93
93
|
|
94
|
-
def
|
95
|
-
value =
|
96
|
-
|
94
|
+
def jsonify_trace_chain
|
95
|
+
value = trace_chain.chain.map(&:to_hash)
|
96
|
+
JSON.dump(value)
|
97
97
|
|
98
|
-
#
|
99
|
-
#
|
98
|
+
# not worked
|
99
|
+
# trace_chain.to_json
|
100
|
+
# json_array = trace_chain.map { |result| JSON.dump(result) }
|
100
101
|
# '[ ' + json_array.join(',') + ' ]'
|
101
102
|
end
|
102
103
|
|
103
104
|
def jsonify_tp_self_caches
|
104
|
-
|
105
|
-
|
105
|
+
JSON.dump(tp_self_caches.clone
|
106
|
+
.map(&:to_s))
|
106
107
|
end
|
107
108
|
|
108
109
|
private
|
@@ -1,33 +1,39 @@
|
|
1
1
|
if defined? ActiveRecord
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
module ActiveRecord
|
3
|
+
module Associations
|
4
|
+
class Association
|
5
|
+
# dump association can trigger ActiveSupport::JSON::Encoding::CircularReferenceError when use rails ~> 4.0.1
|
6
|
+
# I try other json gems to fix it, but all failed. That's why I override it here.
|
7
|
+
def to_json(options = nil)
|
8
|
+
Oj.dump(to_s)
|
9
|
+
end
|
10
|
+
end
|
8
11
|
end
|
9
|
-
end
|
10
12
|
|
11
|
-
|
13
|
+
class Relation
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
# Override original method.
|
16
|
+
# becasue it trigger SystemStackError: stack level too deep when use rails ~> 4.1.0
|
17
|
+
# def as_json(options = nil) #:nodoc:
|
18
|
+
# binding.pry
|
19
|
+
# Json.dump(inspect)
|
20
|
+
# end
|
19
21
|
|
20
|
-
|
22
|
+
end
|
21
23
|
|
22
|
-
|
24
|
+
class Base
|
25
|
+
def source_route_display
|
26
|
+
to_s
|
27
|
+
end
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
# dump association can trigger ActiveSupport::JSON::Encoding::CircularReferenceError when use rails ~> 4.0.1
|
30
|
+
# I try other json gems to fix it, but all failed. That's why I override it here.
|
31
|
+
#
|
32
|
+
# it can affect the json output of rails AR. Not good solution
|
33
|
+
# def to_json(options = nil)
|
34
|
+
# JSON.dump(to_s)
|
35
|
+
# end
|
36
|
+
end # END Base
|
32
37
|
|
38
|
+
end # END ActiveRecord
|
33
39
|
end
|