dbwatcher 0.1.5 → 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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/app/controllers/dbwatcher/base_controller.rb +95 -0
- data/app/controllers/dbwatcher/dashboard_controller.rb +12 -0
- data/app/controllers/dbwatcher/queries_controller.rb +24 -0
- data/app/controllers/dbwatcher/sessions_controller.rb +15 -20
- data/app/controllers/dbwatcher/tables_controller.rb +38 -0
- data/app/helpers/dbwatcher/application_helper.rb +103 -0
- data/app/helpers/dbwatcher/formatting_helper.rb +108 -0
- data/app/helpers/dbwatcher/session_helper.rb +27 -0
- data/app/views/dbwatcher/dashboard/index.html.erb +177 -0
- data/app/views/dbwatcher/queries/index.html.erb +240 -0
- data/app/views/dbwatcher/sessions/index.html.erb +120 -27
- data/app/views/dbwatcher/sessions/show.html.erb +326 -129
- data/app/views/dbwatcher/shared/_badge.html.erb +4 -0
- data/app/views/dbwatcher/shared/_data_table.html.erb +20 -0
- data/app/views/dbwatcher/shared/_header.html.erb +7 -0
- data/app/views/dbwatcher/shared/_page_layout.html.erb +20 -0
- data/app/views/dbwatcher/shared/_section_panel.html.erb +9 -0
- data/app/views/dbwatcher/shared/_stats_card.html.erb +11 -0
- data/app/views/dbwatcher/shared/_tab_bar.html.erb +6 -0
- data/app/views/dbwatcher/tables/changes.html.erb +225 -0
- data/app/views/dbwatcher/tables/index.html.erb +123 -0
- data/app/views/dbwatcher/tables/show.html.erb +86 -0
- data/app/views/layouts/dbwatcher/application.html.erb +375 -26
- data/config/routes.rb +17 -3
- data/lib/dbwatcher/configuration.rb +9 -1
- data/lib/dbwatcher/engine.rb +12 -7
- data/lib/dbwatcher/logging.rb +72 -0
- data/lib/dbwatcher/services/dashboard_data_aggregator.rb +121 -0
- data/lib/dbwatcher/services/query_filter_processor.rb +114 -0
- data/lib/dbwatcher/services/table_statistics_collector.rb +119 -0
- data/lib/dbwatcher/sql_logger.rb +107 -0
- data/lib/dbwatcher/storage/api/base_api.rb +134 -0
- data/lib/dbwatcher/storage/api/concerns/table_analyzer.rb +172 -0
- data/lib/dbwatcher/storage/api/query_api.rb +95 -0
- data/lib/dbwatcher/storage/api/session_api.rb +134 -0
- data/lib/dbwatcher/storage/api/table_api.rb +86 -0
- data/lib/dbwatcher/storage/base_storage.rb +113 -0
- data/lib/dbwatcher/storage/change_processor.rb +65 -0
- data/lib/dbwatcher/storage/concerns/data_normalizer.rb +134 -0
- data/lib/dbwatcher/storage/concerns/error_handler.rb +75 -0
- data/lib/dbwatcher/storage/concerns/timestampable.rb +74 -0
- data/lib/dbwatcher/storage/concerns/validatable.rb +117 -0
- data/lib/dbwatcher/storage/date_helper.rb +21 -0
- data/lib/dbwatcher/storage/errors.rb +86 -0
- data/lib/dbwatcher/storage/file_manager.rb +122 -0
- data/lib/dbwatcher/storage/null_session.rb +39 -0
- data/lib/dbwatcher/storage/query_storage.rb +338 -0
- data/lib/dbwatcher/storage/query_validator.rb +24 -0
- data/lib/dbwatcher/storage/session.rb +58 -0
- data/lib/dbwatcher/storage/session_operations.rb +37 -0
- data/lib/dbwatcher/storage/session_query.rb +71 -0
- data/lib/dbwatcher/storage/session_storage.rb +322 -0
- data/lib/dbwatcher/storage/table_storage.rb +237 -0
- data/lib/dbwatcher/storage.rb +112 -85
- data/lib/dbwatcher/tracker.rb +4 -55
- data/lib/dbwatcher/version.rb +1 -1
- data/lib/dbwatcher.rb +12 -2
- metadata +47 -1
data/lib/dbwatcher/storage.rb
CHANGED
@@ -1,109 +1,136 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "storage/base_storage"
|
4
|
+
require_relative "storage/concerns/error_handler"
|
5
|
+
require_relative "storage/concerns/timestampable"
|
6
|
+
require_relative "storage/concerns/validatable"
|
7
|
+
require_relative "storage/concerns/data_normalizer"
|
8
|
+
require_relative "storage/session_storage"
|
9
|
+
require_relative "storage/query_storage"
|
10
|
+
require_relative "storage/table_storage"
|
11
|
+
require_relative "storage/session_query"
|
12
|
+
require_relative "storage/api/base_api"
|
13
|
+
require_relative "storage/api/query_api"
|
14
|
+
require_relative "storage/api/table_api"
|
15
|
+
require_relative "storage/api/session_api"
|
16
|
+
require_relative "storage/session"
|
17
|
+
require_relative "storage/errors"
|
18
|
+
|
3
19
|
module Dbwatcher
|
4
|
-
|
20
|
+
# Storage module provides the main interface for database monitoring data persistence
|
21
|
+
#
|
22
|
+
# This module acts as a facade for different storage backends and provides
|
23
|
+
# clean API entry points for sessions, queries, and tables. It manages
|
24
|
+
# storage instances and provides cleanup operations.
|
25
|
+
#
|
26
|
+
# @example Basic usage
|
27
|
+
# Dbwatcher::Storage.sessions.create("My Session")
|
28
|
+
# Dbwatcher::Storage.sessions.recent.with_changes
|
29
|
+
# Dbwatcher::Storage.queries.save(query_data)
|
30
|
+
# Dbwatcher::Storage.tables.changes_for("users")
|
31
|
+
#
|
32
|
+
# @example Cleanup operations
|
33
|
+
# Dbwatcher::Storage.cleanup_old_sessions
|
34
|
+
# Dbwatcher::Storage.clear_all
|
35
|
+
# @see SessionAPI
|
36
|
+
# @see QueryAPI
|
37
|
+
# @see TableAPI
|
38
|
+
module Storage
|
5
39
|
class << self
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
# Update index
|
16
|
-
update_index(session)
|
17
|
-
|
18
|
-
# Clean old sessions if needed
|
19
|
-
cleanup_old_sessions
|
20
|
-
rescue StandardError => e
|
21
|
-
warn "Failed to save session #{session&.id}: #{e.message}"
|
40
|
+
# Provides access to session operations
|
41
|
+
#
|
42
|
+
# @return [SessionAPI] session API interface
|
43
|
+
# @example
|
44
|
+
# Dbwatcher::Storage.sessions.create("My Session")
|
45
|
+
# Dbwatcher::Storage.sessions.all
|
46
|
+
# Dbwatcher::Storage.sessions.recent.with_changes
|
47
|
+
def sessions
|
48
|
+
@sessions ||= Api::SessionAPI.new(session_storage)
|
22
49
|
end
|
23
50
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
rescue JSON::ParserError => e
|
33
|
-
warn "Failed to parse session file #{id}: #{e.message}"
|
34
|
-
nil
|
35
|
-
rescue StandardError => e
|
36
|
-
warn "Failed to load session #{id}: #{e.message}"
|
37
|
-
nil
|
51
|
+
# Provides access to query operations
|
52
|
+
#
|
53
|
+
# @return [QueryAPI] query API interface
|
54
|
+
# @example
|
55
|
+
# Dbwatcher::Storage.queries.save(query_data)
|
56
|
+
# Dbwatcher::Storage.queries.for_date(Date.today)
|
57
|
+
def queries
|
58
|
+
@queries ||= Api::QueryAPI.new(query_storage)
|
38
59
|
end
|
39
60
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
rescue StandardError => e
|
49
|
-
warn "Failed to load sessions: #{e.message}"
|
50
|
-
[]
|
61
|
+
# Provides access to table operations
|
62
|
+
#
|
63
|
+
# @return [TableAPI] table API interface
|
64
|
+
# @example
|
65
|
+
# Dbwatcher::Storage.tables.changes_for("users")
|
66
|
+
# Dbwatcher::Storage.tables.recent_changes
|
67
|
+
def tables
|
68
|
+
@tables ||= Api::TableAPI.new(table_storage)
|
51
69
|
end
|
52
70
|
|
53
|
-
|
54
|
-
|
55
|
-
|
71
|
+
# Resets all cached storage instances (primarily for testing)
|
72
|
+
#
|
73
|
+
# This method clears all memoized storage instances, forcing them
|
74
|
+
# to be recreated on next access. Useful for testing scenarios.
|
75
|
+
#
|
76
|
+
# @return [void]
|
77
|
+
# @example
|
78
|
+
# Dbwatcher::Storage.reset_storage_instances!
|
79
|
+
def reset_storage_instances!
|
80
|
+
@session_storage = nil
|
81
|
+
@query_storage = nil
|
82
|
+
@table_storage = nil
|
83
|
+
@sessions = nil
|
84
|
+
@queries = nil
|
85
|
+
@tables = nil
|
56
86
|
end
|
57
87
|
|
58
|
-
|
88
|
+
# Cleanup operations
|
59
89
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
90
|
+
# Removes old session files based on configuration
|
91
|
+
#
|
92
|
+
# Automatically removes session files that exceed the configured
|
93
|
+
# retention period. This helps manage storage space usage.
|
94
|
+
#
|
95
|
+
# @return [void]
|
96
|
+
# @see Configuration#auto_clean_after_days
|
97
|
+
def cleanup_old_sessions
|
98
|
+
session_storage.cleanup_old_sessions
|
66
99
|
end
|
67
100
|
|
68
|
-
|
69
|
-
FileUtils.mkdir_p(sessions_path)
|
101
|
+
# Direct access to storage instances (for internal use)
|
70
102
|
|
71
|
-
|
72
|
-
|
73
|
-
|
103
|
+
# Returns the session storage instance
|
104
|
+
#
|
105
|
+
# @return [SessionStorage] the session storage instance
|
106
|
+
# @api private
|
107
|
+
def session_storage
|
108
|
+
@session_storage ||= SessionStorage.new
|
74
109
|
end
|
75
110
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
id: session.id,
|
83
|
-
name: session.name,
|
84
|
-
started_at: session.started_at,
|
85
|
-
ended_at: session.ended_at,
|
86
|
-
change_count: session.changes.count
|
87
|
-
})
|
88
|
-
|
89
|
-
# Keep only max_sessions
|
90
|
-
index = index.first(Dbwatcher.configuration.max_sessions)
|
91
|
-
|
92
|
-
File.write(index_file, JSON.pretty_generate(index))
|
93
|
-
rescue StandardError => e
|
94
|
-
warn "Failed to update sessions index: #{e.message}"
|
111
|
+
# Returns the query storage instance
|
112
|
+
#
|
113
|
+
# @return [QueryStorage] the query storage instance
|
114
|
+
# @api private
|
115
|
+
def query_storage
|
116
|
+
@query_storage ||= QueryStorage.new
|
95
117
|
end
|
96
118
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
119
|
+
# Returns the table storage instance
|
120
|
+
#
|
121
|
+
# @return [TableStorage] the table storage instance
|
122
|
+
# @api private
|
123
|
+
def table_storage
|
124
|
+
@table_storage ||= TableStorage.new(session_storage)
|
125
|
+
end
|
101
126
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
127
|
+
# Clears all storage data
|
128
|
+
#
|
129
|
+
# @return [Integer] total number of files removed
|
130
|
+
def clear_all
|
131
|
+
session_count = session_storage.clear_all
|
132
|
+
query_count = query_storage.clear_all
|
133
|
+
session_count + query_count
|
107
134
|
end
|
108
135
|
end
|
109
136
|
end
|
data/lib/dbwatcher/tracker.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "storage/session"
|
4
|
+
|
3
5
|
module Dbwatcher
|
4
6
|
class Tracker
|
5
7
|
class << self
|
@@ -30,7 +32,7 @@ module Dbwatcher
|
|
30
32
|
private
|
31
33
|
|
32
34
|
def create_session(name, metadata)
|
33
|
-
Session.new(
|
35
|
+
Storage::Session.new(
|
34
36
|
id: SecureRandom.uuid,
|
35
37
|
name: name || "Session #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}",
|
36
38
|
metadata: metadata || {},
|
@@ -50,63 +52,10 @@ module Dbwatcher
|
|
50
52
|
|
51
53
|
def finalize_session(session)
|
52
54
|
session.ended_at = Time.now.strftime("%Y-%m-%dT%H:%M:%S%z")
|
53
|
-
Storage.
|
55
|
+
Storage.sessions.create(session)
|
54
56
|
rescue StandardError
|
55
57
|
nil
|
56
58
|
end
|
57
59
|
end
|
58
|
-
|
59
|
-
class Session
|
60
|
-
attr_accessor :id, :name, :metadata, :started_at, :ended_at, :changes
|
61
|
-
|
62
|
-
def initialize(attrs = {})
|
63
|
-
# Set default values
|
64
|
-
@changes = []
|
65
|
-
@metadata = {}
|
66
|
-
|
67
|
-
# Set provided attributes
|
68
|
-
attrs.each do |key, value|
|
69
|
-
setter_method = "#{key}="
|
70
|
-
send(setter_method, value) if respond_to?(setter_method)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def to_h
|
75
|
-
{
|
76
|
-
id: id,
|
77
|
-
name: name,
|
78
|
-
metadata: metadata,
|
79
|
-
started_at: started_at,
|
80
|
-
ended_at: ended_at,
|
81
|
-
changes: changes
|
82
|
-
}
|
83
|
-
end
|
84
|
-
|
85
|
-
def summary
|
86
|
-
return {} unless changes.is_a?(Array)
|
87
|
-
|
88
|
-
valid_changes = filter_valid_changes
|
89
|
-
group_changes_by_operation(valid_changes)
|
90
|
-
rescue StandardError => e
|
91
|
-
warn "Failed to calculate session summary: #{e.message}"
|
92
|
-
{}
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
|
-
def filter_valid_changes
|
98
|
-
changes.select { |change| valid_change?(change) }
|
99
|
-
end
|
100
|
-
|
101
|
-
def valid_change?(change)
|
102
|
-
change.is_a?(Hash) && change[:table_name] && change[:operation]
|
103
|
-
end
|
104
|
-
|
105
|
-
def group_changes_by_operation(valid_changes)
|
106
|
-
valid_changes
|
107
|
-
.group_by { |change| "#{change[:table_name]},#{change[:operation]}" }
|
108
|
-
.transform_values(&:count)
|
109
|
-
end
|
110
|
-
end
|
111
60
|
end
|
112
61
|
end
|
data/lib/dbwatcher/version.rb
CHANGED
data/lib/dbwatcher.rb
CHANGED
@@ -3,12 +3,19 @@
|
|
3
3
|
require "json"
|
4
4
|
require "fileutils"
|
5
5
|
require "securerandom"
|
6
|
+
require "singleton"
|
7
|
+
require "logger"
|
6
8
|
require_relative "dbwatcher/version"
|
7
9
|
require_relative "dbwatcher/configuration"
|
10
|
+
require_relative "dbwatcher/logging"
|
8
11
|
require_relative "dbwatcher/tracker"
|
9
12
|
require_relative "dbwatcher/storage"
|
13
|
+
require_relative "dbwatcher/sql_logger"
|
10
14
|
require_relative "dbwatcher/model_extension"
|
11
15
|
require_relative "dbwatcher/middleware"
|
16
|
+
require_relative "dbwatcher/services/table_statistics_collector"
|
17
|
+
require_relative "dbwatcher/services/dashboard_data_aggregator"
|
18
|
+
require_relative "dbwatcher/services/query_filter_processor"
|
12
19
|
require_relative "dbwatcher/engine" if defined?(Rails)
|
13
20
|
|
14
21
|
module Dbwatcher
|
@@ -33,8 +40,11 @@ module Dbwatcher
|
|
33
40
|
Tracker.current_session
|
34
41
|
end
|
35
42
|
|
36
|
-
|
37
|
-
|
43
|
+
# Clears all stored data (sessions and queries)
|
44
|
+
#
|
45
|
+
# @return [Integer] total number of files removed
|
46
|
+
def clear_all
|
47
|
+
Storage.clear_all
|
38
48
|
end
|
39
49
|
end
|
40
50
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbwatcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Huy Nguyen
|
@@ -149,9 +149,28 @@ extra_rdoc_files: []
|
|
149
149
|
files:
|
150
150
|
- README.md
|
151
151
|
- Rakefile
|
152
|
+
- app/controllers/dbwatcher/base_controller.rb
|
153
|
+
- app/controllers/dbwatcher/dashboard_controller.rb
|
154
|
+
- app/controllers/dbwatcher/queries_controller.rb
|
152
155
|
- app/controllers/dbwatcher/sessions_controller.rb
|
156
|
+
- app/controllers/dbwatcher/tables_controller.rb
|
157
|
+
- app/helpers/dbwatcher/application_helper.rb
|
158
|
+
- app/helpers/dbwatcher/formatting_helper.rb
|
159
|
+
- app/helpers/dbwatcher/session_helper.rb
|
160
|
+
- app/views/dbwatcher/dashboard/index.html.erb
|
161
|
+
- app/views/dbwatcher/queries/index.html.erb
|
153
162
|
- app/views/dbwatcher/sessions/index.html.erb
|
154
163
|
- app/views/dbwatcher/sessions/show.html.erb
|
164
|
+
- app/views/dbwatcher/shared/_badge.html.erb
|
165
|
+
- app/views/dbwatcher/shared/_data_table.html.erb
|
166
|
+
- app/views/dbwatcher/shared/_header.html.erb
|
167
|
+
- app/views/dbwatcher/shared/_page_layout.html.erb
|
168
|
+
- app/views/dbwatcher/shared/_section_panel.html.erb
|
169
|
+
- app/views/dbwatcher/shared/_stats_card.html.erb
|
170
|
+
- app/views/dbwatcher/shared/_tab_bar.html.erb
|
171
|
+
- app/views/dbwatcher/tables/changes.html.erb
|
172
|
+
- app/views/dbwatcher/tables/index.html.erb
|
173
|
+
- app/views/dbwatcher/tables/show.html.erb
|
155
174
|
- app/views/layouts/dbwatcher/application.html.erb
|
156
175
|
- bin/console
|
157
176
|
- bin/release
|
@@ -160,9 +179,36 @@ files:
|
|
160
179
|
- lib/dbwatcher.rb
|
161
180
|
- lib/dbwatcher/configuration.rb
|
162
181
|
- lib/dbwatcher/engine.rb
|
182
|
+
- lib/dbwatcher/logging.rb
|
163
183
|
- lib/dbwatcher/middleware.rb
|
164
184
|
- lib/dbwatcher/model_extension.rb
|
185
|
+
- lib/dbwatcher/services/dashboard_data_aggregator.rb
|
186
|
+
- lib/dbwatcher/services/query_filter_processor.rb
|
187
|
+
- lib/dbwatcher/services/table_statistics_collector.rb
|
188
|
+
- lib/dbwatcher/sql_logger.rb
|
165
189
|
- lib/dbwatcher/storage.rb
|
190
|
+
- lib/dbwatcher/storage/api/base_api.rb
|
191
|
+
- lib/dbwatcher/storage/api/concerns/table_analyzer.rb
|
192
|
+
- lib/dbwatcher/storage/api/query_api.rb
|
193
|
+
- lib/dbwatcher/storage/api/session_api.rb
|
194
|
+
- lib/dbwatcher/storage/api/table_api.rb
|
195
|
+
- lib/dbwatcher/storage/base_storage.rb
|
196
|
+
- lib/dbwatcher/storage/change_processor.rb
|
197
|
+
- lib/dbwatcher/storage/concerns/data_normalizer.rb
|
198
|
+
- lib/dbwatcher/storage/concerns/error_handler.rb
|
199
|
+
- lib/dbwatcher/storage/concerns/timestampable.rb
|
200
|
+
- lib/dbwatcher/storage/concerns/validatable.rb
|
201
|
+
- lib/dbwatcher/storage/date_helper.rb
|
202
|
+
- lib/dbwatcher/storage/errors.rb
|
203
|
+
- lib/dbwatcher/storage/file_manager.rb
|
204
|
+
- lib/dbwatcher/storage/null_session.rb
|
205
|
+
- lib/dbwatcher/storage/query_storage.rb
|
206
|
+
- lib/dbwatcher/storage/query_validator.rb
|
207
|
+
- lib/dbwatcher/storage/session.rb
|
208
|
+
- lib/dbwatcher/storage/session_operations.rb
|
209
|
+
- lib/dbwatcher/storage/session_query.rb
|
210
|
+
- lib/dbwatcher/storage/session_storage.rb
|
211
|
+
- lib/dbwatcher/storage/table_storage.rb
|
166
212
|
- lib/dbwatcher/tracker.rb
|
167
213
|
- lib/dbwatcher/version.rb
|
168
214
|
homepage: https://github.com/patrick204nqh/dbwatcher
|