activesupport 6.0.6.1 → 7.1.3.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.
Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +865 -438
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -6
  5. data/lib/active_support/actionable_error.rb +4 -2
  6. data/lib/active_support/array_inquirer.rb +4 -2
  7. data/lib/active_support/backtrace_cleaner.rb +30 -10
  8. data/lib/active_support/benchmarkable.rb +4 -3
  9. data/lib/active_support/broadcast_logger.rb +250 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +53 -20
  14. data/lib/active_support/cache/mem_cache_store.rb +208 -63
  15. data/lib/active_support/cache/memory_store.rb +120 -38
  16. data/lib/active_support/cache/null_store.rb +16 -2
  17. data/lib/active_support/cache/redis_cache_store.rb +201 -208
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +73 -66
  20. data/lib/active_support/cache.rb +539 -261
  21. data/lib/active_support/callbacks.rb +273 -142
  22. data/lib/active_support/code_generator.rb +65 -0
  23. data/lib/active_support/concern.rb +53 -7
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/concurrency/share_lock.rb +2 -2
  27. data/lib/active_support/configurable.rb +19 -6
  28. data/lib/active_support/configuration_file.rb +51 -0
  29. data/lib/active_support/core_ext/array/access.rb +1 -5
  30. data/lib/active_support/core_ext/array/conversions.rb +15 -13
  31. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  33. data/lib/active_support/core_ext/benchmark.rb +2 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  35. data/lib/active_support/core_ext/class/attribute.rb +34 -44
  36. data/lib/active_support/core_ext/class/subclasses.rb +19 -29
  37. data/lib/active_support/core_ext/date/blank.rb +1 -1
  38. data/lib/active_support/core_ext/date/calculations.rb +24 -9
  39. data/lib/active_support/core_ext/date/conversions.rb +18 -16
  40. data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -4
  41. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  42. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  43. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  44. data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
  45. data/lib/active_support/core_ext/digest/uuid.rb +30 -13
  46. data/lib/active_support/core_ext/enumerable.rb +146 -72
  47. data/lib/active_support/core_ext/erb/util.rb +196 -0
  48. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  49. data/lib/active_support/core_ext/hash/conversions.rb +3 -4
  50. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  51. data/lib/active_support/core_ext/hash/deep_transform_values.rb +4 -4
  52. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  53. data/lib/active_support/core_ext/hash/keys.rb +5 -5
  54. data/lib/active_support/core_ext/hash/slice.rb +3 -2
  55. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  56. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  58. data/lib/active_support/core_ext/load_error.rb +1 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +31 -29
  61. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +51 -20
  62. data/lib/active_support/core_ext/module/concerning.rb +14 -8
  63. data/lib/active_support/core_ext/module/delegation.rb +75 -42
  64. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  65. data/lib/active_support/core_ext/module/introspection.rb +1 -26
  66. data/lib/active_support/core_ext/name_error.rb +23 -2
  67. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  68. data/lib/active_support/core_ext/numeric/conversions.rb +82 -73
  69. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  70. data/lib/active_support/core_ext/object/blank.rb +2 -2
  71. data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
  72. data/lib/active_support/core_ext/object/duplicable.rb +15 -4
  73. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  74. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  75. data/lib/active_support/core_ext/object/json.rb +52 -28
  76. data/lib/active_support/core_ext/object/to_query.rb +2 -4
  77. data/lib/active_support/core_ext/object/try.rb +20 -20
  78. data/lib/active_support/core_ext/object/with.rb +44 -0
  79. data/lib/active_support/core_ext/object/with_options.rb +25 -6
  80. data/lib/active_support/core_ext/object.rb +1 -0
  81. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  82. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  83. data/lib/active_support/core_ext/pathname.rb +4 -0
  84. data/lib/active_support/core_ext/range/compare_range.rb +6 -25
  85. data/lib/active_support/core_ext/range/conversions.rb +34 -13
  86. data/lib/active_support/core_ext/range/each.rb +1 -1
  87. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  88. data/lib/active_support/core_ext/range.rb +1 -2
  89. data/lib/active_support/core_ext/regexp.rb +8 -1
  90. data/lib/active_support/core_ext/securerandom.rb +25 -13
  91. data/lib/active_support/core_ext/string/access.rb +5 -24
  92. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  93. data/lib/active_support/core_ext/string/filters.rb +21 -15
  94. data/lib/active_support/core_ext/string/indent.rb +1 -1
  95. data/lib/active_support/core_ext/string/inflections.rb +51 -10
  96. data/lib/active_support/core_ext/string/inquiry.rb +2 -1
  97. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  98. data/lib/active_support/core_ext/string/output_safety.rb +85 -194
  99. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  100. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  101. data/lib/active_support/core_ext/symbol.rb +3 -0
  102. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  103. data/lib/active_support/core_ext/time/calculations.rb +46 -8
  104. data/lib/active_support/core_ext/time/conversions.rb +16 -13
  105. data/lib/active_support/core_ext/time/zones.rb +12 -28
  106. data/lib/active_support/core_ext.rb +2 -1
  107. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  108. data/lib/active_support/current_attributes.rb +54 -22
  109. data/lib/active_support/deep_mergeable.rb +53 -0
  110. data/lib/active_support/dependencies/autoload.rb +17 -12
  111. data/lib/active_support/dependencies/interlock.rb +10 -18
  112. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  113. data/lib/active_support/dependencies.rb +58 -769
  114. data/lib/active_support/deprecation/behaviors.rb +77 -38
  115. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  116. data/lib/active_support/deprecation/deprecators.rb +104 -0
  117. data/lib/active_support/deprecation/disallowed.rb +54 -0
  118. data/lib/active_support/deprecation/instance_delegator.rb +31 -5
  119. data/lib/active_support/deprecation/method_wrappers.rb +12 -28
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +40 -25
  121. data/lib/active_support/deprecation/reporting.rb +76 -16
  122. data/lib/active_support/deprecation.rb +36 -4
  123. data/lib/active_support/deprecator.rb +7 -0
  124. data/lib/active_support/descendants_tracker.rb +150 -68
  125. data/lib/active_support/digest.rb +5 -3
  126. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  127. data/lib/active_support/duration/iso8601_serializer.rb +24 -12
  128. data/lib/active_support/duration.rb +136 -56
  129. data/lib/active_support/encrypted_configuration.rb +72 -9
  130. data/lib/active_support/encrypted_file.rb +46 -13
  131. data/lib/active_support/environment_inquirer.rb +40 -0
  132. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  133. data/lib/active_support/error_reporter.rb +203 -0
  134. data/lib/active_support/evented_file_update_checker.rb +86 -137
  135. data/lib/active_support/execution_context/test_helper.rb +13 -0
  136. data/lib/active_support/execution_context.rb +53 -0
  137. data/lib/active_support/execution_wrapper.rb +31 -12
  138. data/lib/active_support/executor/test_helper.rb +7 -0
  139. data/lib/active_support/file_update_checker.rb +4 -2
  140. data/lib/active_support/fork_tracker.rb +79 -0
  141. data/lib/active_support/gem_version.rb +5 -5
  142. data/lib/active_support/gzip.rb +2 -0
  143. data/lib/active_support/hash_with_indifferent_access.rb +86 -42
  144. data/lib/active_support/html_safe_translation.rb +53 -0
  145. data/lib/active_support/i18n.rb +2 -1
  146. data/lib/active_support/i18n_railtie.rb +29 -27
  147. data/lib/active_support/inflector/inflections.rb +26 -9
  148. data/lib/active_support/inflector/methods.rb +54 -64
  149. data/lib/active_support/inflector/transliterate.rb +7 -5
  150. data/lib/active_support/isolated_execution_state.rb +76 -0
  151. data/lib/active_support/json/decoding.rb +6 -5
  152. data/lib/active_support/json/encoding.rb +31 -45
  153. data/lib/active_support/key_generator.rb +32 -7
  154. data/lib/active_support/lazy_load_hooks.rb +33 -7
  155. data/lib/active_support/locale/en.yml +10 -4
  156. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  157. data/lib/active_support/log_subscriber.rb +101 -32
  158. data/lib/active_support/logger.rb +9 -60
  159. data/lib/active_support/logger_silence.rb +2 -26
  160. data/lib/active_support/logger_thread_safe_level.rb +24 -25
  161. data/lib/active_support/message_encryptor.rb +205 -58
  162. data/lib/active_support/message_encryptors.rb +141 -0
  163. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  164. data/lib/active_support/message_pack/extensions.rb +292 -0
  165. data/lib/active_support/message_pack/serializer.rb +63 -0
  166. data/lib/active_support/message_pack.rb +50 -0
  167. data/lib/active_support/message_verifier.rb +237 -86
  168. data/lib/active_support/message_verifiers.rb +135 -0
  169. data/lib/active_support/messages/codec.rb +65 -0
  170. data/lib/active_support/messages/metadata.rb +112 -46
  171. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  172. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  173. data/lib/active_support/messages/rotator.rb +35 -32
  174. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  175. data/lib/active_support/multibyte/chars.rb +15 -52
  176. data/lib/active_support/multibyte/unicode.rb +8 -122
  177. data/lib/active_support/multibyte.rb +1 -1
  178. data/lib/active_support/notifications/fanout.rb +310 -105
  179. data/lib/active_support/notifications/instrumenter.rb +113 -48
  180. data/lib/active_support/notifications.rb +56 -29
  181. data/lib/active_support/number_helper/number_converter.rb +15 -8
  182. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  183. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  184. data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
  185. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -5
  186. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  187. data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
  188. data/lib/active_support/number_helper/rounding_helper.rb +12 -32
  189. data/lib/active_support/number_helper.rb +379 -304
  190. data/lib/active_support/option_merger.rb +11 -18
  191. data/lib/active_support/ordered_hash.rb +4 -4
  192. data/lib/active_support/ordered_options.rb +23 -3
  193. data/lib/active_support/parameter_filter.rb +104 -75
  194. data/lib/active_support/proxy_object.rb +2 -0
  195. data/lib/active_support/rails.rb +1 -4
  196. data/lib/active_support/railtie.rb +90 -6
  197. data/lib/active_support/reloader.rb +12 -4
  198. data/lib/active_support/rescuable.rb +18 -16
  199. data/lib/active_support/ruby_features.rb +7 -0
  200. data/lib/active_support/secure_compare_rotator.rb +58 -0
  201. data/lib/active_support/security_utils.rb +19 -12
  202. data/lib/active_support/string_inquirer.rb +5 -3
  203. data/lib/active_support/subscriber.rb +23 -47
  204. data/lib/active_support/syntax_error_proxy.rb +70 -0
  205. data/lib/active_support/tagged_logging.rb +84 -23
  206. data/lib/active_support/test_case.rb +166 -27
  207. data/lib/active_support/testing/assertions.rb +73 -20
  208. data/lib/active_support/testing/autorun.rb +0 -2
  209. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  210. data/lib/active_support/testing/deprecation.rb +53 -2
  211. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  212. data/lib/active_support/testing/isolation.rb +30 -29
  213. data/lib/active_support/testing/method_call_assertions.rb +24 -11
  214. data/lib/active_support/testing/parallelization/server.rb +82 -0
  215. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  216. data/lib/active_support/testing/parallelization.rb +16 -95
  217. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  218. data/lib/active_support/testing/stream.rb +4 -6
  219. data/lib/active_support/testing/strict_warnings.rb +39 -0
  220. data/lib/active_support/testing/tagged_logging.rb +1 -1
  221. data/lib/active_support/testing/time_helpers.rb +89 -19
  222. data/lib/active_support/time_with_zone.rb +105 -70
  223. data/lib/active_support/values/time_zone.rb +59 -26
  224. data/lib/active_support/version.rb +1 -1
  225. data/lib/active_support/xml_mini/jdom.rb +4 -11
  226. data/lib/active_support/xml_mini/libxml.rb +5 -5
  227. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  228. data/lib/active_support/xml_mini/nokogiri.rb +5 -5
  229. data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
  230. data/lib/active_support/xml_mini/rexml.rb +9 -2
  231. data/lib/active_support/xml_mini.rb +7 -6
  232. data/lib/active_support.rb +40 -1
  233. metadata +127 -40
  234. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
  235. data/lib/active_support/core_ext/hash/compact.rb +0 -5
  236. data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
  237. data/lib/active_support/core_ext/marshal.rb +0 -24
  238. data/lib/active_support/core_ext/module/reachable.rb +0 -6
  239. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
  240. data/lib/active_support/core_ext/range/include_range.rb +0 -9
  241. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -23
  242. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  243. data/lib/active_support/core_ext/uri.rb +0 -25
  244. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
  245. data/lib/active_support/per_thread_registry.rb +0 -60
@@ -44,22 +44,26 @@ en:
44
44
  delimiter: ","
45
45
  # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
46
46
  precision: 3
47
+ # Determine how rounding is performed (see BigDecimal::mode)
48
+ round_mode: default
47
49
  # If set to true, precision will mean the number of significant digits instead
48
50
  # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
49
51
  significant: false
50
- # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
52
+ # If set, the zeros after the decimal separator will always be stripped (e.g.: 1.200 will be 1.2)
51
53
  strip_insignificant_zeros: false
52
54
 
53
55
  # Used in NumberHelper.number_to_currency()
54
56
  currency:
55
57
  format:
56
- # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
58
+ # Where is the currency sign? %u is the currency unit, %n is the number (default: $5.00)
57
59
  format: "%u%n"
60
+ negative_format: "-%u%n"
58
61
  unit: "$"
59
- # These five are to override number.format and are optional
62
+ # These six are to override number.format and are optional
60
63
  separator: "."
61
64
  delimiter: ","
62
65
  precision: 2
66
+ # round_mode:
63
67
  significant: false
64
68
  strip_insignificant_zeros: false
65
69
 
@@ -87,10 +91,11 @@ en:
87
91
  # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human()
88
92
  human:
89
93
  format:
90
- # These five are to override number.format and are optional
94
+ # These six are to override number.format and are optional
91
95
  # separator:
92
96
  delimiter: ""
93
97
  precision: 3
98
+ # round_mode:
94
99
  significant: true
95
100
  strip_insignificant_zeros: true
96
101
  # Used in number_to_human_size()
@@ -108,6 +113,7 @@ en:
108
113
  tb: "TB"
109
114
  pb: "PB"
110
115
  eb: "EB"
116
+ zb: "ZB"
111
117
  # Used in NumberHelper.number_to_human()
112
118
  decimal_units:
113
119
  format: "%n %u"
@@ -27,13 +27,13 @@ module ActiveSupport
27
27
  #
28
28
  # All you need to do is to ensure that your log subscriber is added to
29
29
  # Rails::Subscriber, as in the second line of the code above. The test
30
- # helpers are responsible for setting up the queue, subscriptions and
30
+ # helpers are responsible for setting up the queue and subscriptions, and
31
31
  # turning colors in logs off.
32
32
  #
33
33
  # The messages are available in the @logger instance, which is a logger with
34
34
  # limited powers (it actually does not send anything to your output), and
35
35
  # you can collect them doing @logger.logged(level), where level is the level
36
- # used in logging, like info, debug, warn and so on.
36
+ # used in logging, like info, debug, warn, and so on.
37
37
  module TestHelper
38
38
  def setup # :nodoc:
39
39
  @logger = MockLogger.new
@@ -3,10 +3,13 @@
3
3
  require "active_support/core_ext/module/attribute_accessors"
4
4
  require "active_support/core_ext/class/attribute"
5
5
  require "active_support/subscriber"
6
+ require "active_support/deprecation/proxy_wrappers"
6
7
 
7
8
  module ActiveSupport
8
- # <tt>ActiveSupport::LogSubscriber</tt> is an object set to consume
9
- # <tt>ActiveSupport::Notifications</tt> with the sole purpose of logging them.
9
+ # = Active Support Log \Subscriber
10
+ #
11
+ # +ActiveSupport::LogSubscriber+ is an object set to consume
12
+ # ActiveSupport::Notifications with the sole purpose of logging them.
10
13
  # The log subscriber dispatches notifications to a registered object based
11
14
  # on its given namespace.
12
15
  #
@@ -15,26 +18,23 @@ module ActiveSupport
15
18
  #
16
19
  # module ActiveRecord
17
20
  # class LogSubscriber < ActiveSupport::LogSubscriber
21
+ # attach_to :active_record
22
+ #
18
23
  # def sql(event)
19
24
  # info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
20
25
  # end
21
26
  # end
22
27
  # end
23
28
  #
24
- # And it's finally registered as:
25
- #
26
- # ActiveRecord::LogSubscriber.attach_to :active_record
29
+ # ActiveRecord::LogSubscriber.logger must be set as well, but it is assigned
30
+ # automatically in a \Rails environment.
27
31
  #
28
- # Since we need to know all instance methods before attaching the log
29
- # subscriber, the line above should be called after your
30
- # <tt>ActiveRecord::LogSubscriber</tt> definition.
32
+ # After configured, whenever a <tt>"sql.active_record"</tt> notification is
33
+ # published, it will properly dispatch the event
34
+ # (ActiveSupport::Notifications::Event) to the +sql+ method.
31
35
  #
32
- # After configured, whenever a <tt>"sql.active_record"</tt> notification is published,
33
- # it will properly dispatch the event
34
- # (<tt>ActiveSupport::Notifications::Event</tt>) to the sql method.
35
- #
36
- # Being an <tt>ActiveSupport::Notifications</tt> consumer,
37
- # <tt>ActiveSupport::LogSubscriber</tt> exposes a simple interface to check if
36
+ # Being an ActiveSupport::Notifications consumer,
37
+ # +ActiveSupport::LogSubscriber+ exposes a simple interface to check if
38
38
  # instrumented code raises an exception. It is common to log a different
39
39
  # message in case of an error, and this can be achieved by extending
40
40
  # the previous example:
@@ -56,15 +56,24 @@ module ActiveSupport
56
56
  # end
57
57
  # end
58
58
  #
59
- # Log subscriber also has some helpers to deal with logging and automatically
60
- # flushes all logs when the request finishes
61
- # (via <tt>action_dispatch.callback</tt> notification) in a Rails environment.
59
+ # +ActiveSupport::LogSubscriber+ also has some helpers to deal with
60
+ # logging. For example, ActiveSupport::LogSubscriber.flush_all! will ensure
61
+ # that all logs are flushed, and it is called in Rails::Rack::Logger after a
62
+ # request finishes.
62
63
  class LogSubscriber < Subscriber
63
64
  # Embed in a String to clear all previous ANSI sequences.
64
- CLEAR = "\e[0m"
65
- BOLD = "\e[1m"
65
+ CLEAR = ActiveSupport::Deprecation::DeprecatedObjectProxy.new("\e[0m", "CLEAR is deprecated! Use MODES[:clear] instead.", ActiveSupport.deprecator)
66
+ BOLD = ActiveSupport::Deprecation::DeprecatedObjectProxy.new("\e[1m", "BOLD is deprecated! Use MODES[:bold] instead.", ActiveSupport.deprecator)
67
+
68
+ # ANSI sequence modes
69
+ MODES = {
70
+ clear: 0,
71
+ bold: 1,
72
+ italic: 3,
73
+ underline: 4,
74
+ }
66
75
 
67
- # Colors
76
+ # ANSI sequence colors
68
77
  BLACK = "\e[30m"
69
78
  RED = "\e[31m"
70
79
  GREEN = "\e[32m"
@@ -75,6 +84,13 @@ module ActiveSupport
75
84
  WHITE = "\e[37m"
76
85
 
77
86
  mattr_accessor :colorize_logging, default: true
87
+ class_attribute :log_levels, instance_accessor: false, default: {} # :nodoc:
88
+
89
+ LEVEL_CHECKS = {
90
+ debug: -> (logger) { !logger.debug? },
91
+ info: -> (logger) { !logger.info? },
92
+ error: -> (logger) { !logger.error? },
93
+ }
78
94
 
79
95
  class << self
80
96
  def logger
@@ -83,6 +99,12 @@ module ActiveSupport
83
99
  end
84
100
  end
85
101
 
102
+ def attach_to(...) # :nodoc:
103
+ result = super
104
+ set_event_levels
105
+ result
106
+ end
107
+
86
108
  attr_writer :logger
87
109
 
88
110
  def log_subscribers
@@ -93,24 +115,51 @@ module ActiveSupport
93
115
  def flush_all!
94
116
  logger.flush if logger.respond_to?(:flush)
95
117
  end
118
+
119
+ private
120
+ def fetch_public_methods(subscriber, inherit_all)
121
+ subscriber.public_methods(inherit_all) - LogSubscriber.public_instance_methods(true)
122
+ end
123
+
124
+ def set_event_levels
125
+ if subscriber
126
+ subscriber.event_levels = log_levels.transform_keys { |k| "#{k}.#{namespace}" }
127
+ end
128
+ end
129
+
130
+ def subscribe_log_level(method, level)
131
+ self.log_levels = log_levels.merge(method => LEVEL_CHECKS.fetch(level))
132
+ set_event_levels
133
+ end
134
+ end
135
+
136
+ def initialize
137
+ super
138
+ @event_levels = {}
96
139
  end
97
140
 
98
141
  def logger
99
142
  LogSubscriber.logger
100
143
  end
101
144
 
102
- def start(name, id, payload)
145
+ def silenced?(event)
146
+ logger.nil? || @event_levels[event]&.call(logger)
147
+ end
148
+
149
+ def call(event)
103
150
  super if logger
151
+ rescue => e
152
+ log_exception(event.name, e)
104
153
  end
105
154
 
106
- def finish(name, id, payload)
155
+ def publish_event(event)
107
156
  super if logger
108
157
  rescue => e
109
- if logger
110
- logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
111
- end
158
+ log_exception(event.name, e)
112
159
  end
113
160
 
161
+ attr_writer :event_levels # :nodoc:
162
+
114
163
  private
115
164
  %w(info debug warn error fatal unknown).each do |level|
116
165
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
@@ -120,15 +169,35 @@ module ActiveSupport
120
169
  METHOD
121
170
  end
122
171
 
123
- # Set color by using a symbol or one of the defined constants. If a third
124
- # option is set to +true+, it also adds bold to the string. This is based
125
- # on the Highline implementation and will automatically append CLEAR to the
126
- # end of the returned String.
127
- def color(text, color, bold = false) # :doc:
172
+ # Set color by using a symbol or one of the defined constants. Set modes
173
+ # by specifying bold, italic, or underline options. Inspired by Highline,
174
+ # this method will automatically clear formatting at the end of the returned String.
175
+ def color(text, color, mode_options = {}) # :doc:
128
176
  return text unless colorize_logging
129
177
  color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
130
- bold = bold ? BOLD : ""
131
- "#{bold}#{color}#{text}#{CLEAR}"
178
+ mode = mode_from(mode_options)
179
+ clear = "\e[#{MODES[:clear]}m"
180
+ "#{mode}#{color}#{text}#{clear}"
181
+ end
182
+
183
+ def mode_from(options)
184
+ if options.is_a?(TrueClass) || options.is_a?(FalseClass)
185
+ ActiveSupport.deprecator.warn(<<~MSG.squish)
186
+ Bolding log text with a positional boolean is deprecated and will be removed
187
+ in Rails 7.2. Use an option hash instead (eg. `color("my text", :red, bold: true)`).
188
+ MSG
189
+ options = { bold: options }
190
+ end
191
+
192
+ modes = MODES.values_at(*options.compact_blank.keys)
193
+
194
+ "\e[#{modes.join(";")}m" if modes.any?
195
+ end
196
+
197
+ def log_exception(name, e)
198
+ if logger
199
+ logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
200
+ end
132
201
  end
133
202
  end
134
203
  end
@@ -14,72 +14,21 @@ module ActiveSupport
14
14
  # ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT)
15
15
  # # => true
16
16
  def self.logger_outputs_to?(logger, *sources)
17
- logdev = logger.instance_variable_get("@logdev")
18
- logger_source = logdev.dev if logdev.respond_to?(:dev)
19
- sources.any? { |source| source == logger_source }
20
- end
21
-
22
- # Broadcasts logs to multiple loggers.
23
- def self.broadcast(logger) # :nodoc:
24
- Module.new do
25
- define_method(:add) do |*args, &block|
26
- logger.add(*args, &block)
27
- super(*args, &block)
28
- end
29
-
30
- define_method(:<<) do |x|
31
- logger << x
32
- super(x)
33
- end
34
-
35
- define_method(:close) do
36
- logger.close
37
- super()
38
- end
39
-
40
- define_method(:progname=) do |name|
41
- logger.progname = name
42
- super(name)
43
- end
44
-
45
- define_method(:formatter=) do |formatter|
46
- logger.formatter = formatter
47
- super(formatter)
48
- end
49
-
50
- define_method(:level=) do |level|
51
- logger.level = level
52
- super(level)
53
- end
17
+ loggers = if logger.is_a?(BroadcastLogger)
18
+ logger.broadcasts
19
+ else
20
+ [logger]
21
+ end
54
22
 
55
- define_method(:local_level=) do |level|
56
- logger.local_level = level if logger.respond_to?(:local_level=)
57
- super(level) if respond_to?(:local_level=)
58
- end
23
+ logdevs = loggers.map { |logger| logger.instance_variable_get(:@logdev) }
24
+ logger_sources = logdevs.filter_map { |logdev| logdev.dev if logdev.respond_to?(:dev) }
59
25
 
60
- define_method(:silence) do |level = Logger::ERROR, &block|
61
- if logger.respond_to?(:silence)
62
- logger.silence(level) do
63
- if defined?(super)
64
- super(level, &block)
65
- else
66
- block.call(self)
67
- end
68
- end
69
- else
70
- if defined?(super)
71
- super(level, &block)
72
- else
73
- block.call(self)
74
- end
75
- end
76
- end
77
- end
26
+ (sources & logger_sources).any?
78
27
  end
79
28
 
80
29
  def initialize(*args, **kwargs)
81
30
  super
82
- @formatter = SimpleFormatter.new
31
+ @formatter ||= SimpleFormatter.new
83
32
  end
84
33
 
85
34
  # Simple formatter which only displays the message.
@@ -4,19 +4,6 @@ require "active_support/concern"
4
4
  require "active_support/core_ext/module/attribute_accessors"
5
5
  require "active_support/logger_thread_safe_level"
6
6
 
7
- module LoggerSilence
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- ActiveSupport::Deprecation.warn(
12
- "Including LoggerSilence is deprecated and will be removed in Rails 6.1. " \
13
- "Please use `ActiveSupport::LoggerSilence` instead"
14
- )
15
-
16
- include ActiveSupport::LoggerSilence
17
- end
18
- end
19
-
20
7
  module ActiveSupport
21
8
  module LoggerSilence
22
9
  extend ActiveSupport::Concern
@@ -27,19 +14,8 @@ module ActiveSupport
27
14
  end
28
15
 
29
16
  # Silences the logger for the duration of the block.
30
- def silence(temporary_level = Logger::ERROR)
31
- if silencer
32
- begin
33
- old_local_level = local_level
34
- self.local_level = temporary_level
35
-
36
- yield self
37
- ensure
38
- self.local_level = old_local_level
39
- end
40
- else
41
- yield self
42
- end
17
+ def silence(severity = Logger::ERROR)
18
+ silencer ? log_at(severity) { yield self } : yield(self)
43
19
  end
44
20
  end
45
21
  end
@@ -1,18 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/concern"
4
- require "active_support/core_ext/module/attribute_accessors"
5
- require "concurrent"
6
- require "fiber"
4
+ require "logger"
7
5
 
8
6
  module ActiveSupport
9
7
  module LoggerThreadSafeLevel # :nodoc:
10
8
  extend ActiveSupport::Concern
11
9
 
12
- included do
13
- cattr_accessor :local_levels, default: Concurrent::Map.new(initial_capacity: 2), instance_accessor: false
14
- end
15
-
16
10
  Logger::Severity.constants.each do |severity|
17
11
  class_eval(<<-EOT, __FILE__, __LINE__ + 1)
18
12
  def #{severity.downcase}? # def debug?
@@ -21,26 +15,23 @@ module ActiveSupport
21
15
  EOT
22
16
  end
23
17
 
24
- def after_initialize
25
- ActiveSupport::Deprecation.warn(
26
- "Logger don't need to call #after_initialize directly anymore. It will be deprecated without replacement in " \
27
- "Rails 6.1."
28
- )
29
- end
30
-
31
- def local_log_id
32
- Fiber.current.__id__
33
- end
34
-
35
18
  def local_level
36
- self.class.local_levels[local_log_id]
19
+ IsolatedExecutionState[local_level_key]
37
20
  end
38
21
 
39
22
  def local_level=(level)
40
- if level
41
- self.class.local_levels[local_log_id] = level
23
+ case level
24
+ when Integer
25
+ when Symbol
26
+ level = Logger::Severity.const_get(level.to_s.upcase)
27
+ when nil
28
+ else
29
+ raise ArgumentError, "Invalid log level: #{level.inspect}"
30
+ end
31
+ if level.nil?
32
+ IsolatedExecutionState.delete(local_level_key)
42
33
  else
43
- self.class.local_levels.delete(local_log_id)
34
+ IsolatedExecutionState[local_level_key] = level
44
35
  end
45
36
  end
46
37
 
@@ -48,9 +39,17 @@ module ActiveSupport
48
39
  local_level || super
49
40
  end
50
41
 
51
- def add(severity, message = nil, progname = nil, &block) # :nodoc:
52
- return true if @logdev.nil? || (severity || UNKNOWN) < level
53
- super
42
+ # Change the thread-local level for the duration of the given block.
43
+ def log_at(level)
44
+ old_local_level, self.local_level = local_level, level
45
+ yield
46
+ ensure
47
+ self.local_level = old_local_level
54
48
  end
49
+
50
+ private
51
+ def local_level_key
52
+ @local_level_key ||= :"logger_thread_safe_level_#{object_id}"
53
+ end
55
54
  end
56
55
  end