deprecation_collector 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +9 -3
- data/README.md +6 -2
- data/deprecation_collector.gemspec +1 -1
- data/lib/deprecation_collector/deprecation.rb +4 -2
- data/lib/deprecation_collector/version.rb +1 -1
- data/lib/deprecation_collector.rb +33 -18
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f45c8742c0a83f697b04d7a99af54749b354c25cfcffb78f152a680f8224584
|
4
|
+
data.tar.gz: ab25a06b38f3ebfe82a48136c8a58da8d61e4db93614af0c66e283771f0b61b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d395dc4cedb786ab398911e5de19568f44317040352f1b85a6fc45a45fce465d6c82b8092c2f74e0a6b1d18e4dedfbc3284d59767dad2f3a2202143acd969b81
|
7
|
+
data.tar.gz: 0f9a6cd6f02b9b674710db839fcce21f69a2af31a41cc552ad3266b7cd1c3eaa21dac1ac7f94f0208833536e29c20d70e0261e6b087bc548597035c45bc47799
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
-
== unreleased
|
1
|
+
== 0.0.5 (unreleased)
|
2
|
+
- options `print_to_stderr`, `print_recurring`
|
3
|
+
- fix redis deprecated `pipelined` block arity (support for redis 5)
|
2
4
|
|
5
|
+
== 0.0.4
|
6
|
+
- added first_timestamp to deprecations (unix timestamp of first occurrence, not accurate because a worker with later timestamp may dump its deprecations earlier)
|
7
|
+
|
8
|
+
== 0.0.3
|
9
|
+
- Fixed selective deprecation cleanup (`DeprecationCollector.instance.cleanup { |d| d[:message].include?('foo') }`)
|
3
10
|
|
4
11
|
== 0.0.2
|
5
12
|
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
deprecation_collector (0.0.
|
5
|
-
redis (>=
|
4
|
+
deprecation_collector (0.0.5)
|
5
|
+
redis (>= 3.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
@@ -84,8 +84,12 @@ GEM
|
|
84
84
|
nokogiri (~> 1)
|
85
85
|
rake
|
86
86
|
mini_mime (1.1.2)
|
87
|
+
mini_portile2 (2.8.0)
|
87
88
|
minitest (5.15.0)
|
88
89
|
nio4r (2.5.8)
|
90
|
+
nokogiri (1.13.6)
|
91
|
+
mini_portile2 (~> 2.8.0)
|
92
|
+
racc (~> 1.4)
|
89
93
|
nokogiri (1.13.6-x86_64-darwin)
|
90
94
|
racc (~> 1.4)
|
91
95
|
parallel (1.22.1)
|
@@ -123,7 +127,7 @@ GEM
|
|
123
127
|
thor (>= 0.20.3, < 2.0)
|
124
128
|
rainbow (3.1.1)
|
125
129
|
rake (13.0.6)
|
126
|
-
redis (4.
|
130
|
+
redis (4.8.0)
|
127
131
|
regexp_parser (2.5.0)
|
128
132
|
rexml (3.2.5)
|
129
133
|
rspec (3.11.0)
|
@@ -181,12 +185,14 @@ GEM
|
|
181
185
|
zeitwerk (2.5.4)
|
182
186
|
|
183
187
|
PLATFORMS
|
188
|
+
ruby
|
184
189
|
x86_64-darwin-21
|
185
190
|
|
186
191
|
DEPENDENCIES
|
187
192
|
deprecation_collector!
|
188
193
|
rails (= 6.0)
|
189
194
|
rake (~> 13.0)
|
195
|
+
redis (~> 4.8)
|
190
196
|
rspec (~> 3.0)
|
191
197
|
rubocop (~> 1.21)
|
192
198
|
rubocop-performance
|
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
[![Gem Version](https://badge.fury.io/rb/deprecation_collector.svg)](https://badge.fury.io/rb/deprecation_collector)
|
3
3
|
|
4
4
|
Collects ruby and rails deprecation warnings.
|
5
|
+
Designed to be suitable for use in production under load.
|
6
|
+
|
5
7
|
(gem is a work-in-process, documentation will come later)
|
6
8
|
|
7
9
|
## Installation
|
@@ -17,15 +19,17 @@ bundle add deprecation_collector
|
|
17
19
|
Add an initializer with configuration, like
|
18
20
|
|
19
21
|
```ruby
|
20
|
-
DeprecationCollector.create_instance(redis: your_redis_connection)
|
21
22
|
Rails.application.config.to_prepare do
|
22
23
|
DeprecationCollector.install do |instance|
|
24
|
+
instance.redis = Redis.new # default is $redis
|
23
25
|
instance.app_revision = ::GIT_REVISION
|
24
26
|
instance.count = false
|
25
27
|
instance.save_full_backtrace = true
|
26
28
|
instance.raise_on_deprecation = false
|
27
29
|
instance.write_interval = (::Rails.env.production? && 15.minutes) || 1.minute
|
28
30
|
instance.exclude_realms = %i[kernel] if Rails.env.production?
|
31
|
+
instance.print_to_stderr = true if Rails.env.development?
|
32
|
+
instance.print_recurring = false
|
29
33
|
instance.ignored_messages = [
|
30
34
|
"Ignoring db/schema_cache.yml because it has expired"
|
31
35
|
]
|
@@ -41,7 +45,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
41
45
|
|
42
46
|
## Contributing
|
43
47
|
|
44
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
48
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Vasfed/deprecation_collector.
|
45
49
|
|
46
50
|
## License
|
47
51
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
class DeprecationCollector
|
4
4
|
# :nodoc:
|
5
5
|
class Deprecation
|
6
|
-
attr_reader :message, :realm, :gem_traceline, :app_traceline, :occurences, :full_backtrace
|
6
|
+
attr_reader :message, :realm, :gem_traceline, :app_traceline, :occurences, :first_timestamp, :full_backtrace
|
7
7
|
|
8
8
|
CLEANUP_REGEXES = {
|
9
9
|
# rails views generated methods names are unique per-worker
|
@@ -20,6 +20,7 @@ class DeprecationCollector
|
|
20
20
|
@occurences = 0
|
21
21
|
@gem_traceline = find_gem_traceline(backtrace)
|
22
22
|
@app_traceline = find_app_traceline(backtrace)
|
23
|
+
@first_timestamp = Time.now.to_i
|
23
24
|
|
24
25
|
cleanup_prefixes.each do |path|
|
25
26
|
@gem_traceline.delete_prefix!(path)
|
@@ -53,7 +54,7 @@ class DeprecationCollector
|
|
53
54
|
end
|
54
55
|
|
55
56
|
def digest_base
|
56
|
-
"1:#{RUBY_VERSION}:#{Rails.version}:#{message_for_digest}:#{gem_traceline}:#{app_traceline}"
|
57
|
+
"1:#{RUBY_VERSION}:#{defined?(Rails) && Rails.version}:#{message_for_digest}:#{gem_traceline}:#{app_traceline}"
|
57
58
|
end
|
58
59
|
|
59
60
|
def as_json(_options = {})
|
@@ -68,6 +69,7 @@ class DeprecationCollector
|
|
68
69
|
hostname: Socket.gethostname,
|
69
70
|
revision: DeprecationCollector.instance.app_revision,
|
70
71
|
count: @occurences, # output anyway for frequency estimation (during write_interval inside single process)
|
72
|
+
first_timestamp: first_timestamp, # this may not be accurate, a worker with later timestamp may dump earlier
|
71
73
|
digest_base: digest_base # for debug purposes
|
72
74
|
}.compact
|
73
75
|
end
|
@@ -5,6 +5,7 @@ require_relative "deprecation_collector/deprecation"
|
|
5
5
|
require_relative "deprecation_collector/collectors"
|
6
6
|
require "time"
|
7
7
|
require "redis"
|
8
|
+
require "json"
|
8
9
|
|
9
10
|
# singleton class for collector
|
10
11
|
class DeprecationCollector
|
@@ -53,7 +54,8 @@ class DeprecationCollector
|
|
53
54
|
attr_accessor :count, :raise_on_deprecation, :save_full_backtrace,
|
54
55
|
:exclude_realms,
|
55
56
|
:write_interval, :write_interval_jitter,
|
56
|
-
:app_revision, :app_root
|
57
|
+
:app_revision, :app_root,
|
58
|
+
:print_to_stderr, :print_recurring
|
57
59
|
attr_writer :redis
|
58
60
|
|
59
61
|
def initialize(mutex: nil)
|
@@ -96,8 +98,8 @@ class DeprecationCollector
|
|
96
98
|
raise "Deprecation: #{message}" if @raise_on_deprecation
|
97
99
|
|
98
100
|
deprecation = Deprecation.new(message, realm, backtrace, cleanup_prefixes)
|
99
|
-
store_deprecation(deprecation)
|
100
|
-
log_deprecation_if_needed(deprecation)
|
101
|
+
fresh = store_deprecation(deprecation)
|
102
|
+
log_deprecation_if_needed(deprecation, fresh)
|
101
103
|
end
|
102
104
|
|
103
105
|
def unsent_data?
|
@@ -163,6 +165,10 @@ class DeprecationCollector
|
|
163
165
|
@redis.set("deprecations:enabled", "false")
|
164
166
|
end
|
165
167
|
|
168
|
+
def dump
|
169
|
+
read_each.to_a.to_json
|
170
|
+
end
|
171
|
+
|
166
172
|
def read_each
|
167
173
|
return to_enum(:read_each) unless block_given?
|
168
174
|
|
@@ -185,10 +191,10 @@ class DeprecationCollector
|
|
185
191
|
def read_one(digest)
|
186
192
|
decode_deprecation(
|
187
193
|
digest,
|
188
|
-
*@redis.pipelined do
|
189
|
-
|
190
|
-
|
191
|
-
|
194
|
+
*@redis.pipelined do |pipe|
|
195
|
+
pipe.hget("deprecations:data", digest)
|
196
|
+
pipe.hget("deprecations:counter", digest)
|
197
|
+
pipe.hget("deprecations:notes", digest)
|
192
198
|
end
|
193
199
|
)
|
194
200
|
end
|
@@ -196,10 +202,10 @@ class DeprecationCollector
|
|
196
202
|
def delete_deprecations(remove_digests)
|
197
203
|
return 0 unless remove_digests.any?
|
198
204
|
|
199
|
-
@redis.pipelined do
|
200
|
-
|
201
|
-
|
202
|
-
|
205
|
+
@redis.pipelined do |pipe|
|
206
|
+
pipe.hdel("deprecations:data", *remove_digests)
|
207
|
+
pipe.hdel("deprecations:notes", *remove_digests)
|
208
|
+
pipe.hdel("deprecations:counter", *remove_digests) if @count
|
203
209
|
end.first
|
204
210
|
end
|
205
211
|
|
@@ -210,7 +216,7 @@ class DeprecationCollector
|
|
210
216
|
cursor, data_pairs = @redis.hscan("deprecations:data", cursor) # NB: some pages may be empty
|
211
217
|
total += data_pairs.size
|
212
218
|
removed += delete_deprecations(
|
213
|
-
data_pairs.select { |_digest, data| !block_given? || yield(JSON.parse(data, symbolize_names: true)) }.keys
|
219
|
+
data_pairs.to_h.select { |_digest, data| !block_given? || yield(JSON.parse(data, symbolize_names: true)) }.keys
|
214
220
|
)
|
215
221
|
break if cursor == "0"
|
216
222
|
end
|
@@ -221,18 +227,22 @@ class DeprecationCollector
|
|
221
227
|
|
222
228
|
def store_deprecation(deprecation)
|
223
229
|
return if deprecation.ignored?
|
230
|
+
fresh = !@deprecations.key?(deprecation.digest)
|
224
231
|
|
225
232
|
@deprecations_mutex.synchronize do
|
226
233
|
(@deprecations[deprecation.digest] ||= deprecation).touch
|
227
234
|
end
|
228
235
|
|
229
236
|
write_to_redis if current_time - @last_write_time > (@write_interval + rand(@write_interval_jitter))
|
237
|
+
fresh
|
230
238
|
end
|
231
239
|
|
232
|
-
def log_deprecation_if_needed(deprecation)
|
233
|
-
return unless
|
234
|
-
|
235
|
-
|
240
|
+
def log_deprecation_if_needed(deprecation, fresh)
|
241
|
+
return unless print_to_stderr && !deprecation.ignored?
|
242
|
+
return unless fresh || print_recurring
|
243
|
+
msg = deprecation.message
|
244
|
+
msg = "DEPRECATION: #{msg}" unless msg.start_with?('DEPRECAT')
|
245
|
+
$stderr.puts(msg) # rubocop:disable Style/StderrPuts
|
236
246
|
end
|
237
247
|
|
238
248
|
def current_time
|
@@ -242,7 +252,12 @@ class DeprecationCollector
|
|
242
252
|
end
|
243
253
|
|
244
254
|
def decode_deprecation(digest, data, count, notes)
|
255
|
+
return nil unless data
|
245
256
|
data = JSON.parse(data, symbolize_names: true)
|
257
|
+
unless data.is_a?(Hash)
|
258
|
+
binding.irb
|
259
|
+
return nil
|
260
|
+
end
|
246
261
|
data[:digest] = digest
|
247
262
|
data[:notes] = JSON.parse(notes, symbolize_names: true) if notes
|
248
263
|
data[:count] = count.to_i if count
|
@@ -250,9 +265,9 @@ class DeprecationCollector
|
|
250
265
|
end
|
251
266
|
|
252
267
|
def write_count_to_redis(deprecations_to_flush)
|
253
|
-
@redis.pipelined do
|
268
|
+
@redis.pipelined do |pipe|
|
254
269
|
deprecations_to_flush.each_pair do |digest, deprecation|
|
255
|
-
|
270
|
+
pipe.hincrby("deprecations:counter", digest, deprecation.occurences)
|
256
271
|
end
|
257
272
|
end
|
258
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.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vasily Fedoseyev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '3.0'
|
27
27
|
description: Collects and aggregates warnings and deprecations. Optimized for production
|
28
28
|
environment.
|
29
29
|
email:
|
@@ -54,7 +54,7 @@ metadata:
|
|
54
54
|
homepage_uri: https://github.com/Vasfed/deprecation_collector
|
55
55
|
source_code_uri: https://github.com/Vasfed/deprecation_collector
|
56
56
|
changelog_uri: https://github.com/Vasfed/deprecation_collector/blob/main/CHANGELOG.md
|
57
|
-
post_install_message:
|
57
|
+
post_install_message:
|
58
58
|
rdoc_options: []
|
59
59
|
require_paths:
|
60
60
|
- lib
|
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
version: '0'
|
71
71
|
requirements: []
|
72
72
|
rubygems_version: 3.1.6
|
73
|
-
signing_key:
|
73
|
+
signing_key:
|
74
74
|
specification_version: 4
|
75
75
|
summary: Collector for ruby/rails deprecations and warnings, suitable for production
|
76
76
|
test_files: []
|