debug_logging 3.1.1 → 3.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a39fc11d3fc815e37db037fd9ce8b08e74e5d98e7612a50f191231ba3ce95231
4
- data.tar.gz: 99ef91cf9302dfc413ebba74435464933524cfa1a2e70f9623b97ff64c849729
3
+ metadata.gz: 434bf02e4e2e51b0ae6ffb99e4d5174d212a2337744e1fd7697d66d804ccc062
4
+ data.tar.gz: efb30cc90b8d325da9511f6899378b790916ad671af4b69df1b6171aa9cda80e
5
5
  SHA512:
6
- metadata.gz: 22ec37827bdf34889a023d235315ee4ca85642cdc070a22751be328f58c8f4b8b22c952da52c2d6900f3bc44431d8d0dd5800483419532f3fd5a5aca9227d529
7
- data.tar.gz: 5b5456b83dfff252840e31ea81af17e5d3b50bdc025e090d55731fcd16353d41352b2304ba53818c791f9ec3970a447e4b01624fd269d6663951a444a876ac6d
6
+ metadata.gz: 99ec10ad80d3caca7a1092365774530b017a15276515f06b610dfd39e0e3e7f9883f59489d53ac2162b36e6c39371eb115b588524c8c9ed2cd4355b30a61bd89
7
+ data.tar.gz: 9af78b97aed63a43e63c27e998d9c713ece75825bcc91b6be704cf757a289c43b96a106d5ef5bff2783828dfac3bd4d48ae110fcfd3841fb556c88cb64bb9108
@@ -1,3 +1,11 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - 'rubocop-md'
5
+ - 'rubocop-performance'
6
+ - 'rubocop-rake'
7
+ - 'rubocop-rspec'
8
+
1
9
  AllCops:
2
10
  NewCops: enable
3
11
 
@@ -1,89 +1,134 @@
1
- inherit_from: .rubocop.yml
2
-
3
1
  # This configuration was generated by
4
2
  # `rubocop --auto-gen-config`
5
- # on 2020-10-06 07:34:51 UTC using RuboCop version 0.92.0.
3
+ # on 2020-12-10 04:35:55 UTC using RuboCop version 1.6.0.
6
4
  # The point is for the user to remove these configuration records
7
5
  # one by one as the offenses are removed from the code base.
8
6
  # Note that changes in the inspected code, or installation of new
9
7
  # versions of RuboCop, may require this file to be generated again.
10
8
 
11
- # Offense count: 1
12
- # Configuration parameters: Include.
13
- # Include: **/*.gemspec
14
- Gemspec/RequiredRubyVersion:
9
+ # Offense count: 7
10
+ Lint/DuplicateMethods:
15
11
  Exclude:
16
- - 'debug_logging.gemspec'
17
-
18
- # Offense count: 1
19
- # Cop supports --auto-correct.
20
- # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
21
- # SupportedStyles: space, no_space
22
- # SupportedStylesForEmptyBraces: space, no_space
23
- Layout/SpaceInsideBlockBraces:
24
- Exclude:
25
- - 'lib/debug_logging/argument_printer.rb'
12
+ - 'README.md'
26
13
 
27
- # Offense count: 5
28
- # Configuration parameters: IgnoredMethods.
14
+ # Offense count: 6
15
+ # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
29
16
  Metrics/AbcSize:
30
- Max: 97
17
+ Max: 96
31
18
 
32
- # Offense count: 38
33
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
34
- # ExcludedMethods: refine
19
+ # Offense count: 58
20
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
21
+ # IgnoredMethods: refine
35
22
  Metrics/BlockLength:
36
- Max: 810
23
+ Max: 851
37
24
 
38
25
  # Offense count: 6
39
26
  # Configuration parameters: CountBlocks.
40
27
  Metrics/BlockNesting:
41
28
  Max: 4
42
29
 
43
- # Offense count: 1
44
- # Configuration parameters: CountComments, CountAsOne.
45
- Metrics/ClassLength:
46
- Max: 101
47
-
48
30
  # Offense count: 4
49
31
  # Configuration parameters: IgnoredMethods.
50
32
  Metrics/CyclomaticComplexity:
51
- Max: 22
33
+ Max: 24
52
34
 
53
- # Offense count: 11
54
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
35
+ # Offense count: 15
36
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
55
37
  Metrics/MethodLength:
56
- Max: 50
38
+ Max: 75
57
39
 
58
- # Offense count: 1
40
+ # Offense count: 2
59
41
  # Configuration parameters: CountComments, CountAsOne.
60
42
  Metrics/ModuleLength:
61
43
  Max: 112
62
44
 
63
- # Offense count: 4
45
+ # Offense count: 5
64
46
  # Configuration parameters: IgnoredMethods.
65
47
  Metrics/PerceivedComplexity:
66
- Max: 26
48
+ Max: 31
67
49
 
68
- # Offense count: 1
69
- # Configuration parameters: AllowedChars.
70
- Style/AsciiComments:
50
+ # Offense count: 3
51
+ # Configuration parameters: EnforcedStyleForLeadingUnderscores.
52
+ # SupportedStylesForLeadingUnderscores: disallowed, required, optional
53
+ Naming/MemoizedInstanceVariableName:
71
54
  Exclude:
72
55
  - 'lib/debug_logging/configuration.rb'
73
56
 
57
+ # Offense count: 60
58
+ # Configuration parameters: Prefixes.
59
+ # Prefixes: when, with, without
60
+ RSpec/ContextWording:
61
+ Exclude:
62
+ - 'spec/debug_logging/class_logger_spec.rb'
63
+ - 'spec/debug_logging/class_notifier_spec.rb'
64
+ - 'spec/debug_logging/configuration_spec.rb'
65
+ - 'spec/debug_logging/instance_logger_spec.rb'
66
+ - 'spec/debug_logging/instance_notifier_spec.rb'
67
+ - 'spec/debug_logging_spec.rb'
68
+
69
+ # Offense count: 46
70
+ # Configuration parameters: Max.
71
+ RSpec/ExampleLength:
72
+ Exclude:
73
+ - 'spec/debug_logging/class_logger_spec.rb'
74
+ - 'spec/debug_logging/class_notifier_spec.rb'
75
+ - 'spec/debug_logging/configuration_spec.rb'
76
+ - 'spec/debug_logging/instance_logger_spec.rb'
77
+ - 'spec/debug_logging/instance_notifier_spec.rb'
78
+ - 'spec/debug_logging/log_subscriber_spec.rb'
79
+ - 'spec/debug_logging_spec.rb'
80
+
81
+ # Offense count: 53
82
+ # Configuration parameters: AssignmentOnly.
83
+ RSpec/InstanceVariable:
84
+ Exclude:
85
+ - 'spec/debug_logging/class_notifier_spec.rb'
86
+ - 'spec/debug_logging/instance_notifier_spec.rb'
87
+ - 'spec/debug_logging/log_subscriber_spec.rb'
88
+
89
+ # Offense count: 4
90
+ RSpec/LeakyConstantDeclaration:
91
+ Exclude:
92
+ - 'spec/debug_logging/configuration_spec.rb'
93
+
94
+ # Offense count: 23
95
+ # Configuration parameters: .
96
+ # SupportedStyles: have_received, receive
97
+ RSpec/MessageSpies:
98
+ EnforcedStyle: receive
99
+
100
+ # Offense count: 80
101
+ RSpec/MultipleExpectations:
102
+ Max: 32
103
+
74
104
  # Offense count: 1
75
- # Cop supports --auto-correct.
76
- # Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
77
- # SupportedStyles: assign_to_condition, assign_inside_condition
78
- Style/ConditionalAssignment:
105
+ # Configuration parameters: AllowSubject.
106
+ RSpec/MultipleMemoizedHelpers:
107
+ Max: 10
108
+
109
+ # Offense count: 27
110
+ RSpec/NestedGroups:
111
+ Max: 5
112
+
113
+ # Offense count: 1
114
+ # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
115
+ RSpec/VerifiedDoubles:
79
116
  Exclude:
80
- - 'lib/debug_logging/argument_printer.rb'
117
+ - 'spec/support/shared_context.rb'
118
+
119
+ # Offense count: 1
120
+ # Configuration parameters: AllowedChars.
121
+ Style/AsciiComments:
122
+ Exclude:
123
+ - '**/*.md'
124
+ - '**/*.markdown'
125
+ - 'lib/debug_logging/configuration.rb'
81
126
 
82
- # Offense count: 9
127
+ # Offense count: 13
83
128
  Style/Documentation:
84
129
  Exclude:
85
- - 'spec/**/*'
86
- - 'test/**/*'
130
+ - '**/*.md'
131
+ - '**/*.markdown'
87
132
  - 'lib/debug_logging.rb'
88
133
  - 'lib/debug_logging/argument_printer.rb'
89
134
  - 'lib/debug_logging/class_logger.rb'
@@ -96,7 +141,7 @@ Style/Documentation:
96
141
  - 'lib/debug_logging/log_subscriber.rb'
97
142
  - 'lib/simple_debug_logging.rb'
98
143
 
99
- # Offense count: 1
144
+ # Offense count: 2
100
145
  # Cop supports --auto-correct.
101
146
  # Configuration parameters: EnforcedStyle.
102
147
  # SupportedStyles: empty, nil, both
@@ -105,14 +150,7 @@ Style/EmptyElse:
105
150
  - 'lib/debug_logging/class_logger.rb'
106
151
  - 'lib/debug_logging/class_notifier.rb'
107
152
 
108
- # Offense count: 2
109
- # Configuration parameters: EnforcedStyle.
110
- # SupportedStyles: annotated, template, unannotated
111
- Style/FormatStringToken:
112
- Exclude:
113
- - 'lib/debug_logging/argument_printer.rb'
114
-
115
- # Offense count: 4
153
+ # Offense count: 8
116
154
  Style/IdenticalConditionalBranches:
117
155
  Exclude:
118
156
  - 'lib/debug_logging/class_logger.rb'
@@ -120,14 +158,10 @@ Style/IdenticalConditionalBranches:
120
158
  - 'lib/debug_logging/instance_logger_modulizer.rb'
121
159
  - 'lib/debug_logging/instance_notifier_modulizer.rb'
122
160
 
123
- # Offense count: 1
124
- Style/MultilineBlockChain:
125
- Exclude:
126
- - 'lib/debug_logging/argument_printer.rb'
127
-
128
- # Offense count: 95
161
+ # Offense count: 67
129
162
  # Cop supports --auto-correct.
130
163
  # Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
131
164
  # URISchemes: http, https
165
+ # IgnoredPatterns: (?-mix:^\#)
132
166
  Layout/LineLength:
133
- Max: 223
167
+ Max: 207
@@ -9,7 +9,7 @@ before_script:
9
9
  - ./cc-test-reporter before-build
10
10
 
11
11
  script:
12
- - bundle exec rubocop -DESP --config ./.rubocop_todo.yml
12
+ - bundle exec rubocop -DESP
13
13
  - bundle exec rspec
14
14
 
15
15
  after_script:
@@ -33,4 +33,4 @@ rvm:
33
33
  - ruby-2.4.10
34
34
  - ruby-2.5.8
35
35
  - ruby-2.6.6
36
- - ruby-2.7.1
36
+ - ruby-2.7.2
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # DebugLogging
2
2
 
3
3
  Unobtrusive, inheritable-overridable-configurable, drop-in debug logging, that won't leave a mess behind when it is time to remove it.
4
+ Supports ActiveSupport::Notifications (thanks [@jgillson](https://github.com/jgillson)). Optional ActiveRecord callback-style hooks that you can decorate your methods with. Hooks logic was taken from the [`slippy_method_hooks` gem](https://github.com/guckin/slippy_method_hooks), (thanks [@guckin](https://github.com/guckin)), and prefaced with `debug_` for this implementation. `DebugLogging::Finalize` is lightly modified from [this stackoverflow answer](https://stackoverflow.com/a/34559282).
4
5
 
5
6
  ## What do I mean by "unobtrusive"?
6
7
 
@@ -32,12 +33,16 @@ Unobtrusive, inheritable-overridable-configurable, drop-in debug logging, that w
32
33
  * *colorization by class/method*
33
34
  * *robust argument printer with customizable ellipsis*
34
35
  * *unique invocation identifiers*
35
- * *single line config, per class/instance/method config*
36
- * *separate logger, if needed*
36
+ * *simple single line global config, or per class/instance/method config*
37
+ * *separate loggers, if needed*
37
38
  * *log method calls, also when exit scope*
38
39
  * *Prevents heavy computation of strings with `logger.debug { 'log me' }` block format, since v1.0.12*
39
- * *ActiveSupport::Notifications integration for instrumenting/logging events on class and instance methods, since v3.1*
40
- * *Optional instance variable logging, sine v3.1*
40
+ * *ActiveSupport::Notifications integration for instrumenting/logging events on class and instance methods, since v3.1.3*
41
+ * *Optional instance, and class-instance, variable logging, since v3.1.3*
42
+ * *ActiveRecord style callback-hooks (optional: `require 'debug_logging/hooks'` and `include DebugLogging::Hooks`), since v3.1.3*
43
+ * *All configuration is inheritable to, and overridable by, child classes, since v3.1.3*
44
+ * *[Class finalization hook](https://stackoverflow.com/a/34559282) (optional: `require 'debug_logging/finalize'` and `extend DebugLogging::Finalize`), since v3.1.3*
45
+ * *Error handling hooks you can use to log problems when they happen, since v3.1.7*
41
46
  * **so many free ponies** 🎠🐴🎠🐴🎠🐴
42
47
 
43
48
  ## Next Level Magic
@@ -46,8 +51,10 @@ Herein you will find:
46
51
 
47
52
  * Classes inheriting from Module
48
53
  * Zero tolerance policy on monkey patching
54
+ * When the gem is loaded there are no monkey patches.
55
+ * Rather, your own classes/methods get "patched" and "hooked" as you configure them.
49
56
  * 100% clean, 0% obtrusive
50
- * 100% tested
57
+ * ~100% tested
51
58
  * 100% Ruby 2.1+ compatible
52
59
  - use version `gem "debug_logging", "~> 1.0"` for Ruby < 2.3
53
60
  - use version `gem "debug_logging", "~> 2.0"` for Ruby 2.3
@@ -86,11 +93,12 @@ Recommend creating `config/initializers/debug_logging.rb`, or adding to `config/
86
93
 
87
94
  ```ruby
88
95
  # Showing the defaults
89
- DebugLogging.configuration.logger = Logger.new(STDOUT) # you probably want to override to be the Rails.logger, and if so you can't set it in the initializer, as it needs to be set after Rails.logger is set.
96
+ DebugLogging.configuration.logger = Logger.new($stdout) # you probably want to override to be the Rails.logger, and if so you can't set it in the initializer, as it needs to be set after Rails.logger is set.
90
97
  DebugLogging.configuration.log_level = :debug # at what level do the messages created by this gem sent at?
91
98
  DebugLogging.configuration.multiple_last_hashes = false # pass every hash argument to last_hash_to_s_proc?
92
99
  DebugLogging.configuration.last_hash_to_s_proc = nil # e.g. ->(hash) { "keys: #{hash.keys}" }
93
100
  DebugLogging.configuration.last_hash_max_length = 1_000
101
+ DebugLogging.configuration.args_to_s_proc = nil # e.g. ->(record) { "record id: #{record.id}" }
94
102
  DebugLogging.configuration.args_max_length = 1_000
95
103
  DebugLogging.configuration.instance_benchmarks = false
96
104
  DebugLogging.configuration.class_benchmarks = false
@@ -98,19 +106,23 @@ DebugLogging.configuration.active_support_notifications = false
98
106
  DebugLogging.configuration.colorized_chain_for_method = false # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
99
107
  DebugLogging.configuration.colorized_chain_for_class = false # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
100
108
  DebugLogging.configuration.add_invocation_id = true # identify a method call uniquely in a log, pass a proc for colorization, e.g. ->(colorized_string) { colorized_string.light_black }
101
- DebugLogging.configuration.ellipsis = " ✂️ …".freeze
109
+ DebugLogging.configuration.ellipsis = ' ✂️ …'.freeze
102
110
  DebugLogging.configuration.mark_scope_exit = true # Only has an effect if benchmarking is off, since benchmarking always marks the scope exit
111
+ DebugLogging.configuration.add_payload = false # or a proc which will be called to print the payload
112
+ DebugLogging.configuration.payload_max_length = 1000
113
+ DebugLogging.configuration.error_handler_proc = nil # e.g. ->(error, config, obj) { config.log { "#{error.class}: #{error.message}\n#{obj.errors.inspect}" } }
103
114
  ```
104
115
 
105
116
  If you prefer to use the block style:
106
117
 
107
118
  ```ruby
108
119
  DebugLogging.configure do |config|
109
- config.logger = Logger.new(STDOUT) # probably want to override to be the Rails.logger, and if so you can't set it in the initializer, as it needs to be set after Rails.logger is set.
120
+ config.logger = Logger.new($stdout) # probably want to override to be the Rails.logger, and if so you can't set it in the initializer, as it needs to be set after Rails.logger is set.
110
121
  config.log_level = :debug # at what level do the messages created by this gem sent at?
111
122
  config.multiple_last_hashes = false # pass every hash argument to last_hash_to_s_proc?
112
123
  config.last_hash_to_s_proc = nil # e.g. ->(hash) { "keys: #{hash.keys}" }
113
124
  config.last_hash_max_length = 1_000
125
+ config.args_to_s_proc = nil # e.g. ->(record) { "record id: #{record.id}" }
114
126
  config.args_max_length = 1_000
115
127
  config.instance_benchmarks = false
116
128
  config.class_benchmarks = false
@@ -118,8 +130,11 @@ DebugLogging.configure do |config|
118
130
  config.colorized_chain_for_method = false # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
119
131
  config.colorized_chain_for_class = false # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
120
132
  config.add_invocation_id = true # identify a method call uniquely in a log, pass a proc for colorization, e.g. ->(colorized_string) { colorized_string.light_black }
121
- config.ellipsis = " ✂️ …".freeze
133
+ config.ellipsis = ' ✂️ …'.freeze
122
134
  config.mark_scope_exit = true # Only has an effect if benchmarking is off, since benchmarking always marks the scope exit
135
+ config.add_payload = false # or a proc which will be called to print the payload
136
+ config.payload_max_length = 1000
137
+ config.error_handler_proc = nil # e.g. ->(error, config, obj) { config.log { "#{error.class}: #{error.message}\n#{obj.errors.inspect}" } }
123
138
  end
124
139
  ```
125
140
 
@@ -160,10 +175,20 @@ class Car
160
175
  # == BEGIN CLASS METHODS ==
161
176
  # For class methods:
162
177
  # Option 1: Use *logged* as a method decorator
163
- logged def self.make; new; end
164
- def self.design(*args); new; end
165
- def self.safety(*args); new; end
166
- def self.dealer_options(*args); new; end
178
+ logged def self.make
179
+ new
180
+ end
181
+ def self.design(*_args)
182
+ new
183
+ end
184
+
185
+ def self.safety(*_args)
186
+ new
187
+ end
188
+
189
+ def self.dealer_options(*_args)
190
+ new
191
+ end
167
192
 
168
193
  # Option 2: Use *logged* as a macro
169
194
  logged :design, :safety
@@ -174,29 +199,40 @@ class Car
174
199
  something: 'here', # <= will be logged, and available to last_hash_to_s_proc
175
200
  multiple_last_hashes: true # <= Overrides config
176
201
  }
177
- def self.will_not_be_logged; false; end
202
+ def self.will_not_be_logged
203
+ false
204
+ end
178
205
  # == END CLASS METHODS ==
179
206
 
180
207
  # == BEGIN INSTANCE METHODS ==
181
208
  # For instance methods:
182
209
  # Option 1: specify the exact method(s) to add logging to
183
- include DebugLogging::InstanceLogger.new(i_methods: [:drive, :stop])
210
+ include DebugLogging::InstanceLogger.new(i_methods: %i[drive stop])
184
211
 
185
- def drive(speed); speed; end
186
- def stop(**opts); 0; end
212
+ def drive(speed)
213
+ speed
214
+ end
215
+
216
+ def stop(**_opts)
217
+ 0
218
+ end
187
219
 
188
220
  # For instance methods:
189
221
  # Option 2: add logging to all instance methods defined above (but *not* defined below)
190
- include DebugLogging::InstanceLogger.new(i_methods: self.instance_methods(false))
222
+ include DebugLogging::InstanceLogger.new(i_methods: instance_methods(false))
191
223
 
192
- def faster(**opts); 0; end
224
+ def faster(**_opts)
225
+ 0
226
+ end
193
227
 
194
228
  # Override configuration options for any instance method(s), by passing a hash as the last argument
195
229
  # In the last hash any non-Configuration keys will be data that gets logged,
196
230
  # and also made available to last_hash_to_s_proc
197
231
  include DebugLogging::InstanceLogger.new(i_methods: [:faster], config: { add_invocation_id: false })
198
232
 
199
- def will_not_be_logged; false; end
233
+ def will_not_be_logged
234
+ false
235
+ end
200
236
  # == END INSTANCE METHODS ==
201
237
  end
202
238
  ```
@@ -242,10 +278,20 @@ class Car
242
278
  # == BEGIN CLASS METHODS ==
243
279
  # For class methods:
244
280
  # Option 1: Use *notifies* as a method decorator
245
- notifies def self.make; new; end
246
- def self.design(*args); new; end
247
- def self.safety(*args); new; end
248
- def self.dealer_options(*args); new; end
281
+ notifies def self.make
282
+ new
283
+ end
284
+ def self.design(*_args)
285
+ new
286
+ end
287
+
288
+ def self.safety(*_args)
289
+ new
290
+ end
291
+
292
+ def self.dealer_options(*_args)
293
+ new
294
+ end
249
295
 
250
296
  # Option 2: Use *logged* as a macro
251
297
  notifies :design, :safety
@@ -256,25 +302,36 @@ class Car
256
302
  something: 'here', # <= will be added to the event payload, and be available to last_hash_to_s_proc
257
303
  add_invocation_id: false # <= Overrides config
258
304
  }
259
- def self.will_not_be_notified; false; end
305
+ def self.will_not_be_notified
306
+ false
307
+ end
260
308
  # == END CLASS METHODS ==
261
309
 
262
310
  # == BEGIN INSTANCE METHODS ==
263
- def drive(speed); speed; end
264
- def stop(**opts); 0; end
311
+ def drive(speed)
312
+ speed
313
+ end
314
+
315
+ def stop(**_opts)
316
+ 0
317
+ end
265
318
 
266
319
  # For instance methods:
267
320
  # Option 2: add instrumentation to all instance methods defined above (but *not* defined below)
268
- include DebugLogging::InstanceNotifier.new(i_methods: self.instance_methods(false))
321
+ include DebugLogging::InstanceNotifier.new(i_methods: instance_methods(false))
269
322
 
270
- def faster(**opts); 0; end
323
+ def faster(**_opts)
324
+ 0
325
+ end
271
326
 
272
327
  # Override options for any instance method(s), by passing a hash as the last argument
273
328
  # In the last hash any non-Configuration keys will be data that gets added to the event payload,
274
329
  # and also made available to last_hash_to_s_proc
275
330
  include DebugLogging::InstanceNotifier.new(i_methods: [:faster], config: { add_invocation_id: false })
276
331
 
277
- def will_not_be_notified; false; end
332
+ def will_not_be_notified
333
+ false
334
+ end
278
335
  # == END INSTANCE METHODS ==
279
336
  end
280
337
  ```
@@ -339,6 +396,10 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
339
396
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
340
397
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
341
398
 
399
+ ### License Exceptions
400
+
401
+ * [`debug_logging/finalize`](https://stackoverflow.com/a/34559282) is licensed under https://creativecommons.org/licenses/by-sa/4.0/
402
+
342
403
  [semver]: http://semver.org/
343
404
  [pvc]: http://docs.rubygems.org/read/chapter/16#page74
344
405
  [railsbling]: http://www.railsbling.com