debug_logging 4.0.0 → 4.0.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +56 -27
- data/CONTRIBUTING.md +1 -1
- data/README.md +39 -10
- data/SECURITY.md +2 -2
- data/lib/debug_logging/argument_printer.rb +26 -20
- data/lib/debug_logging/class_logger.rb +26 -56
- data/lib/debug_logging/class_notifier.rb +22 -38
- data/lib/debug_logging/configuration.rb +21 -12
- data/lib/debug_logging/constants.rb +11 -7
- data/lib/debug_logging/hooks.rb +7 -5
- data/lib/debug_logging/instance_logger.rb +30 -2
- data/lib/debug_logging/instance_logger_modulizer.rb +19 -45
- data/lib/debug_logging/instance_notifier.rb +6 -0
- data/lib/debug_logging/instance_notifier_modulizer.rb +15 -31
- data/lib/debug_logging/lamb_dart/base.rb +46 -0
- data/lib/debug_logging/lamb_dart/log.rb +47 -0
- data/lib/debug_logging/lamb_dart/note.rb +30 -0
- data/lib/debug_logging/lamb_dart.rb +9 -0
- data/lib/debug_logging/lamb_dartable.rb +41 -0
- data/lib/debug_logging/lamb_darts/benchmarked.rb +19 -0
- data/lib/debug_logging/lamb_darts/enter_log.rb +16 -0
- data/lib/debug_logging/lamb_darts/error_handle.rb +28 -0
- data/lib/debug_logging/lamb_darts/exit_log.rb +15 -0
- data/lib/debug_logging/lamb_darts/notify.rb +17 -0
- data/lib/debug_logging/log_subscriber.rb +2 -2
- data/lib/debug_logging/util.rb +39 -19
- data/lib/debug_logging/version.rb +1 -1
- data/lib/debug_logging.rb +18 -7
- data/lib/simple_debug_logging.rb +18 -16
- data.tar.gz.sig +0 -0
- metadata +62 -12
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5059baba71c02b6f460a6cc3badf9871441b16e926afe59636ad7ef2f8b907c
|
4
|
+
data.tar.gz: 9ac589b2e46cd7f439f45751c50404e09bf07f0cc2b5e9713b93d83338e2f5e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed2fdd91670149c07f1ef0c118fda035b858b63cbe87d7d09000c18ab14f4133bf37a340ad11ec0c851be4bd2f1e2b807444a21b3bb002cdbaa6f8b9ddb6b17e
|
7
|
+
data.tar.gz: 41bedf5260a5e667d0dc6570987f26c05a66651638623e2cfddbaf132782e50067693d1f1bc9660808146456a06ab5e4c8f497de5555783e6aa073c5cabb811e
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -11,7 +11,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
11
11
|
### Fixed
|
12
12
|
### Removed
|
13
13
|
|
14
|
-
## [4.0.0] -
|
14
|
+
## [4.0.2] ([tag][4.0.2t]) - 2024-05-12
|
15
|
+
### Added
|
16
|
+
- More documentation
|
17
|
+
### Changed
|
18
|
+
- DRY logic for `DebugLogging::ClassLogger` & `DebugLogging::InstanceLogger` via `LambDart`
|
19
|
+
- Refactored test suite; increased test coverage to 97%
|
20
|
+
- Refactored ActiveSupport::Notification integration (DRY)
|
21
|
+
### Fixed
|
22
|
+
- Add undeclared runtime dependency `version_gem`
|
23
|
+
- `DebugLogging::Hooks` integration via `extend`
|
24
|
+
- `DebugLogging::ClassNotifier` support for method signatures with kwargs
|
25
|
+
- `error_handler_proc` support for method signatures with kwargs
|
26
|
+
|
27
|
+
## [4.0.1] ([tag][4.0.1t]) - 2024-03-01
|
28
|
+
### Added
|
29
|
+
- Support for all Numeric types to be used as monotonic timestamps for ActiveSupport::Notifications
|
30
|
+
- `time_formatter_proc` - used to format timestamp added to beginning of log lines
|
31
|
+
- `add_timestamp` - Add timestamp to front of each log line
|
32
|
+
### Changed
|
33
|
+
- `DebugLogging::ArgumentPrinter.debug_time_to_s` => `DebugLogging::ArgumentPrinter.debug_event_time_to_s`
|
34
|
+
### Fixed
|
35
|
+
### Removed
|
36
|
+
|
37
|
+
## [4.0.0] ([tag][4.0.0t]) - 2024-02-28
|
15
38
|
### Added
|
16
39
|
- Class method DSL:
|
17
40
|
- `logged`
|
@@ -30,57 +53,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
30
53
|
- Support for `include DebugLogging::InstanceLogger.new(...)`
|
31
54
|
- Support for `include DebugLogging::InstanceNotifier.new(...)`
|
32
55
|
|
33
|
-
## [3.1.9] - 2023-10-31
|
56
|
+
## [3.1.9] ([tag][3.1.9t]) - 2023-10-31
|
34
57
|
### Fixed
|
35
58
|
- Maximum Ruby version is 2.7. Versions 3.x are not compatible with Ruby >= 3
|
36
59
|
|
37
|
-
## [3.1.8] - 2020-12-19
|
60
|
+
## [3.1.8] ([tag][3.1.8t]) - 2020-12-19
|
38
61
|
|
39
|
-
## [3.1.7] - 2020-12-19
|
62
|
+
## [3.1.7] ([tag][3.1.7t]) - 2020-12-19
|
40
63
|
|
41
|
-
## [3.1.6] - tagged, but unreleased
|
64
|
+
## [3.1.6] ([tag][3.1.6t]) - tagged, but unreleased
|
42
65
|
|
43
|
-
## [3.1.5] - 2020-12-18
|
66
|
+
## [3.1.5] ([tag][3.1.5t]) - 2020-12-18
|
44
67
|
|
45
|
-
## [3.1.4] - 2020-12-18
|
68
|
+
## [3.1.4] ([tag][3.1.4t]) - 2020-12-18
|
46
69
|
|
47
|
-
## [3.1.3] - 2020-12-18
|
70
|
+
## [3.1.3] ([tag][3.1.3t]) - 2020-12-18
|
48
71
|
|
49
|
-
## [3.1.2] - 2020-12-10
|
72
|
+
## [3.1.2] ([tag][3.1.2t]) - 2020-12-10
|
50
73
|
|
51
|
-
## [3.1.1] - 2020-12-09
|
74
|
+
## [3.1.1] ([tag][3.1.1t]) - 2020-12-09
|
52
75
|
|
53
|
-
## [3.1.0] - 2020-10-24
|
76
|
+
## [3.1.0] ([tag][3.1.0t]) - 2020-10-24
|
54
77
|
|
55
|
-
## [3.0.0] - 2020-10-07
|
78
|
+
## [3.0.0] ([tag][3.0.0t]) - 2020-10-07
|
56
79
|
|
57
|
-
## [2.0.0] - 2020-10-06
|
80
|
+
## [2.0.0] ([tag][2.0.0t]) - 2020-10-06
|
58
81
|
|
59
|
-
## [1.0.17] - 2018-09-10
|
82
|
+
## [1.0.17] ([tag][1.0.17t]) - 2018-09-10
|
60
83
|
|
61
|
-
## [1.0.16] - 2018-01-16
|
84
|
+
## [1.0.16] ([tag][1.0.16t]) - 2018-01-16
|
62
85
|
|
63
|
-
## [1.0.15] - 2017-10-17
|
86
|
+
## [1.0.15] ([tag][1.0.15t]) - 2017-10-17
|
64
87
|
|
65
|
-
## [1.0.14] - 2017-10-09
|
88
|
+
## [1.0.14] ([tag][1.0.14t]) - 2017-10-09
|
66
89
|
|
67
|
-
## [1.0.13] - 2017-10-08
|
90
|
+
## [1.0.13] ([tag][1.0.13t]) - 2017-10-08
|
68
91
|
|
69
|
-
## [1.0.12] - 2017-10-08
|
92
|
+
## [1.0.12] ([tag][1.0.12t]) - 2017-10-08
|
70
93
|
|
71
|
-
## [1.0.11] - 2017-10-06
|
94
|
+
## [1.0.11] ([tag][1.0.11t]) - 2017-10-06
|
72
95
|
|
73
|
-
## [1.0.10] - 2017-09-26
|
96
|
+
## [1.0.10] ([tag][1.0.10t]) - 2017-09-26
|
74
97
|
|
75
|
-
## [1.0.9] - 2017-09-06
|
98
|
+
## [1.0.9] ([tag][1.0.9t]) - 2017-09-06
|
76
99
|
|
77
|
-
## [1.0.8] - 2017-09-06
|
100
|
+
## [1.0.8] ([tag][1.0.8t]) - 2017-09-06
|
78
101
|
|
79
|
-
## [1.0.7] - 2017-09-06
|
102
|
+
## [1.0.7] ([tag][1.0.7t]) - 2017-09-06
|
80
103
|
|
81
|
-
## [1.0.6] - 2017-09-05
|
104
|
+
## [1.0.6] ([tag][1.0.6t]) - 2017-09-05
|
82
105
|
|
83
|
-
## [1.0.5] ([tag][1.0.
|
106
|
+
## [1.0.5] ([tag][1.0.5t]) - 2017-03-31
|
84
107
|
|
85
108
|
## [1.0.4] ([tag][1.0.4t]) - 2017-03-31
|
86
109
|
|
@@ -95,7 +118,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
95
118
|
## [0.1.0] ([tag][0.1.0t]) - 2017-03-25
|
96
119
|
- Initial release
|
97
120
|
|
98
|
-
[Unreleased]: https://gitlab.com/kettle-rb/kettle-soup-cover/-/compare/
|
121
|
+
[Unreleased]: https://gitlab.com/kettle-rb/kettle-soup-cover/-/compare/v4.0.2...HEAD
|
122
|
+
[4.0.2t]: https://gitlab.com/pboling/debug_logging/-/tags/v4.0.2
|
123
|
+
[4.0.2]: https://gitlab.com/kettle-rb/kettle-soup-cover/-/compare/v4.0.1...v4.0.2
|
124
|
+
[4.0.1t]: https://gitlab.com/pboling/debug_logging/-/tags/v4.0.1
|
125
|
+
[4.0.1]: https://gitlab.com/kettle-rb/kettle-soup-cover/-/compare/v4.0.0...v4.0.1
|
126
|
+
[4.0.0t]: https://gitlab.com/pboling/debug_logging/-/tags/v4.0.0
|
127
|
+
[4.0.0]: https://gitlab.com/kettle-rb/kettle-soup-cover/-/compare/v3.1.9...v4.0.0
|
99
128
|
[3.1.9t]: https://gitlab.com/pboling/debug_logging/-/tags/v3.1.9
|
100
129
|
[3.1.9]: https://gitlab.com/kettle-rb/kettle-soup-cover/-/compare/v3.1.8...v3.1.9
|
101
130
|
[3.1.8t]: https://gitlab.com/pboling/debug_logging/-/tags/v3.1.8
|
data/CONTRIBUTING.md
CHANGED
@@ -20,7 +20,7 @@ To release a new version:
|
|
20
20
|
6. Run `git checkout main` (Or whichever branch is considered `trunk`, e.g. `master`)
|
21
21
|
7. Run `git pull origin main` to ensure you will release the latest trunk code.
|
22
22
|
8. Set `SOURCE_DATE_EPOCH` so `rake build` and `rake release` use same timestamp, and generate same checksums
|
23
|
-
a. Run `export SOURCE_DATE_EPOCH=$EPOCHSECONDS`
|
23
|
+
a. Run `export SOURCE_DATE_EPOCH=$EPOCHSECONDS && echo $SOURCE_DATE_EPOCH`
|
24
24
|
9. Run `bundle exec rake build`
|
25
25
|
10. Run [`bin/checksums`](https://github.com/rubygems/guides/pull/325) to create SHA-256 and SHA-512 checksums
|
26
26
|
a. Checksums will be committed automatically by the script, but not pushed
|
data/README.md
CHANGED
@@ -60,7 +60,7 @@ Supports `ActiveSupport::Notifications` (thanks [@jgillson](https://github.com/j
|
|
60
60
|
[✌️wellfound-img]: https://img.shields.io/badge/peter--boling-orange?style=plastic&logo=angellist
|
61
61
|
[🐦twitter]: http://twitter.com/intent/user?screen_name=galtzo
|
62
62
|
[🐦twitter-img]: https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow%20@galtzo
|
63
|
-
[🚎blog]: http://www.railsbling.com/tags/
|
63
|
+
[🚎blog]: http://www.railsbling.com/tags/debug_logging/
|
64
64
|
[🚎blog-img]: https://img.shields.io/badge/blog-railsbling-brightgreen.svg?style=flat
|
65
65
|
[my🧪lab]: https://gitlab.com/pboling
|
66
66
|
[my🧊berg]: https://codeberg.org/pboling
|
@@ -82,6 +82,7 @@ Supports `ActiveSupport::Notifications` (thanks [@jgillson](https://github.com/j
|
|
82
82
|
* *All configuration is inheritable to, and overridable by, child classes, since v3.1.3*
|
83
83
|
* *[Class finalization hook](https://stackoverflow.com/a/34559282) (optional: `require 'debug_logging/finalize'` and `extend DebugLogging::Finalize`), since v3.1.3*
|
84
84
|
* *Error handling hooks you can use to log problems when they happen, since v3.1.7*
|
85
|
+
* *Fixed: Works with benchmarking options since v4.0.2*
|
85
86
|
* **so many free ponies** 🎠🐴🎠🐴🎠🐴
|
86
87
|
|
87
88
|
## Next Level Magic
|
@@ -89,7 +90,7 @@ Supports `ActiveSupport::Notifications` (thanks [@jgillson](https://github.com/j
|
|
89
90
|
Herein you will find:
|
90
91
|
|
91
92
|
* ~~Classes inheriting from Module~~ Refactored to use standard Modules and `prepend`!
|
92
|
-
* Zero tolerance policy on monkey patching
|
93
|
+
* Zero tolerance policy on global monkey patching
|
93
94
|
* When the gem is loaded there are no monkey patches.
|
94
95
|
* Rather, your own classes/methods get "patched" and "hooked" as you configure them.
|
95
96
|
* 100% clean, 0% obtrusive
|
@@ -148,7 +149,7 @@ Recommend creating `config/initializers/debug_logging.rb`, or adding to `config/
|
|
148
149
|
```ruby
|
149
150
|
# Showing the defaults
|
150
151
|
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.
|
151
|
-
DebugLogging.configuration.log_level = :debug # at what level
|
152
|
+
DebugLogging.configuration.log_level = :debug # at what level are the messages created by this gem sent at?
|
152
153
|
DebugLogging.configuration.multiple_last_hashes = false # pass every hash argument to last_hash_to_s_proc?
|
153
154
|
DebugLogging.configuration.last_hash_to_s_proc = nil # e.g. ->(hash) { "keys: #{hash.keys}" }
|
154
155
|
DebugLogging.configuration.last_hash_max_length = 1_000
|
@@ -160,11 +161,13 @@ DebugLogging.configuration.active_support_notifications = false
|
|
160
161
|
DebugLogging.configuration.colorized_chain_for_method = false # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
161
162
|
DebugLogging.configuration.colorized_chain_for_class = false # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
162
163
|
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 }
|
164
|
+
DebugLogging.configuration.time_formatter_proc = DebugLogging::Constants::DEFAULT_TIME_FORMATTER
|
165
|
+
DebugLogging.configuration.add_timestamp = false
|
163
166
|
DebugLogging.configuration.ellipsis = " ✂️ …".freeze
|
164
167
|
DebugLogging.configuration.mark_scope_exit = true # Only has an effect if benchmarking is off, since benchmarking always marks the scope exit
|
165
168
|
DebugLogging.configuration.add_payload = false # or a proc which will be called to print the payload
|
166
169
|
DebugLogging.configuration.payload_max_length = 1000
|
167
|
-
DebugLogging.configuration.error_handler_proc = nil # e.g. ->(error, config, obj, method_name, args) { config.log { "#{error.class}: #{error.message} in #{method_name}\nargs: #{args.inspect}" } }
|
170
|
+
DebugLogging.configuration.error_handler_proc = nil # e.g. ->(error, config, obj, method_name, *args, **kwargs) { config.log { "#{error.class}: #{error.message} in #{method_name}\nargs: #{args.inspect}" } }
|
168
171
|
```
|
169
172
|
|
170
173
|
If you prefer to use the block style:
|
@@ -183,12 +186,14 @@ DebugLogging.configure do |config|
|
|
183
186
|
config.active_support_notifications = false
|
184
187
|
config.colorized_chain_for_method = false # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
185
188
|
config.colorized_chain_for_class = false # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
189
|
+
config.time_formatter_proc = DebugLogging::Constants::DEFAULT_TIME_FORMATTER
|
190
|
+
config.add_timestamp = false
|
186
191
|
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 }
|
187
192
|
config.ellipsis = " ✂️ …".freeze
|
188
193
|
config.mark_scope_exit = true # Only has an effect if benchmarking is off, since benchmarking always marks the scope exit
|
189
194
|
config.add_payload = false # or a proc which will be called to print the payload
|
190
195
|
config.payload_max_length = 1000
|
191
|
-
config.error_handler_proc = nil # e.g. ->(error, config, obj, method_name, args) { config.log { "#{error.class}: #{error.message} in #{method_name}\nargs: #{args.inspect}" } }
|
196
|
+
config.error_handler_proc = nil # e.g. ->(error, config, obj, method_name, *args, **kwargs) { config.log { "#{error.class}: #{error.message} in #{method_name}\nargs: #{args.inspect}" } }
|
192
197
|
end
|
193
198
|
```
|
194
199
|
|
@@ -208,7 +213,7 @@ Just send along a hash of the config options, similar to the following:
|
|
208
213
|
|
209
214
|
See the example class below, and the specs.
|
210
215
|
|
211
|
-
**NOTE ON** `Rails.logger` - It will probably be nil in your initializer, so setting the `config.logger` to `Rails.logger` there will result in setting it to `nil`, which means the default will end up being used: `Logger.new(
|
216
|
+
**NOTE ON** `Rails.logger` - It will probably be nil in your initializer, so setting the `config.logger` to `Rails.logger` there will result in setting it to `nil`, which means the default will end up being used: `Logger.new($stdout)`. Instead just config the logger in your application.rb, or anytime later, but *before your classes get loaded* and start inheriting the config:
|
212
217
|
|
213
218
|
```ruby
|
214
219
|
DebugLogging.configuration.logger = Rails.logger
|
@@ -260,6 +265,7 @@ class Car
|
|
260
265
|
logged :dealer_options, {
|
261
266
|
something: "here", # <= will be logged, and available to last_hash_to_s_proc
|
262
267
|
multiple_last_hashes: true, # <= Overrides config
|
268
|
+
error_handler_proc: nil, # NOTE: if you define the error_handler_proc inside a class like this you can use self inside the proc to refer to the class the method was called on!
|
263
269
|
}
|
264
270
|
def self.will_not_be_logged
|
265
271
|
false
|
@@ -294,7 +300,28 @@ class Car
|
|
294
300
|
# Override configuration options for any instance method(s), by passing a hash as the last argument
|
295
301
|
# In the last hash any non-Configuration keys will be data that gets logged,
|
296
302
|
# and also made available to last_hash_to_s_proc
|
297
|
-
|
303
|
+
# Here's an example that sets every possible option, while also showing what the default values are!
|
304
|
+
i_logged [:faster], {
|
305
|
+
logger: Logger.new($stdout), # probably want to override to be the Rails.logger
|
306
|
+
log_level: :debug, # at what level do the messages created by this gem sent at?
|
307
|
+
multiple_last_hashes: false,
|
308
|
+
last_hash_to_s_proc: nil, # e.g. ->(hash) { "keys: #{hash.keys}" }
|
309
|
+
last_hash_max_length: 1_000,
|
310
|
+
args_to_s_proc: nil, # e.g. ->(*record) { "record id: #{record.first.id}" }
|
311
|
+
args_max_length: 1_000,
|
312
|
+
colorized_chain_for_method: false, # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
313
|
+
colorized_chain_for_class: false, # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
314
|
+
add_invocation_id: true, # allows unique identification of method call; association of entry and exit log lines
|
315
|
+
ellipsis: " ✂️ …".freeze,
|
316
|
+
mark_scope_exit: false,
|
317
|
+
add_payload: true, # Can also be a proc returning a string, which will be called when printing the payload
|
318
|
+
payload_max_length: 1_000,
|
319
|
+
error_handler_proc: nil, # NOTE: if you define the error_handler_proc inside a class like this you can use self inside the proc to refer to the instance of the class the method was called on!
|
320
|
+
time_formatter_proc: DebugLogging::Constants::DEFAULT_TIME_FORMATTER,
|
321
|
+
add_timestamp: false,
|
322
|
+
instance_benchmarks: false,
|
323
|
+
class_benchmarks: false,
|
324
|
+
}
|
298
325
|
|
299
326
|
# You can also use `i_logged` as a true method decorator:
|
300
327
|
i_logged def slower
|
@@ -414,8 +441,8 @@ end
|
|
414
441
|
Run tests!
|
415
442
|
|
416
443
|
```shell
|
417
|
-
|
418
|
-
|
444
|
+
bin/setup
|
445
|
+
bin/rake
|
419
446
|
```
|
420
447
|
|
421
448
|
## Contributing
|
@@ -486,13 +513,15 @@ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright
|
|
486
513
|
[homepage]: https://github.com/pboling/debug_logging
|
487
514
|
[blogpage]: http://www.railsbling.com/tags/debug_logging/
|
488
515
|
|
489
|
-
[comment]: <> ( PERSONAL LINKS )
|
516
|
+
[comment]: <> ( 💁🏼♂️ PERSONAL LINKS )
|
490
517
|
|
491
518
|
[💁🏼♂️aboutme]: https://about.me/peter.boling
|
492
519
|
[💁🏼♂️angellist]: https://angel.co/peter-boling
|
493
520
|
[💁🏼♂️devto]: https://dev.to/galtzo
|
494
521
|
[💁🏼♂️followme]: https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow
|
495
522
|
[💁🏼♂️twitter]: http://twitter.com/galtzo
|
523
|
+
[💁🏼♂️peterboling]: http://www.peterboling.com
|
524
|
+
[💁🏼♂️railsbling]: http://www.railsbling.com
|
496
525
|
|
497
526
|
[comment]: <> ( KEYED LINKS )
|
498
527
|
|
data/SECURITY.md
CHANGED
@@ -7,11 +7,13 @@ module DebugLogging
|
|
7
7
|
"completed in #{format("%f", tms.real)}s (#{format("%f", tms.total)}s CPU)"
|
8
8
|
end
|
9
9
|
|
10
|
-
def debug_invocation_id_to_s(args: nil, kwargs: nil, config_proxy: nil)
|
10
|
+
def debug_invocation_id_to_s(args: nil, kwargs: nil, start_at: nil, config_proxy: nil)
|
11
11
|
return "" unless (args || kwargs) && config_proxy
|
12
12
|
|
13
13
|
if config_proxy.debug_add_invocation_id
|
14
|
-
|
14
|
+
time = start_at ? Util.debug_time(start_at) : Time.now
|
15
|
+
unique_id = (time.to_f.to_s % "%#-21a")[4..-4]
|
16
|
+
invocation = " ~#{args.object_id}|#{kwargs.object_id}@#{unique_id}~"
|
15
17
|
case config_proxy.debug_add_invocation_id
|
16
18
|
when true
|
17
19
|
invocation
|
@@ -23,24 +25,28 @@ module DebugLogging
|
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
|
28
|
+
# @return [String]
|
29
|
+
def debug_time_to_s(time_or_monotonic, config_proxy: nil)
|
30
|
+
return "" unless config_proxy&.debug_add_timestamp
|
31
|
+
return config_proxy.debug_time_formatter_proc.call(Time.now) unless time_or_monotonic
|
32
|
+
|
33
|
+
time = Util.debug_time(time_or_monotonic)
|
34
|
+
|
35
|
+
config_proxy.debug_time_formatter_proc.call(time)
|
36
|
+
end
|
37
|
+
|
38
|
+
# A custom time format will never apply here, because ActiveSupport::Notifications have a required time format
|
39
|
+
def debug_event_time_to_s(time_or_monotonic)
|
27
40
|
# Time format must match:
|
28
41
|
# \d{4,}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-+]\d{4}
|
29
42
|
# YYYY-MM-DD HH:mm:ss +00:00
|
30
43
|
# strftime("%F %T %z")
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
when Time, DateTime
|
35
|
-
time_or_monotonic.strftime("%F %T %z")
|
36
|
-
when String
|
37
|
-
Time.parse(time_or_monotonic).strftime("%F %T %z")
|
38
|
-
else
|
39
|
-
time_or_monotonic
|
40
|
-
end
|
44
|
+
time_or_monotonic = Time.now if time_or_monotonic.nil? || (time_or_monotonic.respond_to?(:empty?) && time_or_monotonic.empty?)
|
45
|
+
time = Util.debug_time(time_or_monotonic)
|
46
|
+
DebugLogging::Constants::EVENT_TIME_FORMATTER.call(time)
|
41
47
|
end
|
42
48
|
|
43
|
-
def debug_invocation_to_s(klass: nil, separator: nil,
|
49
|
+
def debug_invocation_to_s(klass: nil, separator: nil, decorated_method: nil, config_proxy: nil)
|
44
50
|
return "" unless config_proxy
|
45
51
|
|
46
52
|
klass_string = if config_proxy.debug_colorized_chain_for_class
|
@@ -49,9 +55,9 @@ module DebugLogging
|
|
49
55
|
klass.to_s
|
50
56
|
end
|
51
57
|
method_string = if config_proxy.debug_colorized_chain_for_method
|
52
|
-
config_proxy.debug_colorized_chain_for_method.call(ColorizedString[
|
58
|
+
config_proxy.debug_colorized_chain_for_method.call(ColorizedString[decorated_method.to_s])
|
53
59
|
else
|
54
|
-
|
60
|
+
decorated_method.to_s
|
55
61
|
end
|
56
62
|
"#{klass_string}#{separator}#{method_string}"
|
57
63
|
end
|
@@ -63,7 +69,7 @@ module DebugLogging
|
|
63
69
|
|
64
70
|
add_args_ellipsis = false
|
65
71
|
args = args.dup
|
66
|
-
args.push(kwargs) if kwargs
|
72
|
+
args.push(kwargs) if kwargs&.keys && !kwargs&.keys&.length&.zero?
|
67
73
|
if config_proxy.debug_last_hash_to_s_proc && args[-1].is_a?(Hash)
|
68
74
|
add_other_args_ellipsis = false
|
69
75
|
if args.length > 1
|
@@ -188,7 +194,7 @@ module DebugLogging
|
|
188
194
|
proc_name: "add_payload",
|
189
195
|
proc: config_proxy.debug_add_payload,
|
190
196
|
args: payload,
|
191
|
-
max_length: config_proxy.
|
197
|
+
max_length: config_proxy.debug_payload_max_length,
|
192
198
|
)
|
193
199
|
printed_payload += printed
|
194
200
|
printed_payload += config_proxy.debug_ellipsis if add_payload_ellipsis
|
@@ -198,8 +204,8 @@ module DebugLogging
|
|
198
204
|
|
199
205
|
module_function
|
200
206
|
|
201
|
-
def debug_event_name_to_s(
|
202
|
-
"#{
|
207
|
+
def debug_event_name_to_s(decorated_method: nil)
|
208
|
+
"#{decorated_method}.log"
|
203
209
|
end
|
204
210
|
end
|
205
211
|
end
|
@@ -1,72 +1,42 @@
|
|
1
1
|
module DebugLogging
|
2
2
|
module ClassLogger
|
3
|
+
class << self
|
4
|
+
def extended(base)
|
5
|
+
base.extend(LambDartable::Log)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
def logged(*methods_to_log)
|
4
10
|
methods_to_log, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
5
11
|
method_names: methods_to_log,
|
6
12
|
payload: nil,
|
7
13
|
config: nil,
|
8
14
|
)
|
9
|
-
Array(methods_to_log).each do |
|
10
|
-
|
11
|
-
method_names:
|
15
|
+
Array(methods_to_log).each do |decorated_method|
|
16
|
+
decorated_method, method_payload, method_config_opts = DebugLogging::Util.extract_payload_and_config(
|
17
|
+
method_names: decorated_method,
|
12
18
|
payload: payload,
|
13
19
|
config: config_opts,
|
14
20
|
)
|
15
|
-
original_method = method(
|
21
|
+
original_method = method(decorated_method)
|
16
22
|
(class << self; self; end).class_eval do
|
17
|
-
define_method(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
+
define_method(decorated_method) do |*args, **kwargs, &block|
|
24
|
+
lamb_dart = LambDart::Log.new(
|
25
|
+
klass: self,
|
26
|
+
method_config_opts:,
|
27
|
+
method_payload:,
|
28
|
+
args:,
|
29
|
+
kwargs:,
|
30
|
+
decorated_method:,
|
23
31
|
)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
separator: "::",
|
33
|
-
method_to_log: method_to_log,
|
34
|
-
config_proxy: config_proxy,
|
35
|
-
)
|
36
|
-
invocation_id = debug_invocation_id_to_s(args: args, config_proxy: config_proxy)
|
37
|
-
signature = debug_signature_to_s(args: args, config_proxy: config_proxy)
|
38
|
-
paymud = debug_payload_to_s(payload: paydirt, config_proxy: config_proxy)
|
39
|
-
"#{log_prefix}#{signature}#{invocation_id} debug: #{paymud}"
|
40
|
-
end
|
41
|
-
if config_proxy.benchmarkable_for?(:debug_class_benchmarks)
|
42
|
-
tms = Benchmark.measure do
|
43
|
-
method_return_value = if args.size == 1 && (harsh = args[0]) && harsh.is_a?(Hash)
|
44
|
-
original_method.call(**harsh, &block)
|
45
|
-
else
|
46
|
-
original_method.call(*args, &block)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
config_proxy.log do
|
50
|
-
"#{log_prefix} #{debug_benchmark_to_s(tms: tms)}#{invocation_id}"
|
51
|
-
end
|
52
|
-
else
|
53
|
-
method_return_value = if args.size == 1 && (harsh = args[0]) && harsh.is_a?(Hash)
|
54
|
-
original_method.call(**harsh, &block)
|
55
|
-
else
|
56
|
-
original_method.call(*args, &block)
|
57
|
-
end
|
58
|
-
if config_proxy.exit_scope_markable? && invocation_id && !invocation_id.empty?
|
59
|
-
config_proxy.log do
|
60
|
-
"#{log_prefix} completed#{invocation_id}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
method_return_value
|
65
|
-
rescue StandardError => e
|
66
|
-
if config_proxy.error_handler_proc
|
67
|
-
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_log, args)
|
68
|
-
else
|
69
|
-
raise e
|
32
|
+
real_mccoy = ->() {
|
33
|
+
original_method.call(*args, **kwargs, &block)
|
34
|
+
}
|
35
|
+
_dl_ld_enter_log(lamb_dart) do
|
36
|
+
_dl_ld_error_handle(lamb_dart) do
|
37
|
+
return _dl_ld_benchmarked(lamb_dart) { real_mccoy.call } if lamb_dart.bench?
|
38
|
+
|
39
|
+
_dl_ld_exit_log(lamb_dart) { real_mccoy.call }
|
70
40
|
end
|
71
41
|
end
|
72
42
|
end
|
@@ -1,53 +1,37 @@
|
|
1
1
|
module DebugLogging
|
2
2
|
module ClassNotifier
|
3
|
+
class << self
|
4
|
+
def extended(base)
|
5
|
+
base.extend(LambDartable::Note)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
def notified(*methods_to_notify)
|
4
10
|
methods_to_notify, payload, config_opts = DebugLogging::Util.extract_payload_and_config(
|
5
11
|
method_names: methods_to_notify,
|
6
12
|
payload: nil,
|
7
13
|
config: nil,
|
8
14
|
)
|
9
|
-
Array(methods_to_notify).each do |
|
10
|
-
|
11
|
-
method_names:
|
15
|
+
Array(methods_to_notify).each do |decorated_method|
|
16
|
+
decorated_method, method_payload, method_config_opts = DebugLogging::Util.extract_payload_and_config(
|
17
|
+
method_names: decorated_method,
|
12
18
|
payload: payload,
|
13
19
|
config: config_opts,
|
14
20
|
)
|
15
|
-
original_method = method(
|
21
|
+
original_method = method(decorated_method)
|
16
22
|
(class << self; self; end).class_eval do
|
17
|
-
define_method(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
paydirt = DebugLogging::Util.payload_instance_variable_hydration(scope: self, payload: method_payload)
|
33
|
-
ActiveSupport::Notifications.instrument(
|
34
|
-
DebugLogging::ArgumentPrinter.debug_event_name_to_s(method_to_notify: method_to_notify),
|
35
|
-
{
|
36
|
-
debug_args: args,
|
37
|
-
config_proxy: config_proxy,
|
38
|
-
**paydirt,
|
39
|
-
},
|
40
|
-
) do
|
41
|
-
if args.size == 1 && (harsh = args[0]) && harsh.is_a?(Hash)
|
42
|
-
original_method.call(**harsh, &block)
|
43
|
-
else
|
44
|
-
original_method.call(*args, &block)
|
45
|
-
end
|
46
|
-
rescue StandardError => e
|
47
|
-
if config_proxy.error_handler_proc
|
48
|
-
config_proxy.error_handler_proc.call(config_proxy, e, self, method_to_notify, args)
|
49
|
-
else
|
50
|
-
raise e
|
23
|
+
define_method(decorated_method) do |*args, **kwargs, &block|
|
24
|
+
lamb_dart = LambDart::Note.new(
|
25
|
+
klass: self,
|
26
|
+
method_config_opts:,
|
27
|
+
method_payload:,
|
28
|
+
args:,
|
29
|
+
kwargs:,
|
30
|
+
decorated_method:,
|
31
|
+
)
|
32
|
+
_dl_ld_notify(lamb_dart) do
|
33
|
+
_dl_ld_error_handle(lamb_dart) do
|
34
|
+
original_method.call(*args, **kwargs, &block)
|
51
35
|
end
|
52
36
|
end
|
53
37
|
end
|
@@ -12,16 +12,25 @@ module DebugLogging
|
|
12
12
|
# extend DebugLogging::InstanceLogger
|
13
13
|
# i_logged [:drive, :stop],
|
14
14
|
# {
|
15
|
-
# logger: Logger.new(
|
16
|
-
# log_level: :debug # at what level do the messages created by this gem sent at?
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
15
|
+
# logger: Logger.new($stdout), # probably want to override to be the Rails.logger
|
16
|
+
# log_level: :debug, # at what level do the messages created by this gem sent at?
|
17
|
+
# multiple_last_hashes: false,
|
18
|
+
# last_hash_to_s_proc: nil, # e.g. ->(hash) { "keys: #{hash.keys}" }
|
19
|
+
# last_hash_max_length: 1_000,
|
20
|
+
# args_to_s_proc: nil, # e.g. ->(*record) { "record id: #{record.first.id}" }
|
21
|
+
# args_max_length: 1_000,
|
22
|
+
# colorized_chain_for_method: false, # e.g. ->(colorized_string) { colorized_string.red.on_blue.underline }
|
23
|
+
# colorized_chain_for_class: false, # e.g. ->(colorized_string) { colorized_string.colorize(:light_blue ).colorize( :background => :red) }
|
24
|
+
# add_invocation_id: true, # allows unique identification of method call; association of entry and exit log lines
|
25
|
+
# ellipsis: " ✂️ …".freeze,
|
26
|
+
# mark_scope_exit: false,
|
27
|
+
# add_payload: true, # Can also be a proc returning a string, which will be called when printing the payload
|
28
|
+
# payload_max_length: 1_000,
|
29
|
+
# error_handler_proc: nil,
|
30
|
+
# time_formatter_proc: DebugLogging::Constants::DEFAULT_TIME_FORMATTER,
|
31
|
+
# add_timestamp: false,
|
32
|
+
# instance_benchmarks: false,
|
33
|
+
# class_benchmarks: false,
|
25
34
|
# }
|
26
35
|
#
|
27
36
|
CONFIG_KEYS.each do |key|
|
@@ -29,11 +38,11 @@ module DebugLogging
|
|
29
38
|
end
|
30
39
|
|
31
40
|
class << self
|
32
|
-
def config_pointer(type,
|
41
|
+
def config_pointer(type, decorated_method)
|
33
42
|
# Methods names that do not match the following regex can't be part of an ivar name
|
34
43
|
# /[a-zA-Z_][a-zA-Z0-9_]*/
|
35
44
|
# Thus we have to use a different form of the method name that is compatible with ivar name conventions
|
36
|
-
"@debug_logging_config_#{type}_#{Digest::MD5.hexdigest(
|
45
|
+
"@debug_logging_config_#{type}_#{Digest::MD5.hexdigest(decorated_method.to_s)}".to_sym
|
37
46
|
end
|
38
47
|
end
|
39
48
|
|