deprecation_collector 0.3.0 → 0.5.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/.rubocop.yml +2 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +4 -4
- data/Gemfile.lock +3 -2
- data/Rakefile +10 -6
- data/deprecation_collector.gemspec +2 -1
- data/gemfiles/rails_6.gemfile +3 -0
- data/gemfiles/rails_6.gemfile.lock +90 -86
- data/gemfiles/rails_7.gemfile +3 -0
- data/gemfiles/rails_7.gemfile.lock +85 -75
- data/gemfiles/rails_none.gemfile +3 -0
- data/gemfiles/rails_none.gemfile.lock +20 -7
- data/lib/deprecation_collector/deprecation.rb +2 -1
- data/lib/deprecation_collector/storage.rb +205 -0
- data/lib/deprecation_collector/version.rb +1 -1
- data/lib/deprecation_collector/web/application.rb +42 -20
- data/lib/deprecation_collector/web/helpers.rb +48 -4
- data/lib/deprecation_collector/web/router.rb +76 -49
- data/lib/deprecation_collector/web/utils.rb +10 -7
- data/lib/deprecation_collector/web/views/import.html.template.rb +13 -0
- data/lib/deprecation_collector/web/views/index.html.template.rb +57 -31
- data/lib/deprecation_collector/web/views/layout.html.template.rb +77 -4
- data/lib/deprecation_collector/web/views/show.html.template.rb +73 -4
- data/lib/deprecation_collector/web.rb +11 -2
- data/lib/deprecation_collector.rb +88 -116
- metadata +19 -3
@@ -1,13 +1,82 @@
|
|
1
1
|
_buf = ''; _buf << ("<header class=\"mb-3\"><h1>Deprecation</h1><a class=\"btn btn-secondary\"".freeze);
|
2
2
|
;
|
3
3
|
;
|
4
|
-
; _slim_codeattributes1 = deprecations_path; if _slim_codeattributes1; if _slim_codeattributes1 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes1))).to_s); _buf << ("\"".freeze); end; end; _buf << (">Back</a
|
5
|
-
; _slim_codeattributes2 = deprecation_path(@deprecation[:digest]); if _slim_codeattributes2; if _slim_codeattributes2 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes2))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\" title=\"Delete\"><span class=\"glyphicon glyphicon-trash insalesicon-trash\"></span>Delete</a
|
4
|
+
; _slim_codeattributes1 = deprecations_path; if _slim_codeattributes1; if _slim_codeattributes1 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes1))).to_s); _buf << ("\"".freeze); end; end; _buf << (">Back</a> <a class=\"btn btn-danger\" data-confirm=\"Delete?\" data-method=\"delete\"".freeze);
|
5
|
+
; _slim_codeattributes2 = deprecation_path(@deprecation[:digest]); if _slim_codeattributes2; if _slim_codeattributes2 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes2))).to_s); _buf << ("\"".freeze); end; end; _buf << (" rel=\"nofollow\" title=\"Delete\"><span class=\"glyphicon glyphicon-trash insalesicon-trash\"></span>Delete</a> </header><main><dl class=\"row\"><dt>Message</dt><dd><code>".freeze);
|
6
6
|
;
|
7
7
|
;
|
8
8
|
;
|
9
9
|
;
|
10
10
|
;
|
11
11
|
;
|
12
|
-
;
|
13
|
-
; _buf << (
|
12
|
+
;
|
13
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:message]))).to_s);
|
14
|
+
; _buf << ("</code></dd><dt>First time</dt><dd>".freeze);
|
15
|
+
;
|
16
|
+
;
|
17
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:first_timestamp]&.yield_self { |time| Time.at(time) }))).to_s);
|
18
|
+
;
|
19
|
+
; _buf << ("</dd>".freeze); if @deprecation[:count] > 1;
|
20
|
+
; _buf << ("<dt>Count</dt><dd>".freeze);
|
21
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:count]))).to_s);
|
22
|
+
;
|
23
|
+
; _buf << ("</dd>".freeze); end; _buf << ("<dt>Realm</dt><dd>".freeze);
|
24
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:realm]))).to_s);
|
25
|
+
;
|
26
|
+
; _buf << ("</dd>".freeze); if @deprecation[:ruby_version];
|
27
|
+
; _buf << ("<dt>Ruby</dt><dd>".freeze);
|
28
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:ruby_version]))).to_s);
|
29
|
+
; _buf << ("</dd>".freeze); end; if @deprecation[:rails_version];
|
30
|
+
; _buf << ("<dt>Rails</dt><dd>".freeze);
|
31
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:rails_version]))).to_s);
|
32
|
+
;
|
33
|
+
; _buf << ("</dd>".freeze); end; if @deprecation[:revision];
|
34
|
+
; _buf << ("<dt>Revision</dt><dd>".freeze);
|
35
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:revision]))).to_s);
|
36
|
+
; _buf << ("</dd>".freeze); end; if @deprecation[:hostname];
|
37
|
+
; _buf << ("<dt>Hostname</dt><dd>".freeze);
|
38
|
+
; _buf << ((::Temple::Utils.escape_html((@deprecation[:hostname]))).to_s);
|
39
|
+
;
|
40
|
+
; _buf << ("</dd>".freeze); end; if @deprecation[:context];
|
41
|
+
; _buf << ("<dt>Context</dt><dd><div class=\"card p-3\"><pre><code>".freeze);
|
42
|
+
;
|
43
|
+
;
|
44
|
+
;
|
45
|
+
; _buf << ((::Temple::Utils.escape_html((JSON.pretty_generate(@deprecation[:context])))).to_s);
|
46
|
+
;
|
47
|
+
; _buf << ("</code></pre></div></dd>".freeze); end; if @deprecation[:app_traceline];
|
48
|
+
; _buf << ("<dt>App traceline</dt><dd>".freeze);
|
49
|
+
;
|
50
|
+
; location, function = @deprecation[:app_traceline].split(':in `', 2);
|
51
|
+
; _buf << ("<code class=\"code_location\">".freeze); _buf << ((::Temple::Utils.escape_html((location))).to_s);
|
52
|
+
; _buf << ("</code> <i>".freeze); _buf << ((::Temple::Utils.escape_html((function.delete_suffix("'")))).to_s);
|
53
|
+
;
|
54
|
+
; _buf << ("</i></dd>".freeze); end; if @deprecation[:gem_traceline];
|
55
|
+
; _buf << ("<dt>Gem traceline</dt><dd>".freeze);
|
56
|
+
;
|
57
|
+
; location, function = @deprecation[:gem_traceline].split(':in `', 2);
|
58
|
+
; full_gemname = location.delete_prefix('/gems/').gsub(%r{/.*}, '');
|
59
|
+
; location_in_gem = location.delete_prefix("/gems/#{full_gemname}/");
|
60
|
+
; _buf << ("<i>".freeze); _buf << ((::Temple::Utils.escape_html((full_gemname))).to_s);
|
61
|
+
; _buf << ("</i> <code class=\"code_location\"".freeze); _slim_codeattributes3 = location_in_gem; if _slim_codeattributes3; if _slim_codeattributes3 == true; _buf << (" data-copy-value=\"\"".freeze); else; _buf << (" data-copy-value=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes3))).to_s); _buf << ("\"".freeze); end; end; _buf << (">".freeze); _buf << ((::Temple::Utils.escape_html((location_in_gem.delete_prefix('lib/')))).to_s);
|
62
|
+
; _buf << ("</code> <i>".freeze); _buf << ((::Temple::Utils.escape_html((function.delete_suffix("'")))).to_s);
|
63
|
+
;
|
64
|
+
; _buf << ("</i></dd>".freeze); end; if @deprecation[:full_backtrace];
|
65
|
+
; _buf << ("<dt>Backtrace</dt><dd>".freeze);
|
66
|
+
;
|
67
|
+
; @deprecation[:full_backtrace].each do |trace_line|;
|
68
|
+
; _buf << ("<div class=\"trace-line\">".freeze);
|
69
|
+
; location, function = trace_line.split(':in `', 2);
|
70
|
+
; _buf << ("<code class=\"code_location\">".freeze); _buf << ((::Temple::Utils.escape_html((location))).to_s);
|
71
|
+
; _buf << ("</code> <i>".freeze); _buf << ((::Temple::Utils.escape_html((function.delete_suffix("'")))).to_s);
|
72
|
+
;
|
73
|
+
; _buf << ("</i></div>".freeze); end; _buf << ("</dd>".freeze); end; fields_to_reject = %i[message first_timestamp count realm app_traceline gem_traceline full_backtrace ruby_version rails_version context revision hostname digest_base digest].to_set;
|
74
|
+
; additional_data = @deprecation.reject { |key,_val| fields_to_reject.include?(key) };
|
75
|
+
; if additional_data.size > 0;
|
76
|
+
; _buf << ("<dt>Additional data <div class=\"card p-3\"><pre><code>".freeze);
|
77
|
+
;
|
78
|
+
;
|
79
|
+
;
|
80
|
+
; _buf << ((::Temple::Utils.escape_html((JSON.pretty_generate additional_data))).to_s);
|
81
|
+
; _buf << ("</code></pre></div></dt>".freeze); end; _buf << ("</dl><a".freeze); _slim_codeattributes4 = deprecation_path(params[:id], format: 'json'); if _slim_codeattributes4; if _slim_codeattributes4 == true; _buf << (" href=\"\"".freeze); else; _buf << (" href=\"".freeze); _buf << ((::Temple::Utils.escape_html((_slim_codeattributes4))).to_s); _buf << ("\"".freeze); end; end; _buf << (">Raw json</a></main>".freeze);
|
82
|
+
; _buf
|
@@ -4,10 +4,17 @@ require "erb"
|
|
4
4
|
require "rack/content_length"
|
5
5
|
require "rack/builder"
|
6
6
|
|
7
|
-
require_relative
|
7
|
+
require_relative "web/application"
|
8
8
|
|
9
9
|
class DeprecationCollector
|
10
|
+
# rack app with a html interface to deprecation collector with a persistent storage like redis
|
10
11
|
class Web
|
12
|
+
attr_accessor :import_enabled
|
13
|
+
|
14
|
+
def initialize(import_enabled: nil)
|
15
|
+
@import_enabled = import_enabled
|
16
|
+
end
|
17
|
+
|
11
18
|
def self.call(env)
|
12
19
|
@app ||= new
|
13
20
|
@app.call(env)
|
@@ -22,11 +29,13 @@ class DeprecationCollector
|
|
22
29
|
end
|
23
30
|
|
24
31
|
private
|
32
|
+
|
25
33
|
def build
|
34
|
+
web = self
|
26
35
|
::Rack::Builder.new do
|
27
36
|
# use Rack::Static etc goes here
|
28
37
|
|
29
|
-
run Web::Application.new
|
38
|
+
run Web::Application.new(web)
|
30
39
|
end
|
31
40
|
end
|
32
41
|
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require_relative "deprecation_collector/version"
|
4
4
|
require_relative "deprecation_collector/deprecation"
|
5
5
|
require_relative "deprecation_collector/collectors"
|
6
|
+
require_relative "deprecation_collector/storage"
|
6
7
|
require "time"
|
7
|
-
require "redis"
|
8
8
|
require "json"
|
9
9
|
require "set"
|
10
10
|
|
@@ -52,37 +52,68 @@ class DeprecationCollector
|
|
52
52
|
end
|
53
53
|
|
54
54
|
# NB: count is expensive in production env (but possible if needed) - produces a lot of redis writes
|
55
|
-
attr_accessor :
|
55
|
+
attr_accessor :raise_on_deprecation, :save_full_backtrace,
|
56
56
|
:exclude_realms,
|
57
|
-
:
|
58
|
-
:app_revision, :app_root,
|
57
|
+
:app_name, :app_revision, :app_root,
|
59
58
|
:print_to_stderr, :print_recurring
|
60
|
-
|
59
|
+
attr_reader :count, :write_interval, :write_interval_jitter, :key_prefix
|
60
|
+
attr_writer :context_saver, :fingerprinter
|
61
61
|
|
62
62
|
def initialize(mutex: nil)
|
63
|
-
# on cruby hash itself is threadsafe, but we need to prevent races
|
64
|
-
@deprecations_mutex = mutex || Mutex.new
|
65
|
-
@deprecations = {}
|
66
|
-
@known_digests = Set.new
|
67
|
-
@last_write_time = current_time
|
68
63
|
@enabled = true
|
64
|
+
@instance_mutex = mutex
|
69
65
|
|
70
66
|
load_default_config
|
71
67
|
end
|
72
68
|
|
73
69
|
def load_default_config
|
74
|
-
|
75
|
-
|
70
|
+
if (redis = defined?($redis) && $redis) # rubocop:disable Style/GlobalVars
|
71
|
+
self.redis = redis
|
72
|
+
end
|
76
73
|
@raise_on_deprecation = false
|
77
74
|
@exclude_realms = []
|
78
75
|
@ignore_message_regexp = nil
|
79
76
|
@app_root = (defined?(Rails) && Rails.root.present? && Rails.root) || Dir.pwd
|
80
77
|
# NB: in production with hugreds of workers may easily overload redis with writes, so more delay needed:
|
81
|
-
|
82
|
-
|
78
|
+
self.count = false
|
79
|
+
self.write_interval = 900 # 15.minutes
|
80
|
+
self.write_interval_jitter = 60
|
83
81
|
@context_saver = nil
|
84
82
|
end
|
85
83
|
|
84
|
+
def redis=(val)
|
85
|
+
raise ArgumentError, "redis should not be nil" unless val
|
86
|
+
|
87
|
+
@storage ||= DeprecationCollector::Storage::Redis.new(val, mutex: @instance_mutex, count: count, # rubocop:disable Naming/MemoizedInstanceVariableName
|
88
|
+
write_interval: write_interval,
|
89
|
+
write_interval_jitter: write_interval_jitter,
|
90
|
+
key_prefix: key_prefix)
|
91
|
+
end
|
92
|
+
|
93
|
+
def count=(val)
|
94
|
+
storage.count = val if storage.respond_to?(:count)
|
95
|
+
@count = val
|
96
|
+
end
|
97
|
+
|
98
|
+
def write_interval=(val)
|
99
|
+
storage.write_interval = val if storage.respond_to?(:write_interval)
|
100
|
+
@write_interval = val
|
101
|
+
end
|
102
|
+
|
103
|
+
def write_interval_jitter=(val)
|
104
|
+
storage.write_interval_jitter = val if storage.respond_to?(:write_interval_jitter)
|
105
|
+
@write_interval_jitter = val
|
106
|
+
end
|
107
|
+
|
108
|
+
def key_prefix=(val)
|
109
|
+
storage.key_prefix = val
|
110
|
+
@key_prefix = val
|
111
|
+
end
|
112
|
+
|
113
|
+
def storage
|
114
|
+
@storage ||= DeprecationCollector::Storage::StdErr.new
|
115
|
+
end
|
116
|
+
|
86
117
|
def ignored_messages=(val)
|
87
118
|
@ignore_message_regexp = (val && Regexp.union(val)) || nil
|
88
119
|
end
|
@@ -127,123 +158,81 @@ class DeprecationCollector
|
|
127
158
|
@count
|
128
159
|
end
|
129
160
|
|
130
|
-
def redis
|
131
|
-
raise "DeprecationCollector#redis is not set" unless @redis
|
132
|
-
|
133
|
-
@redis
|
134
|
-
end
|
135
|
-
|
136
161
|
def write_to_redis(force: false)
|
137
|
-
return unless force ||
|
138
|
-
|
139
|
-
deprecations_to_flush = nil
|
140
|
-
@deprecations_mutex.synchronize do
|
141
|
-
deprecations_to_flush = @deprecations
|
142
|
-
@deprecations = {}
|
143
|
-
@last_write_time = current_time
|
144
|
-
# checking in this section to prevent multiple parallel check requests
|
145
|
-
return (@enabled = false) unless enabled_in_redis?
|
146
|
-
end
|
162
|
+
return unless force || @enabled
|
147
163
|
|
148
|
-
|
149
|
-
|
150
|
-
# make as few writes as possible, other workers may already have reported our warning
|
151
|
-
fetch_known_digests
|
152
|
-
deprecations_to_flush.reject! { |digest, _val| @known_digests.include?(digest) }
|
153
|
-
return unless deprecations_to_flush.any?
|
154
|
-
|
155
|
-
@known_digests.merge(deprecations_to_flush.keys)
|
156
|
-
@redis.mapped_hmset("deprecations:data", deprecations_to_flush.transform_values(&:to_json))
|
164
|
+
storage.flush(force: force)
|
157
165
|
end
|
158
166
|
|
159
167
|
# prevent fresh process from wiring frequent already known messages
|
160
168
|
def fetch_known_digests
|
161
|
-
|
169
|
+
storage.fetch_known_digests
|
162
170
|
end
|
163
171
|
|
164
172
|
def flush_redis(enable: false)
|
165
|
-
|
166
|
-
@redis.del("deprecations:enabled") if enable
|
167
|
-
@deprecations.clear
|
168
|
-
@known_digests.clear
|
173
|
+
storage.clear(enable: enable)
|
169
174
|
end
|
170
175
|
|
171
176
|
def enabled_in_redis?
|
172
|
-
|
177
|
+
storage.enabled?
|
178
|
+
end
|
179
|
+
|
180
|
+
def enabled?
|
181
|
+
@enabled
|
173
182
|
end
|
174
183
|
|
175
184
|
def enable
|
185
|
+
storage.enable
|
176
186
|
@enabled = true
|
177
|
-
@redis.set("deprecations:enabled", "true")
|
178
187
|
end
|
179
188
|
|
180
189
|
def disable
|
181
190
|
@enabled = false
|
182
|
-
|
191
|
+
storage.disable
|
183
192
|
end
|
184
193
|
|
185
194
|
def dump
|
186
|
-
read_each.to_a.to_json
|
195
|
+
read_each.to_a.compact.to_json
|
196
|
+
end
|
197
|
+
|
198
|
+
def import_dump(json)
|
199
|
+
dump = JSON.parse(json)
|
200
|
+
# TODO: some checks
|
201
|
+
|
202
|
+
digests = dump.map { |dep| dep["digest"] }
|
203
|
+
raise "need digests" unless digests.none?(&:nil?)
|
204
|
+
|
205
|
+
dump_hash = dump.map { |dep| [dep.delete("digest"), dep] }.to_h
|
206
|
+
|
207
|
+
storage.import(dump_hash)
|
187
208
|
end
|
188
209
|
|
189
210
|
def read_each
|
190
211
|
return to_enum(:read_each) unless block_given?
|
191
212
|
|
192
|
-
|
193
|
-
|
194
|
-
cursor, data_pairs = @redis.hscan("deprecations:data", cursor)
|
195
|
-
|
196
|
-
if data_pairs.any?
|
197
|
-
data_pairs.zip(
|
198
|
-
@redis.hmget("deprecations:counter", data_pairs.map(&:first)),
|
199
|
-
@redis.hmget("deprecations:notes", data_pairs.map(&:first))
|
200
|
-
).each do |(digest, data), count, notes|
|
201
|
-
yield decode_deprecation(digest, data, count, notes)
|
202
|
-
end
|
203
|
-
end
|
204
|
-
break if cursor == "0"
|
213
|
+
storage.read_each do |digest, data, count, notes|
|
214
|
+
yield decode_deprecation(digest, data, count, notes)
|
205
215
|
end
|
206
216
|
end
|
207
217
|
|
208
218
|
def read_one(digest)
|
209
|
-
decode_deprecation(
|
210
|
-
digest,
|
211
|
-
*@redis.pipelined do |pipe|
|
212
|
-
pipe.hget("deprecations:data", digest)
|
213
|
-
pipe.hget("deprecations:counter", digest)
|
214
|
-
pipe.hget("deprecations:notes", digest)
|
215
|
-
end
|
216
|
-
)
|
219
|
+
decode_deprecation(*storage.read_one(digest))
|
217
220
|
end
|
218
221
|
|
219
222
|
def delete_deprecations(remove_digests)
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
end
|
228
|
-
|
229
|
-
def cleanup
|
230
|
-
cursor = 0
|
231
|
-
removed = total = 0
|
232
|
-
loop do
|
233
|
-
cursor, data_pairs = @redis.hscan("deprecations:data", cursor) # NB: some pages may be empty
|
234
|
-
total += data_pairs.size
|
235
|
-
removed += delete_deprecations(
|
236
|
-
data_pairs.to_h.select { |_digest, data| !block_given? || yield(JSON.parse(data, symbolize_names: true)) }.keys
|
237
|
-
)
|
238
|
-
break if cursor == "0"
|
239
|
-
end
|
240
|
-
"#{removed} removed, #{total - removed} left"
|
223
|
+
storage.delete(remove_digests)
|
224
|
+
end
|
225
|
+
|
226
|
+
def cleanup(&block)
|
227
|
+
raise ArgumentError, "provide a block to filter deprecations" unless block
|
228
|
+
|
229
|
+
storage.cleanup(&block)
|
241
230
|
end
|
242
231
|
|
243
232
|
protected
|
244
233
|
|
245
234
|
def unsent_deprecations
|
246
|
-
|
235
|
+
storage.unsent_deprecations
|
247
236
|
end
|
248
237
|
|
249
238
|
def store_deprecation(deprecation, allow_context: true)
|
@@ -251,51 +240,34 @@ class DeprecationCollector
|
|
251
240
|
|
252
241
|
deprecation.context = context_saver.call if context_saver && allow_context
|
253
242
|
deprecation.custom_fingerprint = fingerprinter.call(deprecation) if fingerprinter && allow_context
|
243
|
+
deprecation.app_name = app_name if app_name
|
254
244
|
|
255
|
-
|
256
|
-
@deprecations_mutex.synchronize do
|
257
|
-
(@deprecations[deprecation.digest] ||= deprecation).touch
|
258
|
-
end
|
259
|
-
|
260
|
-
write_to_redis if current_time - @last_write_time > (@write_interval + rand(@write_interval_jitter))
|
261
|
-
fresh
|
245
|
+
storage.store(deprecation)
|
262
246
|
end
|
263
247
|
|
264
248
|
def log_deprecation_if_needed(deprecation, fresh)
|
265
249
|
return unless print_to_stderr && !deprecation.ignored?
|
266
250
|
return unless fresh || print_recurring
|
267
251
|
|
252
|
+
log_deprecation(deprecation)
|
253
|
+
end
|
254
|
+
|
255
|
+
def log_deprecation(deprecation)
|
268
256
|
msg = deprecation.message
|
269
257
|
msg = "DEPRECATION: #{msg}" unless msg.start_with?("DEPRECAT")
|
270
258
|
$stderr.puts(msg) # rubocop:disable Style/StderrPuts
|
271
259
|
end
|
272
260
|
|
273
|
-
def current_time
|
274
|
-
return Time.zone.now if Time.respond_to?(:zone) && Time.zone
|
275
|
-
|
276
|
-
Time.now
|
277
|
-
end
|
278
|
-
|
279
261
|
def decode_deprecation(digest, data, count, notes)
|
280
262
|
return nil unless data
|
281
263
|
|
282
264
|
data = JSON.parse(data, symbolize_names: true)
|
283
|
-
|
284
|
-
|
285
|
-
return nil
|
286
|
-
end
|
265
|
+
# this should not happen (this means broken Deprecation#to_json or some data curruption)
|
266
|
+
return nil unless data.is_a?(Hash)
|
287
267
|
|
288
268
|
data[:digest] = digest
|
289
269
|
data[:notes] = JSON.parse(notes, symbolize_names: true) if notes
|
290
270
|
data[:count] = count.to_i if count
|
291
271
|
data
|
292
272
|
end
|
293
|
-
|
294
|
-
def write_count_to_redis(deprecations_to_flush)
|
295
|
-
@redis.pipelined do |pipe|
|
296
|
-
deprecations_to_flush.each_pair do |digest, deprecation|
|
297
|
-
pipe.hincrby("deprecations:counter", digest, deprecation.occurences)
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
273
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deprecation_collector
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vasily Fedoseyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04
|
11
|
+
date: 2023-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack-test
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
description: Collects and aggregates warnings and deprecations. Optimized for production
|
42
56
|
environment.
|
43
57
|
email:
|
@@ -66,12 +80,14 @@ files:
|
|
66
80
|
- lib/deprecation_collector.rb
|
67
81
|
- lib/deprecation_collector/collectors.rb
|
68
82
|
- lib/deprecation_collector/deprecation.rb
|
83
|
+
- lib/deprecation_collector/storage.rb
|
69
84
|
- lib/deprecation_collector/version.rb
|
70
85
|
- lib/deprecation_collector/web.rb
|
71
86
|
- lib/deprecation_collector/web/application.rb
|
72
87
|
- lib/deprecation_collector/web/helpers.rb
|
73
88
|
- lib/deprecation_collector/web/router.rb
|
74
89
|
- lib/deprecation_collector/web/utils.rb
|
90
|
+
- lib/deprecation_collector/web/views/import.html.template.rb
|
75
91
|
- lib/deprecation_collector/web/views/index.html.template.rb
|
76
92
|
- lib/deprecation_collector/web/views/layout.html.template.rb
|
77
93
|
- lib/deprecation_collector/web/views/show.html.template.rb
|
@@ -98,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
114
|
- !ruby/object:Gem::Version
|
99
115
|
version: '0'
|
100
116
|
requirements: []
|
101
|
-
rubygems_version: 3.4.
|
117
|
+
rubygems_version: 3.4.10
|
102
118
|
signing_key:
|
103
119
|
specification_version: 4
|
104
120
|
summary: Collector for ruby/rails deprecations and warnings, suitable for production
|