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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +5 -0
  4. data/app/assets/stylesheets/rails_event_viewer/application.css +1 -1
  5. data/app/controllers/rails_event_viewer/application_controller.rb +1 -11
  6. data/app/controllers/rails_event_viewer/events_controller.rb +6 -6
  7. data/app/helpers/rails_event_viewer/application_helper.rb +21 -75
  8. data/app/models/rails_event_viewer/entry.rb +0 -26
  9. data/app/models/rails_event_viewer/page.rb +9 -0
  10. data/app/views/layouts/rails_event_viewer/application.html.erb +3 -4
  11. data/app/views/rails_event_viewer/analytics/overview.html.erb +11 -9
  12. data/app/views/rails_event_viewer/dashboard/index.html.erb +13 -13
  13. data/app/views/rails_event_viewer/event_types/index.html.erb +6 -6
  14. data/app/views/rails_event_viewer/event_types/show.html.erb +14 -14
  15. data/app/views/rails_event_viewer/events/_event_row.html.erb +8 -8
  16. data/app/views/rails_event_viewer/events/_filters_sidebar.html.erb +16 -14
  17. data/app/views/rails_event_viewer/events/index.html.erb +6 -6
  18. data/app/views/rails_event_viewer/events/show.html.erb +22 -22
  19. data/app/views/rails_event_viewer/groups/index.html.erb +7 -7
  20. data/app/views/rails_event_viewer/groups/show.html.erb +11 -11
  21. data/app/views/rails_event_viewer/shared/_navigation.html.erb +8 -14
  22. data/app/views/rails_event_viewer/shared/_pagination.html.erb +10 -10
  23. data/app/views/rails_event_viewer/shared/_stat_card.html.erb +5 -5
  24. data/db/migrate/20261002121337_create_rails_event_viewer_entries.rb +0 -1
  25. data/lib/generators/rails_event_viewer/install/templates/create_rails_event_viewer_entries.rb.erb +0 -1
  26. data/lib/rails_event_viewer/adapter.rb +0 -8
  27. data/lib/rails_event_viewer/adapters/active_record.rb +8 -44
  28. data/lib/rails_event_viewer/adapters/concerns/in_memory_filtering.rb +0 -7
  29. data/lib/rails_event_viewer/adapters/memory.rb +0 -4
  30. data/lib/rails_event_viewer/adapters/null.rb +0 -8
  31. data/lib/rails_event_viewer/adapters/redis.rb +3 -17
  32. data/lib/rails_event_viewer/flusher.rb +5 -5
  33. data/lib/rails_event_viewer/logging.rb +1 -11
  34. data/lib/rails_event_viewer/version.rb +1 -1
  35. data/lib/rails_event_viewer.rb +5 -5
  36. metadata +7 -2
  37. 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 = apply_name_filters(scope, relation)
153
- scope = apply_tag_filters(scope, relation)
154
- scope = apply_context_filters(scope, relation)
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 apply_name_filters(scope, relation)
161
- return scope if relation.names.blank?
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 }
@@ -24,10 +24,6 @@ module RailsEventViewer
24
24
  @max_events = max_events
25
25
  end
26
26
 
27
- def supports_retention?
28
- true
29
- end
30
-
31
27
  def write_events(new_events)
32
28
  return if new_events.empty?
33
29
 
@@ -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 fetch_all_filtered(relation).drop(relation.offset_value).take(relation.limit_value)
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
- fetch_all_filtered(relation).size
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
- fetch_all_events
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&.warn("[RailsEventViewer] Flusher thread still busy after #{shutdown_timeout}s writing #{@writing} events") if @thread.alive?
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&.warn("[RailsEventViewer] #{leftover} events still buffered at shutdown") if leftover.positive?
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&.warn("[RailsEventViewer] Dropped #{dropped} events because the buffer was full")
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&.debug("[RailsEventViewer] Flusher thread started (PID: #{Process.pid})")
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&.debug("[RailsEventViewer] Flusher thread stopped (PID: #{Process.pid})")
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
- logger = effective_logger
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
@@ -1,3 +1,3 @@
1
1
  module RailsEventViewer
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -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:migrations` and `rails db:migrate`. " \
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.3.1
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
- }