callstacking-rails 0.1.2 → 0.1.3

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +621 -0
  3. data/README.md +49 -6
  4. data/app/assets/config/callstacking_rails_manifest.js +1 -0
  5. data/app/assets/stylesheets/{checkpoint → callstacking}/rails/application.css +0 -0
  6. data/app/controllers/{checkpoint → callstacking}/rails/application_controller.rb +1 -1
  7. data/app/helpers/{checkpoint → callstacking}/rails/application_helper.rb +1 -1
  8. data/app/jobs/{checkpoint → callstacking}/rails/application_job.rb +1 -1
  9. data/app/mailers/{checkpoint → callstacking}/rails/application_mailer.rb +1 -1
  10. data/app/models/{checkpoint → callstacking}/rails/application_record.rb +1 -1
  11. data/config/routes.rb +1 -1
  12. data/exe/callstacking-rails +32 -0
  13. data/lib/{checkpoint → callstacking}/rails/client/authenticate.rb +2 -1
  14. data/lib/{checkpoint → callstacking}/rails/client/base.rb +3 -3
  15. data/lib/{checkpoint → callstacking}/rails/client/trace.rb +3 -1
  16. data/lib/callstacking/rails/engine.rb +49 -0
  17. data/lib/{checkpoint → callstacking}/rails/env.rb +3 -1
  18. data/lib/callstacking/rails/instrument.rb +100 -0
  19. data/lib/callstacking/rails/loader.rb +29 -0
  20. data/lib/{checkpoint → callstacking}/rails/settings.rb +13 -5
  21. data/lib/callstacking/rails/setup.rb +115 -0
  22. data/lib/callstacking/rails/spans.rb +53 -0
  23. data/lib/callstacking/rails/trace.rb +126 -0
  24. data/lib/{checkpoint → callstacking}/rails/traces_helper.rb +20 -7
  25. data/lib/callstacking/rails/version.rb +5 -0
  26. data/lib/callstacking/rails.rb +7 -0
  27. metadata +32 -40
  28. data/MIT-LICENSE +0 -20
  29. data/app/assets/config/checkpoint_rails_manifest.js +0 -1
  30. data/app/controllers/checkpoint/rails/traces_controller.rb +0 -6
  31. data/lib/checkpoint/rails/engine.rb +0 -34
  32. data/lib/checkpoint/rails/setup.rb +0 -93
  33. data/lib/checkpoint/rails/traceable.rb +0 -210
  34. data/lib/checkpoint/rails/version.rb +0 -5
  35. data/lib/checkpoint/rails.rb +0 -7
@@ -0,0 +1,126 @@
1
+ require "rails"
2
+ require "active_support/concern"
3
+ require "callstacking/rails/client/base"
4
+ require "callstacking/rails/client/authenticate"
5
+ require "callstacking/rails/client/trace"
6
+ require "callstacking/rails/settings"
7
+
8
+ module Callstacking
9
+ module Rails
10
+ class Trace
11
+ include Callstacking::Rails::Settings
12
+
13
+ attr_accessor :spans, :client, :lock
14
+ cattr_accessor :current_request_id
15
+
16
+ def initialize(spans)
17
+ @traces = []
18
+ @spans = spans
19
+
20
+ @lock = Mutex.new
21
+ @client = Callstacking::Rails::Client::Trace.new
22
+ end
23
+
24
+ def tracing
25
+ read_settings
26
+
27
+ trace_id = nil
28
+
29
+ ActiveSupport::Notifications.subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
30
+ request_id = payload[:request].request_id
31
+ Callstacking::Rails::Trace.current_request_id = request_id
32
+
33
+ trace_id, _interval = client.create(payload[:method], payload[:controller],
34
+ payload[:action], payload[:format],
35
+ ::Rails.root, payload[:request].original_url,
36
+ request_id, payload[:headers],
37
+ payload[:params])
38
+
39
+ puts "#{settings[:url] || Callstacking::Rails::Settings::PRODUCTION_URL}/traces/#{trace_id}"
40
+
41
+ create_message(start_request_message(payload), spans.increment_order_num, @traces)
42
+ end
43
+
44
+ @spans.on_call_entry do |nesting_level, order_num, klass, method_name, arguments, path, line_no|
45
+ create_call_entry(nesting_level, order_num, klass, method_name, arguments, path, line_no, @traces)
46
+ end
47
+
48
+ @spans.on_call_return do |coupled_callee, nesting_level, order_num, klass, method_name, path, line_no, return_val|
49
+ create_call_return(coupled_callee, nesting_level, order_num, klass, method_name, path, line_no, return_val, @traces)
50
+ end
51
+
52
+ ActiveSupport::Notifications.subscribe("process_action.action_controller") do |name, start, finish, id, payload|
53
+ create_message(completed_request_message(payload), spans.increment_order_num, @traces)
54
+ send_traces!(trace_id, @traces)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def completed_request_message(payload)
61
+ "Completed request: #{payload[:method]} #{payload[:controller]}##{payload[:action]} as #{payload[:format]}"
62
+ end
63
+
64
+ def start_request_message(payload)
65
+ "Started request: #{payload[:method]} #{payload[:controller]}##{payload[:action]} as #{payload[:format]}"
66
+ end
67
+
68
+ def create_call_return(coupled_callee, nesting_level, order_num, klass, method_name, path, line_no, return_val, traces)
69
+ lock.synchronize do
70
+ traces << { trace_entry: { trace_entryable_type: 'TraceCallReturn',
71
+ order_num: order_num,
72
+ nesting_level: nesting_level,
73
+ trace_entryable_attributes: {
74
+ local_variables: {},
75
+ klass: klass_name(klass),
76
+ line_number: line_no,
77
+ path: path,
78
+ method_name: method_name,
79
+ return_value: return_val.inspect,
80
+ coupled_callee: coupled_callee,
81
+ } } }
82
+ end
83
+ end
84
+
85
+ def create_call_entry(nesting_level, order_num, klass, method_name, arguments, path, line_no, traces)
86
+ lock.synchronize do
87
+ traces << { trace_entry: { trace_entryable_type: 'TraceCallEntry',
88
+ order_num: order_num,
89
+ nesting_level: nesting_level,
90
+ trace_entryable_attributes: {
91
+ args: arguments,
92
+ klass: klass_name(klass),
93
+ line_number: line_no,
94
+ path: path,
95
+ method_name: method_name,
96
+ } } }
97
+ end
98
+ end
99
+
100
+ def create_message(message, order_num, traces)
101
+ lock.synchronize do
102
+ traces << { trace_entry: { trace_entryable_type: 'TraceMessage',
103
+ order_num: order_num,
104
+ nesting_level: 0,
105
+ trace_entryable_attributes: {
106
+ message: message
107
+ } } }
108
+ end
109
+ end
110
+
111
+ def send_traces!(trace_id, traces)
112
+ lock.synchronize do
113
+ return if traces.empty?
114
+
115
+ client.upsert(trace_id, { traces: traces })
116
+ traces.clear
117
+ end
118
+ end
119
+
120
+ private
121
+ def klass_name(klass)
122
+ (klass.is_a?(Class) ? klass.name : klass.class.name)
123
+ end
124
+ end
125
+ end
126
+ end
@@ -1,25 +1,26 @@
1
- require "action_view/helpers/tag_helper.rb"
1
+ require "action_view/helpers/tag_helper"
2
2
  require "action_view/context.rb"
3
3
 
4
- module Checkpoint
4
+ module Callstacking
5
5
  module Rails
6
6
  module TracesHelper
7
7
  include ActionView::Helpers::TagHelper
8
+ include ActionView::Helpers::JavaScriptHelper
8
9
  include ActionView::Context
9
- include Checkpoint::Rails::Settings
10
+ include Callstacking::Rails::Settings
10
11
 
11
12
  def hud
12
13
  read_settings
13
14
 
14
- frame_url = "#{url || Checkpoint::Rails::Settings::PRODUCTION_URL}/traces/#{Checkpoint::Rails::Traceable.current_request_id}/print"
15
+ frame_url = "#{url || Callstacking::Rails::Settings::PRODUCTION_URL}/traces/#{Callstacking::Rails::Trace.current_request_id}/print"
15
16
 
16
17
  body = []
17
18
  body << (content_tag( :div, data: { turbo:false },
18
- style: 'background-color: #FFF; color: #0000FF; font-size: 20pt; top: 50%; right: 20px;
19
- padding: 30px 10px 0px 10px; position: fixed; height: 100px; width: 40px; cursor: pointer;',
19
+ style: 'top: 50%; right: 10px; font-size: 24pt; :hover{text-shadow: 1px 1px 2px #000000};
20
+ padding: 0px; position: fixed; height: 50px; width: 40px; cursor: pointer;',
20
21
  onclick: 'document.getElementById("callstacking-debugger").style.display = "unset";
21
22
  document.getElementById("callstacking-close").style.display = "unset";') do
22
- ""
23
+ "💥"
23
24
  end)
24
25
 
25
26
  body << (content_tag(:iframe, src: frame_url, id: 'callstacking-debugger', data: { turbo:false },
@@ -27,6 +28,18 @@ module Checkpoint
27
28
  z-index: 99; opacity: 1.0; background-color: #FFF; color: #000; border: 1px solid;
28
29
  margin: 0; padding: 0; box-shadow: 5px 5px; display: none;") do
29
30
  end)
31
+
32
+ body << (javascript_tag('
33
+ document.onkeyup = function(e) {
34
+ // Mac - option-d Win - alt-d
35
+ if (e.altKey && e.which == 68) {
36
+ if (document.getElementById("callstacking-debugger").style.display === "none") {
37
+ document.getElementById("callstacking-debugger").style.display = "block";
38
+ } else {
39
+ document.getElementById("callstacking-debugger").style.display = "none";
40
+ }
41
+ }
42
+ };'))
30
43
 
31
44
  body.join
32
45
  end
@@ -0,0 +1,5 @@
1
+ module Callstacking
2
+ module Rails
3
+ VERSION = "0.1.3"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require "callstacking/rails/version"
2
+ require "callstacking/rails/engine"
3
+
4
+ module Callstacking
5
+ module Rails
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: callstacking-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Jones
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-21 00:00:00.000000000 Z
11
+ date: 2023-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,54 +52,45 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: concurrent-ruby
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- description: Rolling debugger that shows the full state of each call.
55
+ description: Quickly visualize which methods call which, their parameters, and return
56
+ values.
70
57
  email:
71
58
  - jim.jones1@gmail.com
72
- executables: []
59
+ executables:
60
+ - callstacking-rails
73
61
  extensions: []
74
62
  extra_rdoc_files: []
75
63
  files:
76
- - MIT-LICENSE
64
+ - LICENSE
77
65
  - README.md
78
66
  - Rakefile
79
- - app/assets/config/checkpoint_rails_manifest.js
80
- - app/assets/stylesheets/checkpoint/rails/application.css
81
- - app/controllers/checkpoint/rails/application_controller.rb
82
- - app/controllers/checkpoint/rails/traces_controller.rb
83
- - app/helpers/checkpoint/rails/application_helper.rb
84
- - app/jobs/checkpoint/rails/application_job.rb
85
- - app/mailers/checkpoint/rails/application_mailer.rb
86
- - app/models/checkpoint/rails/application_record.rb
67
+ - app/assets/config/callstacking_rails_manifest.js
68
+ - app/assets/stylesheets/callstacking/rails/application.css
69
+ - app/controllers/callstacking/rails/application_controller.rb
70
+ - app/helpers/callstacking/rails/application_helper.rb
71
+ - app/jobs/callstacking/rails/application_job.rb
72
+ - app/mailers/callstacking/rails/application_mailer.rb
73
+ - app/models/callstacking/rails/application_record.rb
87
74
  - config/routes.rb
88
- - lib/checkpoint/rails.rb
89
- - lib/checkpoint/rails/client/authenticate.rb
90
- - lib/checkpoint/rails/client/base.rb
91
- - lib/checkpoint/rails/client/trace.rb
92
- - lib/checkpoint/rails/engine.rb
93
- - lib/checkpoint/rails/env.rb
94
- - lib/checkpoint/rails/settings.rb
95
- - lib/checkpoint/rails/setup.rb
96
- - lib/checkpoint/rails/traceable.rb
97
- - lib/checkpoint/rails/traces_helper.rb
98
- - lib/checkpoint/rails/version.rb
75
+ - exe/callstacking-rails
76
+ - lib/callstacking/rails.rb
77
+ - lib/callstacking/rails/client/authenticate.rb
78
+ - lib/callstacking/rails/client/base.rb
79
+ - lib/callstacking/rails/client/trace.rb
80
+ - lib/callstacking/rails/engine.rb
81
+ - lib/callstacking/rails/env.rb
82
+ - lib/callstacking/rails/instrument.rb
83
+ - lib/callstacking/rails/loader.rb
84
+ - lib/callstacking/rails/settings.rb
85
+ - lib/callstacking/rails/setup.rb
86
+ - lib/callstacking/rails/spans.rb
87
+ - lib/callstacking/rails/trace.rb
88
+ - lib/callstacking/rails/traces_helper.rb
89
+ - lib/callstacking/rails/version.rb
99
90
  - lib/tasks/checkpoint/rails_tasks.rake
100
91
  homepage: https://github.com/callstacking/callstacking-rails
101
92
  licenses:
102
- - MIT
93
+ - GPL-3.0-or-later
103
94
  metadata:
104
95
  homepage_uri: https://github.com/callstacking/callstacking-rails
105
96
  source_code_uri: https://github.com/callstacking/callstacking-rails
@@ -121,5 +112,6 @@ requirements: []
121
112
  rubygems_version: 3.3.7
122
113
  signing_key:
123
114
  specification_version: 4
124
- summary: Rolling debugger that shows the full state of each call per request.
115
+ summary: Quickly visualize which methods call which, their parameters, and return
116
+ values.
125
117
  test_files: []
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright 2022 Jim Jones
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1 +0,0 @@
1
- //= link_directory ../stylesheets/checkpoint/rails .css
@@ -1,6 +0,0 @@
1
- module Checkpoint::Rails
2
- class TracesController < ApplicationController
3
- def index
4
- end
5
- end
6
- end
@@ -1,34 +0,0 @@
1
- require "checkpoint/rails/traceable"
2
- require "checkpoint/rails/setup"
3
- require "checkpoint/rails/settings"
4
- require "checkpoint/rails/client/base"
5
- require "checkpoint/rails/client/authenticate"
6
- require "checkpoint/rails/client/trace"
7
- require "checkpoint/rails/traces_helper"
8
-
9
- module Checkpoint
10
- module Rails
11
- class Engine < ::Rails::Engine
12
- isolate_namespace Checkpoint::Rails
13
-
14
- include ::Checkpoint::Rails::Traceable
15
-
16
- initializer "engine_name.assets.precompile" do |app|
17
- app.config.assets.precompile << "checkpoint_rails_manifest.js"
18
- end
19
-
20
- initializer 'local_helper.action_controller' do
21
- ActiveSupport.on_load :action_controller do
22
- helper Checkpoint::Rails::TracesHelper
23
- include Checkpoint::Rails::TracesHelper
24
- end
25
- end
26
-
27
- initializer :append_before_action do
28
- ActionController::Base.send :after_action, :inject_hud
29
- end
30
-
31
- set_trace
32
- end
33
- end
34
- end
@@ -1,93 +0,0 @@
1
- require 'yaml'
2
- require "checkpoint/rails/settings"
3
-
4
- module Checkpoint
5
- module Rails
6
- class Setup
7
- include ::Checkpoint::Rails::Settings
8
- extend ::Checkpoint::Rails::Settings
9
-
10
- attr_accessor :client
11
-
12
- def initialize
13
- read_settings
14
- end
15
-
16
- def client
17
- @client = Checkpoint::Rails::Client::Authenticate.new
18
- end
19
-
20
- def start
21
- email = prompt("Enter email:")
22
- password = prompt("Enter password:")
23
-
24
- url = if Rails::Checkpoint::Env.production? && ENV['CHECKPOINT_RAILS_LOCAL_TEST'].nil?
25
- PRODUCTION_URL
26
- else
27
- prompt("Enter URL for #{Checkpoint::Rails::Env.environment} API calls [#{PRODUCTION_URL}]:") || PRODUCTION_URL
28
- end
29
-
30
- save(email, password, url)
31
-
32
- puts "Authentication successful."
33
- puts "Settings saved to #{SETTINGS_FILE}"
34
- rescue StandardError => e
35
- puts "Problem authenticating: #{e.message}"
36
- end
37
-
38
- def prompt(label)
39
- puts label
40
- value = STDIN.gets.chomp
41
- puts
42
-
43
- return nil if value == ''
44
- value
45
- end
46
-
47
- def token(email, password)
48
- client.login(email, password)
49
- end
50
-
51
- def save(email, password, url)
52
- props = { auth_token: '',
53
- url: url,
54
- }
55
-
56
- props = { Checkpoint::Rails::Env.environment => {
57
- settings: props
58
- } }
59
-
60
- write_settings(complete_settings.merge(props))
61
-
62
- props[Checkpoint::Rails::Env.environment][:settings][:auth_token] = token(email, password)
63
-
64
- write_settings(complete_settings.merge(props))
65
-
66
- read_settings
67
- end
68
-
69
- def self.instructions
70
- read_settings
71
- puts "loading environment #{Checkpoint::Rails::Env.environment}"
72
- puts
73
- puts "Usage: "
74
- puts
75
- puts " callstacking-rails register"
76
- puts " Opens a browser window to register as a Callstacking user."
77
- puts
78
- puts " callstacking-rails setup"
79
- puts " Interactively prompts you for your Callstacking username/password, "
80
- puts " Stores auth details in #{SETTINGS_FILE} "
81
- puts
82
- puts " You can have multiple environments."
83
- puts " Default is #{Rails::Checkpoint::Env::DEFAULT_ENVIRONMENT}."
84
- puts
85
- puts " The #{Checkpoint::Rails::Env.environment}: section in the #{SETTINGS_FILE} contains your credentials."
86
- puts " By setting the RAILS_ENV environment you can maintain"
87
- puts " multiple settings."
88
- puts
89
- puts "Questions? Create an issue: https://github.com/callstacking/callstacking-rails/issues"
90
- end
91
- end
92
- end
93
- end
@@ -1,210 +0,0 @@
1
- require "active_support/concern"
2
- require "checkpoint/rails/client/base"
3
- require "checkpoint/rails/client/authenticate"
4
- require "checkpoint/rails/client/trace"
5
- require "checkpoint/rails/settings"
6
-
7
- module Checkpoint
8
- module Rails
9
- module Traceable
10
- extend ActiveSupport::Concern
11
- include Checkpoint::Rails::Settings
12
-
13
- TARGET_DIV = 'traces'
14
-
15
- mattr_accessor :current_request_id
16
-
17
- def set_trace
18
- read_settings
19
-
20
- client = Checkpoint::Rails::Client::Trace.new
21
-
22
- trace_points = {}
23
- params = {}
24
- prev_event = ''
25
- order_num = 0
26
- trace_id = nil
27
- traces = []
28
- lock = Mutex.new
29
- task = nil
30
-
31
- ActiveSupport::Notifications.subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
32
- next if payload[:controller] == 'Checkpoint::Rails::TracesController'
33
-
34
- key = request_key(payload)
35
- params[key] = payload[:params]
36
-
37
- nesting_level = -1
38
-
39
- request_id = payload[:request].request_id
40
- Checkpoint::Rails::Traceable.current_request_id = request_id
41
-
42
- trace_id, _interval = client.create(payload[:method], payload[:controller],
43
- payload[:action], payload[:format],
44
- ::Rails.root, payload[:request].original_url,
45
- request_id,
46
- payload[:headers], params[key])
47
-
48
-
49
- puts "#{settings[:url] || Checkpoint::Rails::Settings::PRODUCTION_URL}/traces/#{trace_id}"
50
-
51
- task = Concurrent::TimerTask.new(execution_interval: 1, timeout_interval: 60) {
52
- send_traces!(trace_id, traces, lock, client)
53
- }
54
-
55
- task.execute
56
-
57
- create_message(start_request_message(payload), order_num, traces, lock)
58
-
59
- trace_points[key]&.disable
60
- trace_point = TracePoint.new(:call, :return) do |t|
61
- trace = caller[0]
62
-
63
- next unless trace.match?(Dir.pwd)
64
-
65
- order_num += 1
66
-
67
- if t.event == :call
68
- nesting_level += 1
69
-
70
- prev_event = previous_event(t)
71
-
72
- create_call_entry(nesting_level, order_num, t, traces, lock)
73
- elsif t.event == :return
74
- coupled_callee = false
75
- coupled_callee = true if prev_event == previous_event(t)
76
-
77
- prev_event = previous_event(t)
78
- return_value = t.return_value.inspect
79
-
80
- create_call_return(coupled_callee, nesting_level, order_num, return_value, t, traces, lock)
81
-
82
- nesting_level -= 1
83
- end
84
- end
85
-
86
- trace_point.enable
87
- trace_points[key] = trace_point
88
- end
89
-
90
- ActiveSupport::Notifications.subscribe("process_action.action_controller") do |name, start, finish, id, payload|
91
- trace_points[request_key(payload)]&.disable
92
- task&.shutdown
93
-
94
- create_message(completed_request_message(payload), order_num, traces, lock)
95
- send_traces!(trace_id, traces, lock, client)
96
- end
97
- end
98
-
99
- private
100
-
101
- def completed_request_message(payload)
102
- "Completed request: #{payload[:method]} #{payload[:controller]}##{payload[:action]} as #{payload[:format]}"
103
- end
104
-
105
- def start_request_message(payload)
106
- puts "start request message - "
107
- "Request: #{payload[:method]} #{payload[:controller]}##{payload[:action]} as #{payload[:format]}"
108
- end
109
-
110
- def create_call_return(coupled_callee, nesting_level, order_num, return_value, t, traces, lock)
111
- lock.synchronize do
112
- traces << { trace_entry: { trace_entryable_type: 'TraceCallReturn',
113
- order_num: order_num,
114
- nesting_level: nesting_level,
115
- trace_entryable_attributes: {
116
- local_variables: locals_for(t),
117
- klass: t.binding.receiver.class.name.to_s,
118
- line_number: t.lineno,
119
- path: t.path,
120
- method_name: t.method_id,
121
- return_value: return_value,
122
- coupled_callee: coupled_callee,
123
- } } }
124
- end
125
- end
126
-
127
- def create_call_entry(nesting_level, order_num, t, traces, lock)
128
- lock.synchronize do
129
- traces << { trace_entry: { trace_entryable_type: 'TraceCallEntry',
130
- order_num: order_num,
131
- nesting_level: nesting_level,
132
- trace_entryable_attributes: {
133
- args: arguments_for(t),
134
- klass: t.binding.receiver.class.name.to_s,
135
- line_number: t.lineno,
136
- path: t.path,
137
- method_name: t.method_id,
138
- } } }
139
- end
140
- end
141
-
142
- def create_message(message, order_num, traces, lock)
143
- lock.synchronize do
144
- traces << { trace_entry: { trace_entryable_type: 'TraceMessage',
145
- order_num: order_num,
146
- nesting_level: 0,
147
- trace_entryable_attributes: {
148
- message: message
149
- } } }
150
- end
151
- end
152
-
153
- def send_traces!(trace_id, traces, lock, client)
154
- lock.synchronize do
155
- return if traces.empty?
156
-
157
- client.upsert(trace_id, { traces: traces })
158
- traces.clear
159
- end
160
- end
161
-
162
- def caller_key(t)
163
- "#{t.binding.receiver.class.name.to_s}##{t.method_id}"
164
- end
165
-
166
- def request_key(payload)
167
- "#{payload[:controller]}##{payload[:action]}"
168
- end
169
-
170
- def previous_event(t)
171
- "#{t.binding.receiver.class.name.to_s}:#{t.method_id}"
172
- end
173
-
174
- def view_rendered?(t)
175
- t.path.to_s =~ /view/
176
- end
177
-
178
- def partial_rendered?(t)
179
- view_rendered?(t) && Pathname.new(t.path).basename.to_s =~ /^_/
180
- end
181
-
182
- def layout_rendered?(t)
183
- view_rendered?(t) && t.path =~ /layouts/
184
- end
185
-
186
- def template_rendered?(t)
187
- view_rendered?(t) && !partial_rendered?(t) && !layout_rendered?(t)
188
- end
189
-
190
- def arguments_for(trace)
191
- param_names = trace&.parameters&.map(&:last)
192
- return {} if param_names.nil?
193
-
194
- param_names.map do |param|
195
- next if [:&, :*, :**].include?(param)
196
- [param, trace.binding.local_variable_get(param.to_s)]
197
- end.compact.to_h
198
- end
199
-
200
- def locals_for(trace)
201
- local_names = trace&.binding&.local_variables
202
- return {} if local_names.nil?
203
-
204
- local_names.map do |local|
205
- [local, trace.binding.local_variable_get(local)]
206
- end.to_h
207
- end
208
- end
209
- end
210
- end
@@ -1,5 +0,0 @@
1
- module Checkpoint
2
- module Rails
3
- VERSION = "0.1.2"
4
- end
5
- end