railscope 0.1.10 → 0.1.11
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/lib/railscope/context.rb +25 -0
- data/lib/railscope/middleware.rb +14 -11
- data/lib/railscope/subscribers/base_subscriber.rb +8 -2
- data/lib/railscope/subscribers/job_subscriber.rb +6 -1
- data/lib/railscope/subscribers/model_subscriber.rb +8 -0
- data/lib/railscope/version.rb +1 -1
- data/lib/railscope.rb +39 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c7b44de114284ee8955d48c35c4966b45e8b798b1624d6a8abefb2212b9e4cd5
|
|
4
|
+
data.tar.gz: 44ba0061f1987733edf5a5dde93ce591fc9eb2ff63f3aae59854051313b59d84
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b054e8e101d09dcd88c954eaf82452c9e18629398eb2270d2eddcd89769562eac8325a0c55c77505d5a1f2ecf5f2c7fa644d65e9eec318045c37832dbc3d92f
|
|
7
|
+
data.tar.gz: 9c7feb08613c99ef5fb206170dedb9e841a846e6d7077f4e06c8fa0673f19764f0ea5acff74da590e4879f7e78cb72213b9ceea35e76990f6b38e1aebabef26f
|
data/lib/railscope/context.rb
CHANGED
|
@@ -87,5 +87,30 @@ module Railscope
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
delegate :empty?, to: :@store
|
|
90
|
+
|
|
91
|
+
# Conditional recording: buffer entries until a trigger fires
|
|
92
|
+
|
|
93
|
+
def pending_entries
|
|
94
|
+
self[:pending_entries] ||= []
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def triggered?
|
|
98
|
+
self[:triggered] == true
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def trigger!
|
|
102
|
+
self[:triggered] = true
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def buffer_entry(entry_data)
|
|
106
|
+
pending_entries << entry_data
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def flush_pending!
|
|
110
|
+
pending_entries.each do |entry_data|
|
|
111
|
+
Railscope.storage.write(**entry_data)
|
|
112
|
+
end
|
|
113
|
+
pending_entries.clear
|
|
114
|
+
end
|
|
90
115
|
end
|
|
91
116
|
end
|
data/lib/railscope/middleware.rb
CHANGED
|
@@ -18,17 +18,20 @@ module Railscope
|
|
|
18
18
|
# Capture response body for recording
|
|
19
19
|
context = Context.current
|
|
20
20
|
if context[:recording]
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
# In conditional mode, skip persistence if trigger never fired
|
|
22
|
+
unless Railscope.conditional_recording? && !context.triggered?
|
|
23
|
+
# Read body from env (where Rails stores the response)
|
|
24
|
+
body_content = extract_body_from_env(env)
|
|
25
|
+
|
|
26
|
+
context_data = {
|
|
27
|
+
batch_id: context.batch_id,
|
|
28
|
+
env: env,
|
|
29
|
+
headers: headers
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Update entry with response data
|
|
33
|
+
update_entry_async(context_data, body_content)
|
|
34
|
+
end
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
[status, headers, response]
|
|
@@ -29,7 +29,7 @@ module Railscope
|
|
|
29
29
|
|
|
30
30
|
filtered_payload = Railscope.filter(payload.merge(context_payload))
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
entry_data = {
|
|
33
33
|
entry_type: entry_type,
|
|
34
34
|
batch_id: context.batch_id,
|
|
35
35
|
family_hash: family_hash,
|
|
@@ -37,7 +37,13 @@ module Railscope
|
|
|
37
37
|
payload: filtered_payload,
|
|
38
38
|
tags: (tags + context_tags).uniq,
|
|
39
39
|
occurred_at: Time.current
|
|
40
|
-
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if Railscope.conditional_recording? && !context.triggered?
|
|
43
|
+
context.buffer_entry(entry_data)
|
|
44
|
+
else
|
|
45
|
+
Railscope.storage.write(**entry_data)
|
|
46
|
+
end
|
|
41
47
|
end
|
|
42
48
|
|
|
43
49
|
# Generate a family hash for grouping similar entries
|
|
@@ -76,7 +76,12 @@ module Railscope
|
|
|
76
76
|
# Also create a separate exception entry if job failed
|
|
77
77
|
create_exception_entry!(job, exception_object) if exception_object
|
|
78
78
|
|
|
79
|
-
#
|
|
79
|
+
# In conditional mode: flush if triggered, otherwise entries are discarded with context
|
|
80
|
+
if Railscope.conditional_recording? && context.triggered?
|
|
81
|
+
# Response update for jobs is already in the entry payload, nothing extra needed
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Clear context after job completes (discards any unflushed buffer)
|
|
80
85
|
Railscope::Context.clear!
|
|
81
86
|
rescue StandardError => e
|
|
82
87
|
Rails.logger.error("[Railscope] Failed to record job perform: #{e.message}")
|
|
@@ -42,6 +42,7 @@ module Railscope
|
|
|
42
42
|
model_name = model.class.name
|
|
43
43
|
return if model_name.nil?
|
|
44
44
|
return if IGNORED_MODEL_PREFIXES.any? { |prefix| model_name.start_with?(prefix) }
|
|
45
|
+
return unless Railscope.should_track_model?(model_name)
|
|
45
46
|
|
|
46
47
|
create_entry!(
|
|
47
48
|
entry_type: "model",
|
|
@@ -50,6 +51,13 @@ module Railscope
|
|
|
50
51
|
family_hash: build_family_hash(action, model),
|
|
51
52
|
should_display_on_index: true
|
|
52
53
|
)
|
|
54
|
+
|
|
55
|
+
# Conditional recording: flush buffered entries when trigger matches
|
|
56
|
+
if Railscope.conditional_recording? && !context.triggered? && Railscope.matches_trigger?(model_name, action)
|
|
57
|
+
context.trigger!
|
|
58
|
+
context.flush_pending!
|
|
59
|
+
end
|
|
60
|
+
|
|
53
61
|
Rails.logger.debug("[Railscope] ModelSubscriber - entry created for #{model_name}")
|
|
54
62
|
rescue StandardError => e
|
|
55
63
|
Rails.logger.error("[Railscope] Failed to record model event: #{e.class}: #{e.message}")
|
data/lib/railscope/version.rb
CHANGED
data/lib/railscope.rb
CHANGED
|
@@ -27,7 +27,8 @@ module Railscope
|
|
|
27
27
|
STORAGE_REDIS = :redis
|
|
28
28
|
|
|
29
29
|
class << self
|
|
30
|
-
attr_writer :retention_days, :redis, :storage_backend, :ignore_paths, :ignore_jobs, :ignore_commands
|
|
30
|
+
attr_writer :retention_days, :redis, :storage_backend, :ignore_paths, :ignore_jobs, :ignore_commands,
|
|
31
|
+
:ignore_models
|
|
31
32
|
attr_accessor :authenticate_with
|
|
32
33
|
|
|
33
34
|
def enabled=(value)
|
|
@@ -123,6 +124,43 @@ module Railscope
|
|
|
123
124
|
ignore_commands.any? { |pattern| command_name.match?(pattern) }
|
|
124
125
|
end
|
|
125
126
|
|
|
127
|
+
# Model filtering (blocklist)
|
|
128
|
+
|
|
129
|
+
def ignore_models
|
|
130
|
+
@ignore_models ||= []
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def add_ignore_models(*model_names)
|
|
134
|
+
@ignore_models = ignore_models.concat(model_names.flatten.map(&:to_s)).uniq
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def should_track_model?(model_name)
|
|
138
|
+
return false if model_name.nil?
|
|
139
|
+
|
|
140
|
+
ignore_models.none? { |pattern| model_name.match?(pattern) }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Conditional recording: only persist a batch when a watched model event fires
|
|
144
|
+
|
|
145
|
+
def watch_triggers
|
|
146
|
+
@watch_triggers ||= []
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def add_watch_trigger(model_name, on:)
|
|
150
|
+
actions = Array(on).map(&:to_s)
|
|
151
|
+
@watch_triggers = watch_triggers.push({ model: model_name.to_s, on: actions }).uniq
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def conditional_recording?
|
|
155
|
+
watch_triggers.any?
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def matches_trigger?(model_name, action)
|
|
159
|
+
watch_triggers.any? do |trigger|
|
|
160
|
+
model_name.match?(trigger[:model]) && trigger[:on].include?(action.to_s)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
126
164
|
def context
|
|
127
165
|
Context.current
|
|
128
166
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: railscope
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.11
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Phelipe Tussolini
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-02-18 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rails
|
|
@@ -155,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
155
155
|
- !ruby/object:Gem::Version
|
|
156
156
|
version: '0'
|
|
157
157
|
requirements: []
|
|
158
|
-
rubygems_version: 3.6.
|
|
158
|
+
rubygems_version: 3.6.2
|
|
159
159
|
specification_version: 4
|
|
160
160
|
summary: A debug assistant for Rails applications inspired by Laravel Telescope
|
|
161
161
|
test_files: []
|