rails_event_viewer 0.3.1 → 0.4.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/CHANGELOG.md +22 -0
- data/README.md +5 -0
- data/app/assets/stylesheets/rails_event_viewer/application.css +1 -1
- data/app/controllers/rails_event_viewer/application_controller.rb +1 -11
- data/app/controllers/rails_event_viewer/events_controller.rb +6 -6
- data/app/helpers/rails_event_viewer/application_helper.rb +21 -75
- data/app/models/rails_event_viewer/entry.rb +0 -26
- data/app/models/rails_event_viewer/page.rb +9 -0
- data/app/views/layouts/rails_event_viewer/application.html.erb +3 -4
- data/app/views/rails_event_viewer/analytics/overview.html.erb +11 -9
- data/app/views/rails_event_viewer/dashboard/index.html.erb +13 -13
- data/app/views/rails_event_viewer/event_types/index.html.erb +6 -6
- data/app/views/rails_event_viewer/event_types/show.html.erb +14 -14
- data/app/views/rails_event_viewer/events/_event_row.html.erb +8 -8
- data/app/views/rails_event_viewer/events/_filters_sidebar.html.erb +16 -14
- data/app/views/rails_event_viewer/events/index.html.erb +6 -6
- data/app/views/rails_event_viewer/events/show.html.erb +22 -22
- data/app/views/rails_event_viewer/groups/index.html.erb +7 -7
- data/app/views/rails_event_viewer/groups/show.html.erb +11 -11
- data/app/views/rails_event_viewer/shared/_navigation.html.erb +8 -14
- data/app/views/rails_event_viewer/shared/_pagination.html.erb +10 -10
- data/app/views/rails_event_viewer/shared/_stat_card.html.erb +5 -5
- data/db/migrate/20261002121337_create_rails_event_viewer_entries.rb +0 -1
- data/lib/generators/rails_event_viewer/install/templates/create_rails_event_viewer_entries.rb.erb +0 -1
- data/lib/rails_event_viewer/adapter.rb +0 -8
- data/lib/rails_event_viewer/adapters/active_record.rb +8 -44
- data/lib/rails_event_viewer/adapters/concerns/in_memory_filtering.rb +0 -7
- data/lib/rails_event_viewer/adapters/memory.rb +0 -4
- data/lib/rails_event_viewer/adapters/null.rb +0 -8
- data/lib/rails_event_viewer/adapters/redis.rb +3 -17
- data/lib/rails_event_viewer/flusher.rb +5 -5
- data/lib/rails_event_viewer/logging.rb +1 -11
- data/lib/rails_event_viewer/version.rb +1 -1
- data/lib/rails_event_viewer.rb +5 -5
- metadata +7 -2
- data/app/assets/stylesheets/rails_event_viewer/tailwind.css +0 -29
|
@@ -3,10 +3,6 @@ module RailsEventViewer
|
|
|
3
3
|
class ActiveRecord
|
|
4
4
|
include Adapter
|
|
5
5
|
|
|
6
|
-
def initialize(**options)
|
|
7
|
-
@options = options
|
|
8
|
-
end
|
|
9
|
-
|
|
10
6
|
def table_exists?
|
|
11
7
|
Entry.table_exists?
|
|
12
8
|
rescue ::ActiveRecord::NoDatabaseError
|
|
@@ -16,7 +12,6 @@ module RailsEventViewer
|
|
|
16
12
|
def write_events(events)
|
|
17
13
|
return if events.empty?
|
|
18
14
|
|
|
19
|
-
# Use insert_all for bulk inserts (more efficient)
|
|
20
15
|
records = events.map do |event|
|
|
21
16
|
{
|
|
22
17
|
name: event[:name],
|
|
@@ -32,7 +27,7 @@ module RailsEventViewer
|
|
|
32
27
|
}
|
|
33
28
|
end
|
|
34
29
|
|
|
35
|
-
Entry.insert_all(records)
|
|
30
|
+
Entry.insert_all(records, returning: false)
|
|
36
31
|
end
|
|
37
32
|
|
|
38
33
|
def fetch_events(relation)
|
|
@@ -88,16 +83,6 @@ module RailsEventViewer
|
|
|
88
83
|
end
|
|
89
84
|
end
|
|
90
85
|
|
|
91
|
-
def distinct_group_values(key, source: :context)
|
|
92
|
-
column = source == :tags ? :tags : :context
|
|
93
|
-
json_path = JsonQuery.extract_path(column, key)
|
|
94
|
-
|
|
95
|
-
Entry
|
|
96
|
-
.where(JsonQuery.extract_path_present(column, key))
|
|
97
|
-
.distinct
|
|
98
|
-
.pluck(Arel.sql(json_path))
|
|
99
|
-
end
|
|
100
|
-
|
|
101
86
|
def group_instances(key, source: :context, limit: 100)
|
|
102
87
|
column = source == :tags ? :tags : :context
|
|
103
88
|
json_path = JsonQuery.extract_path(column, key)
|
|
@@ -148,39 +133,18 @@ module RailsEventViewer
|
|
|
148
133
|
end
|
|
149
134
|
|
|
150
135
|
def build_scope(relation)
|
|
151
|
-
scope = Entry.order(occurred_at: :desc)
|
|
152
|
-
scope =
|
|
153
|
-
scope =
|
|
154
|
-
scope =
|
|
136
|
+
scope = Entry.order(occurred_at: :desc, id: :desc)
|
|
137
|
+
scope = scope.where(name: relation.names) if relation.names.present?
|
|
138
|
+
scope = apply_json_filters(scope, :tags, relation.tags)
|
|
139
|
+
scope = apply_json_filters(scope, :context, relation.contexts)
|
|
155
140
|
scope = apply_time_filters(scope, relation)
|
|
156
141
|
scope = apply_search(scope, relation)
|
|
157
142
|
scope
|
|
158
143
|
end
|
|
159
144
|
|
|
160
|
-
def
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if relation.names.size == 1
|
|
164
|
-
scope.where(name: relation.names.first)
|
|
165
|
-
else
|
|
166
|
-
scope.where(name: relation.names)
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def apply_tag_filters(scope, relation)
|
|
171
|
-
return scope if relation.tags.blank?
|
|
172
|
-
|
|
173
|
-
relation.tags.each do |key, value|
|
|
174
|
-
scope = scope.where(*JsonQuery.contains(:tags, key, value))
|
|
175
|
-
end
|
|
176
|
-
scope
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def apply_context_filters(scope, relation)
|
|
180
|
-
return scope if relation.contexts.blank?
|
|
181
|
-
|
|
182
|
-
relation.contexts.each do |key, value|
|
|
183
|
-
scope = scope.where(*JsonQuery.contains(:context, key, value))
|
|
145
|
+
def apply_json_filters(scope, column, filters)
|
|
146
|
+
filters.each do |key, value|
|
|
147
|
+
scope = scope.where(*JsonQuery.contains(column, key, value))
|
|
184
148
|
end
|
|
185
149
|
scope
|
|
186
150
|
end
|
|
@@ -6,13 +6,6 @@ module RailsEventViewer
|
|
|
6
6
|
module InMemoryFiltering
|
|
7
7
|
extend ActiveSupport::Concern
|
|
8
8
|
|
|
9
|
-
def distinct_group_values(key, source: :context)
|
|
10
|
-
in_memory_events
|
|
11
|
-
.map { |e| group_value_for(e, key, source) }
|
|
12
|
-
.compact
|
|
13
|
-
.uniq
|
|
14
|
-
end
|
|
15
|
-
|
|
16
9
|
def group_instances(key, source: :context, limit: 100)
|
|
17
10
|
in_memory_events
|
|
18
11
|
.group_by { |e| group_value_for(e, key, source).to_s }
|
|
@@ -11,10 +11,6 @@ module RailsEventViewer
|
|
|
11
11
|
false
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def supports_retention?
|
|
15
|
-
false
|
|
16
|
-
end
|
|
17
|
-
|
|
18
14
|
def write_events(events)
|
|
19
15
|
nil
|
|
20
16
|
end
|
|
@@ -51,10 +47,6 @@ module RailsEventViewer
|
|
|
51
47
|
0
|
|
52
48
|
end
|
|
53
49
|
|
|
54
|
-
def distinct_group_values(key, source: :context)
|
|
55
|
-
[]
|
|
56
|
-
end
|
|
57
|
-
|
|
58
50
|
def group_instances(key, source: :context, limit: 100)
|
|
59
51
|
[]
|
|
60
52
|
end
|
|
@@ -26,10 +26,6 @@ module RailsEventViewer
|
|
|
26
26
|
@max_events = max_events
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def supports_analytics?
|
|
30
|
-
true
|
|
31
|
-
end
|
|
32
|
-
|
|
33
29
|
def write_events(events)
|
|
34
30
|
return if events.empty?
|
|
35
31
|
|
|
@@ -57,7 +53,7 @@ module RailsEventViewer
|
|
|
57
53
|
|
|
58
54
|
def fetch_events(relation)
|
|
59
55
|
if relation.filtered?
|
|
60
|
-
return
|
|
56
|
+
return filter_events(in_memory_events, relation).drop(relation.offset_value).take(relation.limit_value)
|
|
61
57
|
end
|
|
62
58
|
|
|
63
59
|
start_idx = relation.offset_value
|
|
@@ -68,7 +64,7 @@ module RailsEventViewer
|
|
|
68
64
|
|
|
69
65
|
def count_events(relation)
|
|
70
66
|
if relation.filtered?
|
|
71
|
-
|
|
67
|
+
filter_events(in_memory_events, relation).size
|
|
72
68
|
else
|
|
73
69
|
@redis.with { |conn| conn.zcard(events_key) }
|
|
74
70
|
end
|
|
@@ -171,18 +167,8 @@ module RailsEventViewer
|
|
|
171
167
|
data
|
|
172
168
|
end
|
|
173
169
|
|
|
174
|
-
def fetch_all_events
|
|
175
|
-
serialized_events = @redis.with { |conn| conn.zrevrange(events_key, 0, -1) }
|
|
176
|
-
serialized_events.map { |json| deserialize_event(json) }
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def fetch_all_filtered(relation)
|
|
180
|
-
events = fetch_all_events
|
|
181
|
-
filter_events(events, relation)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
170
|
def in_memory_events
|
|
185
|
-
|
|
171
|
+
@redis.with { |conn| conn.zrevrange(events_key, 0, -1) }.map { |json| deserialize_event(json) }
|
|
186
172
|
end
|
|
187
173
|
end
|
|
188
174
|
end
|
|
@@ -56,7 +56,7 @@ module RailsEventViewer
|
|
|
56
56
|
if @thread&.alive?
|
|
57
57
|
@flush_requests << true
|
|
58
58
|
@thread.join(shutdown_timeout)
|
|
59
|
-
effective_logger
|
|
59
|
+
RailsEventViewer.effective_logger.warn("[RailsEventViewer] Flusher thread still busy after #{shutdown_timeout}s writing #{@writing} events") if @thread.alive?
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
@mutex.synchronize { @thread = nil }
|
|
@@ -72,7 +72,7 @@ module RailsEventViewer
|
|
|
72
72
|
|
|
73
73
|
report_dropped_events
|
|
74
74
|
leftover = @buffer.size
|
|
75
|
-
effective_logger
|
|
75
|
+
RailsEventViewer.effective_logger.warn("[RailsEventViewer] #{leftover} events still buffered at shutdown") if leftover.positive?
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def running?
|
|
@@ -126,7 +126,7 @@ module RailsEventViewer
|
|
|
126
126
|
end
|
|
127
127
|
return if dropped.zero?
|
|
128
128
|
|
|
129
|
-
effective_logger
|
|
129
|
+
RailsEventViewer.effective_logger.warn("[RailsEventViewer] Dropped #{dropped} events because the buffer was full")
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
def request_flush
|
|
@@ -143,7 +143,7 @@ module RailsEventViewer
|
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
def run_loop
|
|
146
|
-
effective_logger
|
|
146
|
+
RailsEventViewer.effective_logger.debug("[RailsEventViewer] Flusher thread started (PID: #{Process.pid})")
|
|
147
147
|
|
|
148
148
|
until shutdown_requested?
|
|
149
149
|
begin
|
|
@@ -157,7 +157,7 @@ module RailsEventViewer
|
|
|
157
157
|
end
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
-
effective_logger
|
|
160
|
+
RailsEventViewer.effective_logger.debug("[RailsEventViewer] Flusher thread stopped (PID: #{Process.pid})")
|
|
161
161
|
end
|
|
162
162
|
|
|
163
163
|
def wait_for_flush
|
|
@@ -3,17 +3,7 @@ module RailsEventViewer
|
|
|
3
3
|
private
|
|
4
4
|
|
|
5
5
|
def log_error(message)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if logger
|
|
9
|
-
logger.error(message)
|
|
10
|
-
else
|
|
11
|
-
warn message
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def effective_logger
|
|
16
|
-
RailsEventViewer.logger || (defined?(Rails) && Rails.logger)
|
|
6
|
+
RailsEventViewer.effective_logger.error(message)
|
|
17
7
|
end
|
|
18
8
|
end
|
|
19
9
|
end
|
data/lib/rails_event_viewer.rb
CHANGED
|
@@ -76,6 +76,10 @@ module RailsEventViewer
|
|
|
76
76
|
subscriber.stop!
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
+
def effective_logger
|
|
80
|
+
logger || (defined?(Rails) && Rails.logger) || (@fallback_logger ||= Logger.new($stdout))
|
|
81
|
+
end
|
|
82
|
+
|
|
79
83
|
private
|
|
80
84
|
|
|
81
85
|
def build_adapter
|
|
@@ -101,7 +105,7 @@ module RailsEventViewer
|
|
|
101
105
|
|
|
102
106
|
if storage_adapter == :active_record && !adapter_instance.table_exists?
|
|
103
107
|
effective_logger.warn "[RailsEventViewer] Table 'rails_event_viewer_entries' not found. " \
|
|
104
|
-
"Run `rails rails_event_viewer:install
|
|
108
|
+
"Run `bin/rails generate rails_event_viewer:install` and `bin/rails db:migrate`. " \
|
|
105
109
|
"Falling back to NullAdapter (events will not be persisted)."
|
|
106
110
|
require "rails_event_viewer/adapters/null"
|
|
107
111
|
Adapters::Null.new
|
|
@@ -109,10 +113,6 @@ module RailsEventViewer
|
|
|
109
113
|
adapter_instance
|
|
110
114
|
end
|
|
111
115
|
end
|
|
112
|
-
|
|
113
|
-
def effective_logger
|
|
114
|
-
logger || (defined?(Rails) && Rails.logger) || Logger.new($stdout)
|
|
115
|
-
end
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_event_viewer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keshav Biswa
|
|
@@ -30,6 +30,9 @@ dependencies:
|
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '5.0'
|
|
33
|
+
- - "<"
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '6'
|
|
33
36
|
type: :runtime
|
|
34
37
|
prerelease: false
|
|
35
38
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -37,6 +40,9 @@ dependencies:
|
|
|
37
40
|
- - ">="
|
|
38
41
|
- !ruby/object:Gem::Version
|
|
39
42
|
version: '5.0'
|
|
43
|
+
- - "<"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '6'
|
|
40
46
|
- !ruby/object:Gem::Dependency
|
|
41
47
|
name: groupdate
|
|
42
48
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -69,7 +75,6 @@ files:
|
|
|
69
75
|
- app/assets/javascripts/rails_event_viewer/chartjs-adapter-date-fns.bundle.min.js
|
|
70
76
|
- app/assets/javascripts/rails_event_viewer/chartkick.min.js
|
|
71
77
|
- app/assets/stylesheets/rails_event_viewer/application.css
|
|
72
|
-
- app/assets/stylesheets/rails_event_viewer/tailwind.css
|
|
73
78
|
- app/controllers/rails_event_viewer/analytics_controller.rb
|
|
74
79
|
- app/controllers/rails_event_viewer/application_controller.rb
|
|
75
80
|
- app/controllers/rails_event_viewer/dashboard_controller.rb
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
@tailwind base;
|
|
2
|
-
@tailwind components;
|
|
3
|
-
@tailwind utilities;
|
|
4
|
-
|
|
5
|
-
.json-tree {
|
|
6
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
7
|
-
font-size: 0.875rem;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.json-tree-key {
|
|
11
|
-
color: #4b5563;
|
|
12
|
-
font-weight: 500;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.json-tree-string {
|
|
16
|
-
color: #059669;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.json-tree-number {
|
|
20
|
-
color: #2563eb;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.json-tree-boolean {
|
|
24
|
-
color: #7c3aed;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.json-tree-null {
|
|
28
|
-
color: #9ca3af;
|
|
29
|
-
}
|