dbwatcher 1.1.0 → 1.1.2
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/README.md +24 -2
- data/app/assets/javascripts/dbwatcher/components/changes_table_hybrid.js +12 -22
- data/app/assets/javascripts/dbwatcher/components/dashboard.js +325 -0
- data/app/assets/stylesheets/dbwatcher/application.css +394 -41
- data/app/assets/stylesheets/dbwatcher/application.scss +4 -0
- data/app/assets/stylesheets/dbwatcher/components/_badges.scss +68 -23
- data/app/assets/stylesheets/dbwatcher/components/_compact_table.scss +83 -26
- data/app/assets/stylesheets/dbwatcher/components/_diagrams.scss +3 -3
- data/app/assets/stylesheets/dbwatcher/components/_navigation.scss +9 -0
- data/app/assets/stylesheets/dbwatcher/components/_tabulator.scss +248 -0
- data/app/assets/stylesheets/dbwatcher/vendor/_tabulator_overrides.scss +37 -0
- data/app/controllers/dbwatcher/api/v1/system_info_controller.rb +180 -0
- data/app/controllers/dbwatcher/dashboard/system_info_controller.rb +64 -0
- data/app/controllers/dbwatcher/dashboard_controller.rb +17 -0
- data/app/controllers/dbwatcher/sessions_controller.rb +3 -19
- data/app/helpers/dbwatcher/application_helper.rb +43 -11
- data/app/helpers/dbwatcher/diagram_helper.rb +0 -88
- data/app/views/dbwatcher/dashboard/_layout.html.erb +27 -0
- data/app/views/dbwatcher/dashboard/_overview.html.erb +188 -0
- data/app/views/dbwatcher/dashboard/_system_info.html.erb +22 -0
- data/app/views/dbwatcher/dashboard/_system_info_content.html.erb +389 -0
- data/app/views/dbwatcher/dashboard/index.html.erb +8 -177
- data/app/views/dbwatcher/sessions/_changes.html.erb +91 -0
- data/app/views/dbwatcher/sessions/_layout.html.erb +23 -0
- data/app/views/dbwatcher/sessions/index.html.erb +107 -87
- data/app/views/dbwatcher/sessions/show.html.erb +10 -4
- data/app/views/dbwatcher/tables/index.html.erb +32 -40
- data/app/views/layouts/dbwatcher/application.html.erb +100 -48
- data/config/routes.rb +23 -6
- data/lib/dbwatcher/configuration.rb +18 -1
- data/lib/dbwatcher/services/base_service.rb +2 -0
- data/lib/dbwatcher/services/diagram_analyzers/model_association_analyzer.rb +177 -138
- data/lib/dbwatcher/services/diagram_data/dataset.rb +2 -0
- data/lib/dbwatcher/services/mermaid_syntax/class_diagram_builder.rb +13 -9
- data/lib/dbwatcher/services/mermaid_syntax/class_diagram_helper.rb +3 -1
- data/lib/dbwatcher/services/mermaid_syntax/sanitizer.rb +17 -1
- data/lib/dbwatcher/services/system_info/database_info_collector.rb +263 -0
- data/lib/dbwatcher/services/system_info/machine_info_collector.rb +387 -0
- data/lib/dbwatcher/services/system_info/runtime_info_collector.rb +328 -0
- data/lib/dbwatcher/services/system_info/system_info_collector.rb +114 -0
- data/lib/dbwatcher/storage/concerns/error_handler.rb +6 -6
- data/lib/dbwatcher/storage/session.rb +5 -0
- data/lib/dbwatcher/storage/system_info_storage.rb +242 -0
- data/lib/dbwatcher/storage.rb +12 -0
- data/lib/dbwatcher/version.rb +1 -1
- data/lib/dbwatcher.rb +15 -1
- metadata +20 -15
- data/app/helpers/dbwatcher/component_helper.rb +0 -29
- data/app/views/dbwatcher/sessions/_changes_tab.html.erb +0 -265
- data/app/views/dbwatcher/sessions/_tab_navigation.html.erb +0 -12
- data/app/views/dbwatcher/sessions/changes.html.erb +0 -21
- data/app/views/dbwatcher/sessions/components/changes/_filters.html.erb +0 -44
- data/app/views/dbwatcher/sessions/components/changes/_table_list.html.erb +0 -96
- data/app/views/dbwatcher/sessions/diagrams.html.erb +0 -21
- data/app/views/dbwatcher/sessions/shared/_layout.html.erb +0 -8
- data/app/views/dbwatcher/sessions/shared/_navigation.html.erb +0 -35
- data/app/views/dbwatcher/sessions/shared/_session_header.html.erb +0 -25
- data/app/views/dbwatcher/sessions/summary.html.erb +0 -21
- /data/app/views/dbwatcher/sessions/{_diagrams_tab.html.erb → _diagrams.html.erb} +0 -0
- /data/app/views/dbwatcher/sessions/{_summary_tab.html.erb → _summary.html.erb} +0 -0
@@ -29,6 +29,7 @@
|
|
29
29
|
<%= javascript_include_tag "dbwatcher/components/changes_table_hybrid" %>
|
30
30
|
<%= javascript_include_tag "dbwatcher/components/diagrams" %>
|
31
31
|
<%= javascript_include_tag "dbwatcher/components/summary" %>
|
32
|
+
<%= javascript_include_tag "dbwatcher/components/dashboard" %>
|
32
33
|
|
33
34
|
<!-- DBWatcher Services -->
|
34
35
|
<%= javascript_include_tag "dbwatcher/core/alpine_store" %>
|
@@ -56,9 +57,9 @@
|
|
56
57
|
}
|
57
58
|
});
|
58
59
|
|
59
|
-
//
|
60
|
+
// Improved initialization with safety checks
|
60
61
|
document.addEventListener('DOMContentLoaded', function() {
|
61
|
-
//
|
62
|
+
// Prevent immediate DOM access conflicts
|
62
63
|
setTimeout(() => {
|
63
64
|
try {
|
64
65
|
if (window.DBWatcher && !DBWatcher.initialized) {
|
@@ -68,16 +69,22 @@
|
|
68
69
|
} catch (error) {
|
69
70
|
console.error('❌ Error during DBWatcher fallback initialization:', error);
|
70
71
|
}
|
71
|
-
},
|
72
|
+
}, 150);
|
72
73
|
|
73
|
-
// Plugin verification
|
74
|
+
// Plugin verification with safety checks
|
74
75
|
setTimeout(() => {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
try {
|
77
|
+
if (window.Alpine && typeof window.Alpine.directive === 'function') {
|
78
|
+
if (!window.Alpine.directive('collapse')) {
|
79
|
+
console.warn('⚠️ Alpine.js Collapse plugin may not be properly loaded');
|
80
|
+
} else {
|
81
|
+
console.log('✅ Alpine.js Collapse plugin verified');
|
82
|
+
}
|
83
|
+
}
|
84
|
+
} catch (error) {
|
85
|
+
console.warn('⚠️ Alpine.js plugin verification failed:', error);
|
79
86
|
}
|
80
|
-
},
|
87
|
+
}, 300);
|
81
88
|
});
|
82
89
|
</script>
|
83
90
|
|
@@ -129,7 +136,7 @@
|
|
129
136
|
|
130
137
|
<!-- Navigation -->
|
131
138
|
<nav class="flex-1 py-2 overflow-y-auto">
|
132
|
-
<%= link_to root_path, class: "sidebar-item #{current_page?(root_path) ? 'active' : ''}" do %>
|
139
|
+
<%= link_to root_path, class: "sidebar-item #{current_page?(root_path) || (params[:tab] == 'system_info') ? 'active' : ''}" do %>
|
133
140
|
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
134
141
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
135
142
|
d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/>
|
@@ -160,6 +167,8 @@
|
|
160
167
|
</svg>
|
161
168
|
<span x-show="!sidebarCollapsed">SQL Logs</span>
|
162
169
|
<% end %>
|
170
|
+
|
171
|
+
|
163
172
|
</nav>
|
164
173
|
|
165
174
|
<!-- Actions -->
|
@@ -176,6 +185,42 @@
|
|
176
185
|
<span x-show="!sidebarCollapsed" class="text-xs">Clear All</span>
|
177
186
|
<% end %>
|
178
187
|
</div>
|
188
|
+
|
189
|
+
<!-- Gem Info Section -->
|
190
|
+
<div class="mt-auto pt-4 border-t border-gray-700">
|
191
|
+
<div class="px-3 py-2">
|
192
|
+
<div class="text-xs text-gray-400 mb-2 font-medium" x-show="!sidebarCollapsed">
|
193
|
+
dbwatcher v<%= Dbwatcher::VERSION %>
|
194
|
+
</div>
|
195
|
+
<div class="flex items-center gap-2 text-xs text-gray-400" x-show="!sidebarCollapsed">
|
196
|
+
<a href="https://github.com/patrick204nqh/dbwatcher"
|
197
|
+
target="_blank"
|
198
|
+
rel="noopener noreferrer"
|
199
|
+
class="hover:text-blue-400 transition-colors duration-200 flex items-center gap-1"
|
200
|
+
title="View on GitHub">
|
201
|
+
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 24 24">
|
202
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
203
|
+
</svg>
|
204
|
+
<span>GitHub</span>
|
205
|
+
</a>
|
206
|
+
<span class="text-gray-600">•</span>
|
207
|
+
<a href="https://rubydoc.info/gems/dbwatcher/<%= Dbwatcher::VERSION %>"
|
208
|
+
target="_blank"
|
209
|
+
rel="noopener noreferrer"
|
210
|
+
class="hover:text-red-400 transition-colors duration-200 flex items-center gap-1"
|
211
|
+
title="View Documentation">
|
212
|
+
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 24 24">
|
213
|
+
<path d="M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z"/>
|
214
|
+
</svg>
|
215
|
+
<span>Docs</span>
|
216
|
+
</a>
|
217
|
+
</div>
|
218
|
+
<!-- Collapsed state - just show version -->
|
219
|
+
<div class="text-xs text-gray-400 text-center" x-show="sidebarCollapsed" title="DBWatcher v<%= Dbwatcher::VERSION %>">
|
220
|
+
v<%= Dbwatcher::VERSION %>
|
221
|
+
</div>
|
222
|
+
</div>
|
223
|
+
</div>
|
179
224
|
</div>
|
180
225
|
</aside>
|
181
226
|
|
@@ -211,50 +256,57 @@
|
|
211
256
|
<!-- Initialize DBWatcher system -->
|
212
257
|
<script>
|
213
258
|
document.addEventListener('DOMContentLoaded', function() {
|
214
|
-
//
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
window.DBWatcher
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
259
|
+
// Add delay to prevent timing conflicts
|
260
|
+
setTimeout(() => {
|
261
|
+
try {
|
262
|
+
// Initialize DBWatcher if available
|
263
|
+
if (window.DBWatcher) {
|
264
|
+
// Ensure BaseComponent is available
|
265
|
+
if (!window.DBWatcher.BaseComponent && typeof DBWatcher.BaseComponent !== 'function') {
|
266
|
+
window.DBWatcher.BaseComponent = function(config = {}) {
|
267
|
+
return {
|
268
|
+
init() {
|
269
|
+
if (this.componentInit) {
|
270
|
+
try {
|
271
|
+
this.componentInit();
|
272
|
+
} catch (error) {
|
273
|
+
console.error("Error during component initialization:", error);
|
274
|
+
}
|
275
|
+
}
|
226
276
|
}
|
277
|
+
};
|
278
|
+
};
|
279
|
+
console.log('Added fallback BaseComponent');
|
280
|
+
}
|
281
|
+
|
282
|
+
// Register legacy components with Alpine directly if ComponentRegistry isn't available
|
283
|
+
if (!window.DBWatcher.ComponentRegistry) {
|
284
|
+
console.log('ComponentRegistry not available, using direct Alpine registration');
|
285
|
+
|
286
|
+
// Ensure Alpine is available with safety checks
|
287
|
+
if (window.Alpine && typeof window.Alpine.data === 'function') {
|
288
|
+
// Direct registration of components with Alpine
|
289
|
+
if (!window.Alpine.data('changesTable') && window.DBWatcher.components && window.DBWatcher.components.changesTable) {
|
290
|
+
window.Alpine.data('changesTable', (config = {}) => {
|
291
|
+
const component = window.DBWatcher.components.changesTable(config);
|
292
|
+
return component;
|
293
|
+
});
|
294
|
+
console.log('Registered changesTable component with Alpine');
|
227
295
|
}
|
228
296
|
}
|
229
|
-
};
|
230
|
-
};
|
231
|
-
console.log('Added fallback BaseComponent');
|
232
|
-
}
|
233
|
-
|
234
|
-
// Register legacy components with Alpine directly if ComponentRegistry isn't available
|
235
|
-
if (!window.DBWatcher.ComponentRegistry) {
|
236
|
-
console.log('ComponentRegistry not available, using direct Alpine registration');
|
237
|
-
|
238
|
-
// Ensure Alpine is available
|
239
|
-
if (window.Alpine) {
|
240
|
-
// Direct registration of components with Alpine
|
241
|
-
if (!window.Alpine.data('changesTable') && window.DBWatcher.components && window.DBWatcher.components.changesTable) {
|
242
|
-
window.Alpine.data('changesTable', (config = {}) => {
|
243
|
-
const component = window.DBWatcher.components.changesTable(config);
|
244
|
-
return component;
|
245
|
-
});
|
246
|
-
console.log('Registered changesTable component with Alpine');
|
247
297
|
}
|
248
|
-
}
|
249
|
-
}
|
250
298
|
|
251
|
-
|
252
|
-
|
299
|
+
console.log('✅ DBWatcher initialized (fallback)');
|
300
|
+
}
|
253
301
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
302
|
+
// Verify Alpine.js plugins with safety checks
|
303
|
+
if (window.Alpine && typeof window.Alpine.directive === 'function' && window.Alpine.directive('collapse')) {
|
304
|
+
console.log('✅ Alpine.js Collapse plugin verified');
|
305
|
+
}
|
306
|
+
} catch (error) {
|
307
|
+
console.error('❌ Error during DBWatcher system initialization:', error);
|
308
|
+
}
|
309
|
+
}, 200);
|
258
310
|
});
|
259
311
|
</script>
|
260
312
|
</body>
|
data/config/routes.rb
CHANGED
@@ -3,16 +3,20 @@
|
|
3
3
|
Dbwatcher::Engine.routes.draw do
|
4
4
|
root to: "dashboard#index"
|
5
5
|
|
6
|
-
# Dashboard
|
6
|
+
# Dashboard actions
|
7
7
|
delete :clear_all, to: "dashboard#clear_all"
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
# Dashboard system info actions
|
10
|
+
namespace :dashboard do
|
11
|
+
resources :system_info, only: [] do
|
12
|
+
collection do
|
13
|
+
post :refresh
|
14
|
+
delete :clear_cache
|
15
|
+
end
|
14
16
|
end
|
17
|
+
end
|
15
18
|
|
19
|
+
resources :sessions do
|
16
20
|
collection do
|
17
21
|
delete :clear
|
18
22
|
end
|
@@ -32,6 +36,19 @@ Dbwatcher::Engine.routes.draw do
|
|
32
36
|
get :diagram_types
|
33
37
|
end
|
34
38
|
end
|
39
|
+
|
40
|
+
# System information API routes
|
41
|
+
resources :system_info, only: [:index] do
|
42
|
+
collection do
|
43
|
+
post :refresh
|
44
|
+
get :machine
|
45
|
+
get :database
|
46
|
+
get :runtime
|
47
|
+
get :summary
|
48
|
+
delete :clear_cache
|
49
|
+
get :cache_status
|
50
|
+
end
|
51
|
+
end
|
35
52
|
end
|
36
53
|
end
|
37
54
|
|
@@ -21,6 +21,11 @@ module Dbwatcher
|
|
21
21
|
:diagram_preserve_table_case, :diagram_direction, :diagram_cardinality_format,
|
22
22
|
:diagram_show_attribute_count, :diagram_show_method_count
|
23
23
|
|
24
|
+
# System information configuration
|
25
|
+
attr_accessor :collect_system_info, :system_info_refresh_interval,
|
26
|
+
:collect_sensitive_env_vars, :system_info_cache_duration,
|
27
|
+
:system_info_include_performance_metrics
|
28
|
+
|
24
29
|
# Initialize with default values
|
25
30
|
def initialize
|
26
31
|
# Storage configuration defaults
|
@@ -30,7 +35,7 @@ module Dbwatcher
|
|
30
35
|
@auto_clean_after_days = 7
|
31
36
|
|
32
37
|
# Query tracking configuration defaults
|
33
|
-
@track_queries =
|
38
|
+
@track_queries = false
|
34
39
|
@slow_query_threshold = 200 # milliseconds
|
35
40
|
@max_query_logs_per_day = 1000
|
36
41
|
|
@@ -39,6 +44,9 @@ module Dbwatcher
|
|
39
44
|
|
40
45
|
# Initialize diagram configuration with defaults
|
41
46
|
initialize_diagram_config
|
47
|
+
|
48
|
+
# Initialize system information configuration with defaults
|
49
|
+
initialize_system_info_config
|
42
50
|
end
|
43
51
|
|
44
52
|
# Initialize diagram configuration with default values
|
@@ -56,6 +64,15 @@ module Dbwatcher
|
|
56
64
|
@diagram_show_method_count = true
|
57
65
|
end
|
58
66
|
|
67
|
+
# Initialize system information configuration with default values
|
68
|
+
def initialize_system_info_config
|
69
|
+
@collect_system_info = true
|
70
|
+
@system_info_refresh_interval = 5 * 60 # 5 minutes in seconds
|
71
|
+
@collect_sensitive_env_vars = false
|
72
|
+
@system_info_cache_duration = 60 * 60 # 1 hour in seconds
|
73
|
+
@system_info_include_performance_metrics = true
|
74
|
+
end
|
75
|
+
|
59
76
|
# Validate configuration
|
60
77
|
#
|
61
78
|
# @return [Boolean] true if configuration is valid
|