codebeacon-tracer 0.1.0 → 0.3.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/bin/codebeacon +18 -0
- data/lib/codebeacon/tracer/src/configuration.rb +111 -4
- data/lib/codebeacon/tracer/src/data/metadata_mapper.rb +34 -3
- data/lib/codebeacon/tracer/src/data/persistence_manager.rb +2 -2
- data/lib/codebeacon/tracer/src/data/trace_metadata.rb +76 -0
- data/lib/codebeacon/tracer/src/rails/middleware.rb +5 -1
- data/lib/codebeacon/tracer/src/tracer.rb +15 -3
- data/lib/codebeacon/tracer/version.rb +1 -1
- data/lib/codebeacon-tracer.rb +58 -25
- metadata +27 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 834e2095be6b5d5a919b96bbb1395dc33bfc569cfb189d67b7e95434574c8641
|
4
|
+
data.tar.gz: 1215e606cf263cc3cf77954e4f60e175bd8df43ad9adbe1ad17859bc03003c4b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f7871f11660157413fecdb33a856d9f06465690570226b201e9c5ff2a31dd3a6dbea826b2c4a0d4729a15ebadfab4d07357e9ff8978f76314ed43ef63844471
|
7
|
+
data.tar.gz: c2d72f58559f32136268687dfaea900344a4141d6beb4f252821f9cb838e7e2b296cd304c0a9e51387589611068dff1e34f9a88139c56c5a85ebe2022389cb2a
|
data/bin/codebeacon
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require_relative '../lib/codebeacon-tracer'
|
3
|
+
|
4
|
+
script = ARGV.shift
|
5
|
+
if script.nil?
|
6
|
+
Codebeacon::Tracer.logger.error("No script provided")
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
at_exit do
|
11
|
+
Codebeacon::Tracer.stop
|
12
|
+
end
|
13
|
+
Codebeacon::Tracer.start(
|
14
|
+
name: File.basename(script),
|
15
|
+
trigger_type: "script"
|
16
|
+
)
|
17
|
+
|
18
|
+
load File.expand_path(script)
|
@@ -1,6 +1,12 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'yaml'
|
3
3
|
|
4
|
+
begin
|
5
|
+
require 'listen'
|
6
|
+
rescue LoadError
|
7
|
+
# Listen gem not available, file watching will be disabled
|
8
|
+
end
|
9
|
+
|
4
10
|
module Codebeacon
|
5
11
|
module Tracer
|
6
12
|
class Configuration
|
@@ -19,6 +25,7 @@ module Codebeacon
|
|
19
25
|
exclude_paths << lib_root
|
20
26
|
reload_paths_to_record
|
21
27
|
load_main_config
|
28
|
+
start_config_file_watcher
|
22
29
|
end
|
23
30
|
|
24
31
|
def load_main_config
|
@@ -85,6 +92,10 @@ module Codebeacon
|
|
85
92
|
File.expand_path(File.join(lib_root, 'config.yml'))
|
86
93
|
end
|
87
94
|
|
95
|
+
def tracer_config_path
|
96
|
+
File.join(data_dir, "tracer_config.yml")
|
97
|
+
end
|
98
|
+
|
88
99
|
def read_paths
|
89
100
|
if File.exist?(paths_path)
|
90
101
|
YAML.load_file(paths_path)
|
@@ -125,12 +136,46 @@ module Codebeacon
|
|
125
136
|
end
|
126
137
|
|
127
138
|
def trace_enabled?
|
128
|
-
|
129
|
-
|
139
|
+
if @donotcache
|
140
|
+
load_tracer_config_enabled
|
141
|
+
else
|
142
|
+
@trace_enabled ||= load_tracer_config_enabled
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def reload_tracer_config
|
147
|
+
@trace_enabled = load_tracer_config_enabled
|
148
|
+
@recording_meta_exclude_patterns = nil # Force reload of exclusion patterns
|
130
149
|
end
|
131
150
|
|
132
|
-
def
|
133
|
-
@
|
151
|
+
def recording_meta_exclude_patterns
|
152
|
+
if @donotcache
|
153
|
+
load_recording_meta_exclude_patterns
|
154
|
+
else
|
155
|
+
@recording_meta_exclude_patterns ||= load_recording_meta_exclude_patterns
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def skip_tracing?(name, description)
|
160
|
+
return false unless recording_meta_exclude_patterns&.any?
|
161
|
+
|
162
|
+
name_str = name.to_s
|
163
|
+
description_str = description.to_s
|
164
|
+
|
165
|
+
excluded = recording_meta_exclude_patterns.any? do |pattern|
|
166
|
+
name_matches = File.fnmatch(pattern['name'], name_str, File::FNM_CASEFOLD)
|
167
|
+
description_matches = File.fnmatch(pattern['description'], description_str, File::FNM_CASEFOLD)
|
168
|
+
name_matches && description_matches
|
169
|
+
end
|
170
|
+
|
171
|
+
if excluded && debug?
|
172
|
+
logger.debug("Skipping trace due to metadata exclusion - name: '#{name_str}', description: '#{description_str}'")
|
173
|
+
end
|
174
|
+
|
175
|
+
excluded
|
176
|
+
rescue => e
|
177
|
+
logger.warn("Error checking skip_tracing patterns: #{e.message}")
|
178
|
+
false # Default to not skipping on error
|
134
179
|
end
|
135
180
|
|
136
181
|
def debug?
|
@@ -194,6 +239,68 @@ module Codebeacon
|
|
194
239
|
# Codebeacon::Tracer.logger.info("Call count: #{@return_count}")
|
195
240
|
# Codebeacon::Tracer.logger.info("Return @depth: #{@depth}, method: #{tp.method_id}, line: #{tp.lineno}, path: #{tp.path}")
|
196
241
|
end
|
242
|
+
|
243
|
+
def start_config_file_watcher
|
244
|
+
return unless defined?(Listen) && !@config_listener
|
245
|
+
return unless File.directory?(data_dir)
|
246
|
+
|
247
|
+
begin
|
248
|
+
@config_listener = Listen.to(data_dir, only: /tracer_config\.yml$/) do |modified, added, removed|
|
249
|
+
if (modified + added + removed).any? { |path| File.basename(path) == 'tracer_config.yml' }
|
250
|
+
reload_tracer_config
|
251
|
+
end
|
252
|
+
end
|
253
|
+
@config_listener.start
|
254
|
+
rescue => e
|
255
|
+
@donotcache = true
|
256
|
+
logger.warn("Failed to start config file watcher: #{e.message}")
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def stop_config_file_watcher
|
261
|
+
if @config_listener
|
262
|
+
@config_listener.stop
|
263
|
+
@config_listener = nil
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
private
|
268
|
+
|
269
|
+
def load_recording_meta_exclude_patterns
|
270
|
+
if File.exist?(tracer_config_path)
|
271
|
+
config_data = YAML.load_file(tracer_config_path)
|
272
|
+
patterns = config_data.dig('filters', 'recording_meta_exclude') || []
|
273
|
+
|
274
|
+
# Validate patterns
|
275
|
+
valid_patterns = patterns.select do |pattern|
|
276
|
+
if pattern.is_a?(Hash) && pattern.key?('name') && pattern.key?('description')
|
277
|
+
true
|
278
|
+
else
|
279
|
+
logger.warn("Invalid recording_meta_exclude pattern: #{pattern.inspect}")
|
280
|
+
false
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
valid_patterns
|
285
|
+
else
|
286
|
+
[]
|
287
|
+
end
|
288
|
+
rescue => e
|
289
|
+
logger.warn("Error loading recording meta exclude patterns: #{e.message}")
|
290
|
+
[]
|
291
|
+
end
|
292
|
+
|
293
|
+
def load_tracer_config_enabled
|
294
|
+
if File.exist?(tracer_config_path)
|
295
|
+
config_data = YAML.load_file(tracer_config_path)
|
296
|
+
config_data['tracing_enabled'] != false # Default to true if not specified
|
297
|
+
else
|
298
|
+
true
|
299
|
+
end
|
300
|
+
rescue => e
|
301
|
+
logger.warn("Error loading tracer config: #{e.message}")
|
302
|
+
true
|
303
|
+
end
|
197
304
|
end
|
198
305
|
end
|
199
306
|
end
|
@@ -10,7 +10,16 @@ module Codebeacon
|
|
10
10
|
CREATE TABLE IF NOT EXISTS metadata (
|
11
11
|
id INTEGER PRIMARY KEY,
|
12
12
|
name TEXT,
|
13
|
-
description TEXT
|
13
|
+
description TEXT,
|
14
|
+
caller_file TEXT,
|
15
|
+
caller_method TEXT,
|
16
|
+
caller_line INTEGER,
|
17
|
+
caller_class TEXT,
|
18
|
+
caller_defined_class TEXT,
|
19
|
+
start_time TEXT,
|
20
|
+
end_time TEXT,
|
21
|
+
duration_ms REAL,
|
22
|
+
trigger_type TEXT
|
14
23
|
);
|
15
24
|
SQL
|
16
25
|
end
|
@@ -18,8 +27,30 @@ module Codebeacon
|
|
18
27
|
def self.create_indexes(database)
|
19
28
|
end
|
20
29
|
|
21
|
-
def insert(
|
22
|
-
|
30
|
+
def insert(metadata)
|
31
|
+
metadata_hash = metadata.to_hash
|
32
|
+
|
33
|
+
@db.execute(<<-SQL,
|
34
|
+
INSERT INTO metadata (
|
35
|
+
name, description, caller_file, caller_method, caller_line,
|
36
|
+
caller_class, caller_defined_class, start_time, end_time,
|
37
|
+
duration_ms, trigger_type
|
38
|
+
) VALUES (
|
39
|
+
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
40
|
+
)
|
41
|
+
SQL
|
42
|
+
metadata_hash[:name],
|
43
|
+
metadata_hash[:description],
|
44
|
+
metadata_hash[:caller_file],
|
45
|
+
metadata_hash[:caller_method],
|
46
|
+
metadata_hash[:caller_line],
|
47
|
+
metadata_hash[:caller_class],
|
48
|
+
metadata_hash[:caller_defined_class],
|
49
|
+
metadata_hash[:start_time]&.iso8601,
|
50
|
+
metadata_hash[:end_time]&.iso8601,
|
51
|
+
metadata_hash[:duration_ms],
|
52
|
+
metadata_hash[:trigger_type]
|
53
|
+
)
|
23
54
|
end
|
24
55
|
end
|
25
56
|
end
|
@@ -30,8 +30,8 @@ module Codebeacon
|
|
30
30
|
@progress_logger = Codebeacon::Tracer.logger.newProgressLogger("nodes persisted")
|
31
31
|
end
|
32
32
|
|
33
|
-
def save_metadata(
|
34
|
-
@metadata_mapper.insert(
|
33
|
+
def save_metadata(metadata)
|
34
|
+
@metadata_mapper.insert(metadata)
|
35
35
|
end
|
36
36
|
|
37
37
|
def save_node_sources(node_sources)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Codebeacon
|
2
|
+
module Tracer
|
3
|
+
class TraceMetadata
|
4
|
+
attr_reader :name, :description, :caller_file, :caller_method, :caller_line,
|
5
|
+
:caller_class, :caller_defined_class, :start_time,
|
6
|
+
:end_time, :duration_ms, :trigger_type
|
7
|
+
|
8
|
+
def initialize(name: nil, description: nil, caller_location: nil, trigger_type: nil)
|
9
|
+
@name = name
|
10
|
+
@description = description
|
11
|
+
@start_time = Time.now
|
12
|
+
@end_time = nil
|
13
|
+
@duration_ms = nil
|
14
|
+
@trigger_type = trigger_type
|
15
|
+
|
16
|
+
if caller_location
|
17
|
+
capture_caller_info_from_location(caller_location)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def finish_trace
|
22
|
+
@end_time = Time.now
|
23
|
+
@duration_ms = ((@end_time - @start_time) * 1000).round(2)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_hash
|
27
|
+
{
|
28
|
+
name: @name,
|
29
|
+
description: @description,
|
30
|
+
caller_file: @caller_file,
|
31
|
+
caller_method: @caller_method,
|
32
|
+
caller_line: @caller_line,
|
33
|
+
caller_class: @caller_class,
|
34
|
+
caller_defined_class: @caller_defined_class,
|
35
|
+
start_time: @start_time,
|
36
|
+
end_time: @end_time,
|
37
|
+
duration_ms: @duration_ms,
|
38
|
+
trigger_type: @trigger_type
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def capture_caller_info_from_location(location)
|
45
|
+
begin
|
46
|
+
@caller_file = location.absolute_path || location.path
|
47
|
+
@caller_line = location.lineno
|
48
|
+
@caller_method = location.label
|
49
|
+
|
50
|
+
# Try to determine the calling class/module from the location
|
51
|
+
@caller_class, @caller_defined_class = determine_caller_class_from_location(location)
|
52
|
+
rescue => e
|
53
|
+
Codebeacon::Tracer.logger.warn("Failed to capture caller info from location: #{e.message}") if Codebeacon::Tracer.config.debug?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def determine_caller_class_from_location(location)
|
58
|
+
caller_class = ""
|
59
|
+
caller_defined_class = ""
|
60
|
+
|
61
|
+
# Extract class information from the location label if possible
|
62
|
+
if location.label && location.label.include?('#')
|
63
|
+
# Instance method call - extract class name
|
64
|
+
class_method = location.label.split('#')
|
65
|
+
caller_class = class_method[0] if class_method.length > 1
|
66
|
+
elsif location.label && location.label.include?('.')
|
67
|
+
# Class method call - extract class name
|
68
|
+
class_method = location.label.split('.')
|
69
|
+
caller_class = class_method[0] if class_method.length > 1
|
70
|
+
end
|
71
|
+
|
72
|
+
[caller_class, caller_defined_class]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -12,7 +12,8 @@ module Codebeacon
|
|
12
12
|
begin
|
13
13
|
Codebeacon::Tracer.config.set_query_config(env['QUERY_STRING'])
|
14
14
|
if !@first_run #Codebeacon::Tracer.config.trace_enabled? && !@first_run
|
15
|
-
|
15
|
+
# For middleware, the caller is this method itself
|
16
|
+
Codebeacon::Tracer.trace(trigger_type: "middleware") do |tracer|
|
16
17
|
dry_run_log = Codebeacon::Tracer.config.dry_run? ? "--DRY RUN-- " : ""
|
17
18
|
Codebeacon::Tracer.logger.info(dry_run_log + "Tracing enabled for URI=#{env['REQUEST_URI']}")
|
18
19
|
response = @app.call(env).tap do |_|
|
@@ -22,6 +23,9 @@ module Codebeacon
|
|
22
23
|
params = env['action_dispatch.request.parameters'].dup
|
23
24
|
tracer.name = "#{params.delete('controller')}##{params.delete('action')}"
|
24
25
|
tracer.description = params.to_json
|
26
|
+
# Update the metadata with the Rails-specific information
|
27
|
+
tracer.metadata.instance_variable_set(:@name, tracer.name)
|
28
|
+
tracer.metadata.instance_variable_set(:@description, tracer.description)
|
25
29
|
rescue => e
|
26
30
|
Codebeacon::Tracer.logger.error("Error setting tracer metadata: #{e.message}")
|
27
31
|
end
|
@@ -4,16 +4,26 @@ require_relative 'models/thread_local_call_tree_manager'
|
|
4
4
|
module Codebeacon
|
5
5
|
module Tracer
|
6
6
|
class Tracer
|
7
|
-
attr_reader :id, :tree_manager
|
8
|
-
attr_accessor :name, :description
|
7
|
+
attr_reader :id, :tree_manager, :metadata, :name, :description
|
9
8
|
|
10
|
-
def initialize(name
|
9
|
+
def initialize(name: nil, description: nil, caller_location: nil, trigger_type: nil)
|
11
10
|
@progress_logger = Codebeacon::Tracer.logger.newProgressLogger("calls traced")
|
12
11
|
@traces = [trace_call, trace_b_call, trace_return, trace_b_return]
|
13
12
|
@name = name
|
14
13
|
@description = description
|
15
14
|
@trace_id = SecureRandom.uuid
|
16
15
|
@tree_manager = ThreadLocalCallTreeManager.new(@trace_id)
|
16
|
+
@metadata = TraceMetadata.new(name:, description:, caller_location:, trigger_type:)
|
17
|
+
end
|
18
|
+
|
19
|
+
def name=(new_name)
|
20
|
+
@name = new_name
|
21
|
+
@metadata.instance_variable_set(:@name, new_name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def description=(new_description)
|
25
|
+
@description = new_description
|
26
|
+
@metadata.instance_variable_set(:@description, new_description)
|
17
27
|
end
|
18
28
|
|
19
29
|
def id()
|
@@ -32,6 +42,7 @@ module Codebeacon
|
|
32
42
|
def stop()
|
33
43
|
stop_traces
|
34
44
|
@progress_logger.finish()
|
45
|
+
@metadata.finish_trace
|
35
46
|
end
|
36
47
|
|
37
48
|
def cleanup()
|
@@ -95,6 +106,7 @@ module Codebeacon
|
|
95
106
|
if [:call, :b_call, :return, :b_return].include?(type)
|
96
107
|
paths << Kernel.caller(1..1)[0]
|
97
108
|
end
|
109
|
+
paths.uniq!
|
98
110
|
next if skip_methods?(paths)
|
99
111
|
yield tp
|
100
112
|
rescue => e
|
data/lib/codebeacon-tracer.rb
CHANGED
@@ -48,17 +48,30 @@ module Codebeacon
|
|
48
48
|
#
|
49
49
|
# @param name [String, nil] Optional name for the trace
|
50
50
|
# @param description [String, nil] Optional description for the trace
|
51
|
+
# @param trigger_type [String] The type of trigger that initiated the trace (default: "manual")
|
51
52
|
# @yield [tracer] Yields the tracer object to the block
|
52
53
|
# @yieldparam tracer [Tracer] The tracer object
|
53
54
|
# @return [Object] The result of the block
|
54
|
-
def trace(name
|
55
|
+
def trace(name: nil, description: nil, trigger_type: "manual")
|
56
|
+
# Capture caller information immediately at entry point
|
57
|
+
caller_location = caller_locations(1, 1).first
|
58
|
+
|
59
|
+
unless config.trace_enabled?
|
60
|
+
logger.info("Tracing is disabled. Skipping trace: #{name} - #{description}")
|
61
|
+
return yield(nil)
|
62
|
+
end
|
63
|
+
if config.skip_tracing?(name, description)
|
64
|
+
logger.info("Exclusion rules matched. Skipping trace: #{name} - #{description}")
|
65
|
+
return yield(nil)
|
66
|
+
end
|
67
|
+
|
55
68
|
begin
|
56
69
|
setup
|
57
|
-
@tracer = Tracer.new(name
|
70
|
+
@tracer = Tracer.new(name:, description:, caller_location:, trigger_type:)
|
58
71
|
result = @tracer.enable_traces do
|
59
72
|
yield @tracer
|
60
73
|
end
|
61
|
-
persist(@tracer.
|
74
|
+
persist(@tracer.metadata)
|
62
75
|
cleanup
|
63
76
|
result
|
64
77
|
rescue => e
|
@@ -70,18 +83,28 @@ module Codebeacon
|
|
70
83
|
end
|
71
84
|
|
72
85
|
# Starts tracing without a block
|
86
|
+
# @param name [String, nil] Optional name for the trace
|
87
|
+
# @param description [String, nil] Optional description for the trace
|
88
|
+
# @param trigger_type [String] The type of trigger that initiated the trace (default: "manual")
|
73
89
|
# @return [void]
|
74
|
-
def start
|
90
|
+
def start(name: nil, description: nil, trigger_type: "manual")
|
91
|
+
# Capture caller information immediately at entry point
|
92
|
+
caller_location = caller_locations(1, 1).first
|
93
|
+
|
94
|
+
return unless config.trace_enabled?
|
95
|
+
|
75
96
|
setup
|
76
|
-
@tracer = Tracer.new()
|
97
|
+
@tracer = Tracer.new(name:, description:, caller_location:, trigger_type:)
|
77
98
|
@tracer.start
|
78
99
|
end
|
79
100
|
|
80
101
|
# Stops tracing and persists the results
|
81
102
|
# @return [void]
|
82
103
|
def stop
|
104
|
+
return unless @tracer # checks whether trace_enabled? was false when start was called or if it was called
|
105
|
+
|
83
106
|
@tracer.stop
|
84
|
-
persist
|
107
|
+
persist(@tracer.metadata)
|
85
108
|
cleanup
|
86
109
|
end
|
87
110
|
|
@@ -92,25 +115,35 @@ module Codebeacon
|
|
92
115
|
@rubylib_node = NodeSource.new('rubylib', Codebeacon::Tracer.config.rubylib_path)
|
93
116
|
end
|
94
117
|
|
95
|
-
private def persist(
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
118
|
+
private def persist(metadata)
|
119
|
+
name = metadata.name || ""
|
120
|
+
description = metadata.description || ""
|
121
|
+
|
122
|
+
if config.skip_tracing?(name, description)
|
123
|
+
config.logger.debug("Skipping persistence due to metadata exclusion - name: '#{name}', description: '#{description}'") if config.debug?
|
124
|
+
return
|
125
|
+
end
|
126
|
+
|
127
|
+
if Codebeacon::Tracer.config.dry_run?
|
128
|
+
config.logger.debug("Dry run - skipping persistence") if config.debug?
|
129
|
+
return
|
130
|
+
end
|
131
|
+
|
132
|
+
begin
|
133
|
+
schema = DatabaseSchema.new
|
134
|
+
schema.create_tables
|
135
|
+
DatabaseSchema.trim_db_files
|
136
|
+
pm = PersistenceManager.new(schema.db)
|
137
|
+
ordered_sources = [ @app_node, @gem_node, @rubylib_node ]
|
138
|
+
pm.save_metadata(metadata)
|
139
|
+
pm.save_node_sources(ordered_sources)
|
140
|
+
pm.save_trees(@tracer.tree_manager.trees)
|
141
|
+
schema.create_indexes
|
142
|
+
schema.db.close
|
143
|
+
touch_refresh
|
144
|
+
rescue => e
|
145
|
+
Codebeacon::Tracer.logger.error("Error during persistence: #{e.message}")
|
146
|
+
Codebeacon::Tracer.logger.error(e.backtrace.join("\n")) if Codebeacon::Tracer.config.debug?
|
114
147
|
end
|
115
148
|
end
|
116
149
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codebeacon-tracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Conley
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -38,6 +38,26 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: listen
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.8'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 3.8.0
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '3.8'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 3.8.0
|
41
61
|
- !ruby/object:Gem::Dependency
|
42
62
|
name: pry
|
43
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,16 +160,19 @@ description: Codebeacon::Tracer provides tools to trace and capture call graphs
|
|
140
160
|
execution paths.
|
141
161
|
email:
|
142
162
|
- conley.jj@gmail.com
|
143
|
-
executables:
|
163
|
+
executables:
|
164
|
+
- codebeacon
|
144
165
|
extensions: []
|
145
166
|
extra_rdoc_files: []
|
146
167
|
files:
|
168
|
+
- bin/codebeacon
|
147
169
|
- lib/codebeacon-tracer.rb
|
148
170
|
- lib/codebeacon/tracer/src/configuration.rb
|
149
171
|
- lib/codebeacon/tracer/src/data/database.rb
|
150
172
|
- lib/codebeacon/tracer/src/data/metadata_mapper.rb
|
151
173
|
- lib/codebeacon/tracer/src/data/node_source_mapper.rb
|
152
174
|
- lib/codebeacon/tracer/src/data/persistence_manager.rb
|
175
|
+
- lib/codebeacon/tracer/src/data/trace_metadata.rb
|
153
176
|
- lib/codebeacon/tracer/src/data/tree_node_mapper.rb
|
154
177
|
- lib/codebeacon/tracer/src/logger.rb
|
155
178
|
- lib/codebeacon/tracer/src/models/call_tree.rb
|