railswatch 1.0.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 (138) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +485 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/config/railswatch_manifest.js +0 -0
  6. data/app/assets/images/activity.svg +13 -0
  7. data/app/assets/images/bot.svg +1 -0
  8. data/app/assets/images/close.svg +13 -0
  9. data/app/assets/images/details.svg +3 -0
  10. data/app/assets/images/download.svg +3 -0
  11. data/app/assets/images/export.svg +13 -0
  12. data/app/assets/images/external.svg +1 -0
  13. data/app/assets/images/git.svg +1 -0
  14. data/app/assets/images/github.svg +1 -0
  15. data/app/assets/images/home.svg +16 -0
  16. data/app/assets/images/import.svg +13 -0
  17. data/app/assets/images/menu.svg +16 -0
  18. data/app/assets/images/moon.svg +3 -0
  19. data/app/assets/images/stat.svg +1 -0
  20. data/app/assets/images/sun.svg +4 -0
  21. data/app/assets/images/user.svg +1 -0
  22. data/app/controllers/railswatch/base_controller.rb +35 -0
  23. data/app/controllers/railswatch/concerns/csv_exportable.rb +31 -0
  24. data/app/controllers/railswatch/railswatch_controller.rb +183 -0
  25. data/app/engine_assets/javascripts/apex_ext.js +30 -0
  26. data/app/engine_assets/javascripts/application.js +9 -0
  27. data/app/engine_assets/javascripts/autoupdate.js +79 -0
  28. data/app/engine_assets/javascripts/charts.js +279 -0
  29. data/app/engine_assets/javascripts/navbar.js +11 -0
  30. data/app/engine_assets/javascripts/panel.js +43 -0
  31. data/app/engine_assets/javascripts/table.js +12 -0
  32. data/app/engine_assets/javascripts/theme.js +43 -0
  33. data/app/engine_assets/stylesheets/panel.css +111 -0
  34. data/app/engine_assets/stylesheets/responsive.css +102 -0
  35. data/app/engine_assets/stylesheets/style.css +960 -0
  36. data/app/helpers/railswatch/railswatch_helper.rb +338 -0
  37. data/app/views/railswatch/_panel.html.erb +15 -0
  38. data/app/views/railswatch/layouts/railswatch.html.erb +81 -0
  39. data/app/views/railswatch/railswatch/_card.html.erb +7 -0
  40. data/app/views/railswatch/railswatch/_chart.html.erb +13 -0
  41. data/app/views/railswatch/railswatch/_crashes_table_content.html.erb +62 -0
  42. data/app/views/railswatch/railswatch/_custom_events_table_content.html.erb +27 -0
  43. data/app/views/railswatch/railswatch/_delayed_job_table_content.html.erb +52 -0
  44. data/app/views/railswatch/railswatch/_export.html.erb +4 -0
  45. data/app/views/railswatch/railswatch/_grape_requests_table_content.html.erb +31 -0
  46. data/app/views/railswatch/railswatch/_overview.html.erb +124 -0
  47. data/app/views/railswatch/railswatch/_rake_tasks_table_content.html.erb +25 -0
  48. data/app/views/railswatch/railswatch/_recent_requests_table_content.html.erb +28 -0
  49. data/app/views/railswatch/railswatch/_recent_row.html.erb +41 -0
  50. data/app/views/railswatch/railswatch/_requests_table_content.html.erb +51 -0
  51. data/app/views/railswatch/railswatch/_sidekiq_jobs_table_content.html.erb +50 -0
  52. data/app/views/railswatch/railswatch/_summary.html.erb +50 -0
  53. data/app/views/railswatch/railswatch/_table.html.erb +30 -0
  54. data/app/views/railswatch/railswatch/_trace.html.erb +78 -0
  55. data/app/views/railswatch/railswatch/crashes.html.erb +2 -0
  56. data/app/views/railswatch/railswatch/custom.html.erb +6 -0
  57. data/app/views/railswatch/railswatch/delayed_job.html.erb +6 -0
  58. data/app/views/railswatch/railswatch/grape.html.erb +6 -0
  59. data/app/views/railswatch/railswatch/index.html.erb +9 -0
  60. data/app/views/railswatch/railswatch/rake.html.erb +6 -0
  61. data/app/views/railswatch/railswatch/recent.html.erb +2 -0
  62. data/app/views/railswatch/railswatch/requests.html.erb +2 -0
  63. data/app/views/railswatch/railswatch/resources.html.erb +28 -0
  64. data/app/views/railswatch/railswatch/sidekiq.html.erb +6 -0
  65. data/app/views/railswatch/railswatch/slow.html.erb +2 -0
  66. data/app/views/railswatch/railswatch/summary.js.erb +3 -0
  67. data/app/views/railswatch/railswatch/trace.js.erb +9 -0
  68. data/app/views/railswatch/shared/_header.html.erb +39 -0
  69. data/app/views/railswatch/shared/_page_header.html.erb +23 -0
  70. data/config/routes.rb +27 -0
  71. data/lib/generators/railswatch/install/USAGE +19 -0
  72. data/lib/generators/railswatch/install/install_generator.rb +46 -0
  73. data/lib/generators/railswatch/install/templates/create_railswatch_tables.rb +140 -0
  74. data/lib/generators/railswatch/install/templates/initializer.rb +87 -0
  75. data/lib/railswatch/data_source.rb +106 -0
  76. data/lib/railswatch/engine.rb +103 -0
  77. data/lib/railswatch/events/record.rb +63 -0
  78. data/lib/railswatch/extensions/trace.rb +14 -0
  79. data/lib/railswatch/extensions/trace_db.rb +21 -0
  80. data/lib/railswatch/gems/custom_ext.rb +38 -0
  81. data/lib/railswatch/gems/delayed_job_ext.rb +70 -0
  82. data/lib/railswatch/gems/grape_ext.rb +64 -0
  83. data/lib/railswatch/gems/rake_ext.rb +69 -0
  84. data/lib/railswatch/gems/sidekiq_ext.rb +55 -0
  85. data/lib/railswatch/instrument/metrics_collector.rb +70 -0
  86. data/lib/railswatch/interface.rb +9 -0
  87. data/lib/railswatch/models/application_record.rb +31 -0
  88. data/lib/railswatch/models/base_record.rb +59 -0
  89. data/lib/railswatch/models/collection.rb +37 -0
  90. data/lib/railswatch/models/custom_record.rb +32 -0
  91. data/lib/railswatch/models/delayed_job_record.rb +39 -0
  92. data/lib/railswatch/models/event_record.rb +11 -0
  93. data/lib/railswatch/models/grape_record.rb +61 -0
  94. data/lib/railswatch/models/rake_record.rb +33 -0
  95. data/lib/railswatch/models/request_record.rb +105 -0
  96. data/lib/railswatch/models/resource_record.rb +33 -0
  97. data/lib/railswatch/models/sidekiq_record.rb +41 -0
  98. data/lib/railswatch/models/trace_record.rb +21 -0
  99. data/lib/railswatch/pruner.rb +47 -0
  100. data/lib/railswatch/rails/middleware.rb +117 -0
  101. data/lib/railswatch/rails/query_builder.rb +20 -0
  102. data/lib/railswatch/reports/annotations_report.rb +13 -0
  103. data/lib/railswatch/reports/base_report.rb +48 -0
  104. data/lib/railswatch/reports/breakdown_report.rb +11 -0
  105. data/lib/railswatch/reports/crash_report.rb +11 -0
  106. data/lib/railswatch/reports/overview_report.rb +88 -0
  107. data/lib/railswatch/reports/percentile_report.rb +16 -0
  108. data/lib/railswatch/reports/recent_requests_report.rb +21 -0
  109. data/lib/railswatch/reports/requests_report.rb +75 -0
  110. data/lib/railswatch/reports/resources_report.rb +42 -0
  111. data/lib/railswatch/reports/response_time_report.rb +27 -0
  112. data/lib/railswatch/reports/slow_requests_report.rb +21 -0
  113. data/lib/railswatch/reports/throughput_report.rb +16 -0
  114. data/lib/railswatch/reports/trace_report.rb +17 -0
  115. data/lib/railswatch/system_monitor/resources_monitor.rb +88 -0
  116. data/lib/railswatch/thread/current_request.rb +37 -0
  117. data/lib/railswatch/utils.rb +58 -0
  118. data/lib/railswatch/version.rb +7 -0
  119. data/lib/railswatch/widgets/base.rb +17 -0
  120. data/lib/railswatch/widgets/card.rb +19 -0
  121. data/lib/railswatch/widgets/chart.rb +33 -0
  122. data/lib/railswatch/widgets/crashes_table.rb +27 -0
  123. data/lib/railswatch/widgets/custom_events_table.rb +48 -0
  124. data/lib/railswatch/widgets/delayed_job_table.rb +31 -0
  125. data/lib/railswatch/widgets/grape_requests_table.rb +31 -0
  126. data/lib/railswatch/widgets/percentile_card.rb +23 -0
  127. data/lib/railswatch/widgets/rake_tasks_table.rb +31 -0
  128. data/lib/railswatch/widgets/recent_requests_table.rb +35 -0
  129. data/lib/railswatch/widgets/requests_table.rb +27 -0
  130. data/lib/railswatch/widgets/resource_chart.rb +116 -0
  131. data/lib/railswatch/widgets/response_time_chart.rb +29 -0
  132. data/lib/railswatch/widgets/sidekiq_jobs_table.rb +31 -0
  133. data/lib/railswatch/widgets/slow_requests_table.rb +33 -0
  134. data/lib/railswatch/widgets/table.rb +43 -0
  135. data/lib/railswatch/widgets/throughput_chart.rb +29 -0
  136. data/lib/railswatch.rb +184 -0
  137. data/lib/tasks/railswatch.rake +9 -0
  138. metadata +445 -0
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railswatch
4
+ module Widgets
5
+ class ResourceChart < Chart
6
+ attr_reader :server, :key, :type
7
+
8
+ def initialize(server, key:, type:, **)
9
+ super(nil)
10
+ @server = server
11
+ @key = key
12
+ @type = type
13
+ end
14
+
15
+ def id
16
+ [key, 'report', server.key.parameterize].join('_')
17
+ end
18
+
19
+ def data
20
+ all_data = server.report.extract_signal { |event| signal(event) }
21
+ all_data[server.key]
22
+ end
23
+
24
+ def signal(event)
25
+ format(event[key])
26
+ end
27
+
28
+ def format(measurement)
29
+ measurement
30
+ end
31
+ end
32
+
33
+ class CPULoad < ResourceChart
34
+ def initialize(server)
35
+ super(
36
+ server,
37
+ key: :cpu,
38
+ type: 'Percentage',
39
+ subtitle: 'CPU',
40
+ description: 'CPU load average (1 min), average per 1 minute',
41
+ legend: 'CPU',
42
+ )
43
+ end
44
+
45
+ def format(measurement)
46
+ measurement['one_min'].to_f.round(2)
47
+ end
48
+
49
+ def measure
50
+ load_averages = Sys::CPU.load_avg
51
+ {
52
+ one_min: load_averages[0],
53
+ five_min: load_averages[1],
54
+ fifteen_min: load_averages[2]
55
+ }
56
+ rescue StandardError => e
57
+ ::Rails.logger.error "Error fetching CPU usage: #{e.message}"
58
+ { one_min: 0.0, five_min: 0.0, fifteen_min: 0.0 }
59
+ end
60
+ end
61
+
62
+ class MemoryUsage < ResourceChart
63
+ def initialize(server)
64
+ super(
65
+ server,
66
+ key: :memory,
67
+ type: 'Usage',
68
+ subtitle: 'Memory',
69
+ description: 'App memory usage',
70
+ legend: 'Usage',
71
+ )
72
+ end
73
+
74
+ def format(measurement)
75
+ measurement.to_f.round(2)
76
+ end
77
+
78
+ def measure
79
+ GetProcessMem.new.bytes
80
+ rescue StandardError => e
81
+ ::Rails.logger.error "Error fetching memory usage: #{e.message}"
82
+ 0
83
+ end
84
+ end
85
+
86
+ class DiskUsage < ResourceChart
87
+ def initialize(server)
88
+ super(
89
+ server,
90
+ key: :disk,
91
+ type: 'Usage',
92
+ subtitle: 'Storage',
93
+ description: 'Available storage size (local disk size)',
94
+ legend: 'Usage',
95
+ )
96
+ end
97
+
98
+ def format(measurement)
99
+ measurement['available'].to_f.round(2)
100
+ end
101
+
102
+ def measure
103
+ path = '/'
104
+ stat = Sys::Filesystem.stat(path)
105
+ {
106
+ available: stat.blocks_available * stat.block_size,
107
+ total: stat.blocks * stat.block_size,
108
+ used: (stat.blocks - stat.blocks_available) * stat.block_size
109
+ }
110
+ rescue StandardError => e
111
+ ::Rails.logger.error "Error fetching disk space: #{e.message}"
112
+ { available: 0, total: 0, used: 0 }
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railswatch
4
+ module Widgets
5
+ class ResponseTimeChart < Chart
6
+ def initialize(
7
+ datasource,
8
+ subtitle: 'Average Response Time Report',
9
+ description: 'All requests (site visitors, search engines, bots, etc)',
10
+ legend: 'Response Time',
11
+ units: nil
12
+ )
13
+ super
14
+ end
15
+
16
+ def id
17
+ 'response_time_report_chart'
18
+ end
19
+
20
+ def type
21
+ 'RT'
22
+ end
23
+
24
+ def data
25
+ Reports::ResponseTimeReport.new(datasource.db).data
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railswatch
4
+ module Widgets
5
+ class SidekiqJobsTable < Table
6
+ def subtitle
7
+ "Recent Jobs (last #{Railswatch.recent_requests_time_window / 60} minutes)"
8
+ end
9
+
10
+ def data
11
+ @data ||= Railswatch::Reports::RecentRequestsReport.new(datasource.db).data
12
+ end
13
+
14
+ def empty_message
15
+ 'Nothing to show here. Try to make a few requests in the main app.'
16
+ end
17
+
18
+ def show_export?
19
+ false
20
+ end
21
+
22
+ def table_classes
23
+ 'table is-fullwidth is-hoverable is-narrow'
24
+ end
25
+
26
+ def content_partial_path
27
+ 'railswatch/railswatch/sidekiq_jobs_table_content'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railswatch
4
+ module Widgets
5
+ class SlowRequestsTable < Table
6
+ def subtitle
7
+ window_minutes = Railswatch.slow_requests_time_window / 60
8
+ threshold = Railswatch.slow_requests_threshold
9
+ "Slow Requests (last #{window_minutes} minutes + slower than #{threshold}ms)"
10
+ end
11
+
12
+ def data
13
+ @data ||= Railswatch::Reports::SlowRequestsReport.new(datasource.db).data
14
+ end
15
+
16
+ def empty_message
17
+ 'Nothing to show here. Try to make a few requests in the main app.'
18
+ end
19
+
20
+ def table_id
21
+ 'recent'
22
+ end
23
+
24
+ def table_classes
25
+ 'table is-fullwidth is-hoverable is-narrow'
26
+ end
27
+
28
+ def content_partial_path
29
+ 'railswatch/railswatch/recent_requests_table_content'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railswatch
4
+ module Widgets
5
+ class Table < Base
6
+ def subtitle
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def data
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def empty_message
15
+ 'No data to display.'
16
+ end
17
+
18
+ def show_export?
19
+ true
20
+ end
21
+
22
+ def auto_update_interval
23
+ nil
24
+ end
25
+
26
+ def table_id
27
+ nil
28
+ end
29
+
30
+ def table_classes
31
+ 'table is-fullwidth is-hoverable'
32
+ end
33
+
34
+ def content_partial_path
35
+ raise NotImplementedError, 'Subclasses must define content_partial_path'
36
+ end
37
+
38
+ def to_partial_path
39
+ 'railswatch/railswatch/table'
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Railswatch
4
+ module Widgets
5
+ class ThroughputChart < Chart
6
+ def initialize(
7
+ datasource,
8
+ subtitle: 'Throughput Report',
9
+ description: 'All requests (site visitors, search engines, bots, etc)',
10
+ legend: 'RPM',
11
+ units: 'rpm'
12
+ )
13
+ super
14
+ end
15
+
16
+ def id
17
+ 'throughput_report_chart'
18
+ end
19
+
20
+ def type
21
+ 'TIR'
22
+ end
23
+
24
+ def data
25
+ Reports::ThroughputReport.new(datasource.db).data
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/railswatch.rb ADDED
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+ require 'browser'
5
+ require 'active_support/core_ext/integer'
6
+ require_relative 'railswatch/version'
7
+ require_relative 'railswatch/rails/query_builder'
8
+ require_relative 'railswatch/rails/middleware'
9
+ require_relative 'railswatch/models/application_record'
10
+ require_relative 'railswatch/models/base_record'
11
+ require_relative 'railswatch/models/request_record'
12
+ require_relative 'railswatch/models/sidekiq_record'
13
+ require_relative 'railswatch/models/delayed_job_record'
14
+ require_relative 'railswatch/models/grape_record'
15
+ require_relative 'railswatch/models/trace_record'
16
+ require_relative 'railswatch/models/rake_record'
17
+ require_relative 'railswatch/models/resource_record'
18
+ require_relative 'railswatch/models/custom_record'
19
+ require_relative 'railswatch/models/event_record'
20
+ require_relative 'railswatch/data_source'
21
+ require_relative 'railswatch/utils'
22
+ require_relative 'railswatch/reports/base_report'
23
+ require_relative 'railswatch/reports/requests_report'
24
+ require_relative 'railswatch/reports/crash_report'
25
+ require_relative 'railswatch/reports/response_time_report'
26
+ require_relative 'railswatch/reports/throughput_report'
27
+ require_relative 'railswatch/reports/recent_requests_report'
28
+ require_relative 'railswatch/reports/slow_requests_report'
29
+ require_relative 'railswatch/reports/breakdown_report'
30
+ require_relative 'railswatch/reports/trace_report'
31
+ require_relative 'railswatch/reports/percentile_report'
32
+ require_relative 'railswatch/reports/resources_report'
33
+ require_relative 'railswatch/reports/annotations_report'
34
+ require_relative 'railswatch/reports/overview_report'
35
+ require_relative 'railswatch/events/record'
36
+ require_relative 'railswatch/widgets/base'
37
+ require_relative 'railswatch/widgets/chart'
38
+ require_relative 'railswatch/widgets/card'
39
+ require_relative 'railswatch/widgets/table'
40
+ require_relative 'railswatch/widgets/throughput_chart'
41
+ require_relative 'railswatch/widgets/response_time_chart'
42
+ require_relative 'railswatch/widgets/percentile_card'
43
+ require_relative 'railswatch/widgets/resource_chart'
44
+ require_relative 'railswatch/widgets/requests_table'
45
+ require_relative 'railswatch/widgets/recent_requests_table'
46
+ require_relative 'railswatch/widgets/crashes_table'
47
+ require_relative 'railswatch/widgets/slow_requests_table'
48
+ require_relative 'railswatch/widgets/sidekiq_jobs_table'
49
+ require_relative 'railswatch/widgets/delayed_job_table'
50
+ require_relative 'railswatch/widgets/custom_events_table'
51
+ require_relative 'railswatch/widgets/grape_requests_table'
52
+ require_relative 'railswatch/widgets/rake_tasks_table'
53
+ require_relative 'railswatch/extensions/trace'
54
+ require_relative 'railswatch/extensions/trace_db'
55
+ require_relative 'railswatch/thread/current_request'
56
+ require_relative 'railswatch/interface'
57
+ require_relative 'railswatch/pruner'
58
+ require 'isolate_assets'
59
+
60
+ module Railswatch
61
+ extend Railswatch::Interface
62
+
63
+ FORMAT = '%Y%m%dT%H%M'
64
+
65
+ @duration = 4.hours
66
+ @recent_requests_time_window = 60.minutes
67
+ @recent_requests_limit = nil
68
+ @slow_requests_time_window = 4.hours
69
+ @slow_requests_limit = 500
70
+ @slow_requests_threshold = 500
71
+ @database_connection_name = nil
72
+ @debug = false
73
+ @enabled = true
74
+ @mount_at = '/railswatch'
75
+ @http_basic_authentication_enabled = false
76
+ @http_basic_authentication_user_name = 'railswatch'
77
+ @http_basic_authentication_password = 'password12'
78
+ @verify_access_proc = proc { |_controller| true }
79
+ @ignored_endpoints = Set.new([])
80
+ @ignored_paths = Set.new([])
81
+ @skip = false
82
+ @home_link = '/'
83
+ @skipable_rake_tasks = []
84
+ @custom_data_proc = nil
85
+ @current_user_proc = nil
86
+ @include_rake_tasks = false
87
+ @include_custom_events = true
88
+ @ignore_trace_headers = ['datetimei']
89
+ @url_options = nil
90
+ @system_monitor_duration = 24.hours
91
+ @retention = {
92
+ requests: @duration,
93
+ sidekiq: @duration,
94
+ delayed_job: @duration,
95
+ grape: @duration,
96
+ rake: @duration,
97
+ custom: @duration,
98
+ resources: @system_monitor_duration,
99
+ traces: @recent_requests_time_window,
100
+ events: nil
101
+ }
102
+ @system_monitors = %w[
103
+ CPULoad
104
+ MemoryUsage
105
+ DiskUsage
106
+ ]
107
+ @dashboard_charts = [
108
+ %w[P50Card P95Card P99Card],
109
+ 'ThroughputChart',
110
+ 'ResponseTimeChart'
111
+ ]
112
+ @_resource_monitor = nil
113
+ @_running_mode = nil
114
+ @_resource_monitor_enabled = false
115
+
116
+ class << self
117
+ attr_accessor :duration,
118
+ :recent_requests_time_window,
119
+ :recent_requests_limit,
120
+ :slow_requests_time_window,
121
+ :slow_requests_limit,
122
+ :slow_requests_threshold,
123
+ :database_connection_name,
124
+ :debug,
125
+ :enabled,
126
+ :mount_at,
127
+ :http_basic_authentication_enabled,
128
+ :http_basic_authentication_user_name,
129
+ :http_basic_authentication_password,
130
+ :verify_access_proc,
131
+ :skip,
132
+ :home_link,
133
+ :skipable_rake_tasks,
134
+ :custom_data_proc,
135
+ :current_user_proc,
136
+ :include_rake_tasks,
137
+ :include_custom_events,
138
+ :ignore_trace_headers,
139
+ :url_options,
140
+ :system_monitor_duration,
141
+ :retention,
142
+ :system_monitors,
143
+ :dashboard_charts,
144
+ :_resource_monitor,
145
+ :_running_mode,
146
+ :_resource_monitor_enabled
147
+
148
+ attr_reader :ignored_endpoints, :ignored_paths
149
+
150
+ def ignored_endpoints=(endpoints)
151
+ @ignored_endpoints = Set.new(endpoints)
152
+ end
153
+
154
+ def ignored_paths=(paths)
155
+ @ignored_paths = Set.new(paths)
156
+ end
157
+ end
158
+
159
+ def self.setup
160
+ yield(self)
161
+ end
162
+
163
+ def self.prune!
164
+ Railswatch::Pruner.call
165
+ end
166
+
167
+ def self.measure(...)
168
+ Railswatch::Gems::CustomExtension.measure(...)
169
+ end
170
+
171
+ def self.log(message)
172
+ return unless Railswatch.debug
173
+
174
+ if ::Rails.logger
175
+ ::Rails.logger.debug(message)
176
+ else
177
+ puts(message)
178
+ end
179
+ end
180
+ end
181
+
182
+ require 'railswatch/engine'
183
+
184
+ require_relative 'railswatch/gems/custom_ext'
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :railswatch do
4
+ desc 'Prune old railswatch records based on configured retention'
5
+ task prune: :environment do
6
+ results = Railswatch.prune!
7
+ puts results.map { |type, count| "#{type}: #{count}" }.join("\n")
8
+ end
9
+ end