ruby_smart-simple_logger 1.0.0 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b775a10b017444f9047871d41db7c386bb6510b2321c4cf71444eb6a33f8e22
4
- data.tar.gz: c4f786468dcf26311e72f4860c6859942cea284370ba733c5e80b5a4c5a47dfa
3
+ metadata.gz: c9d250fc038e12f5d76ede43d6714efb039be7b6093bd4ea8abca6dfc937d8cc
4
+ data.tar.gz: 52d4bc7495fea29db91b336161b7af454d55b9f22e76f1e83291264844686df7
5
5
  SHA512:
6
- metadata.gz: 460b10c4d0f27a6ab678bd2ad589b2f9986348a596e88b1f5c580bd08fd9c310af75b710758693902bbe76a7e838a6f9231fb37824e627677ca44ca65d52bc27
7
- data.tar.gz: 1c7ea37910757a6748a230a4579a5b848e78ffb03dd40c01f55c9cc035e91853a30e9230735e28627aa67bf549028320f35bb6ff9b0f1b579923699b47411742
6
+ metadata.gz: cf60c99604f5da1abd4bc4ffa5c536c233728c242c7c198849fd1838cacf856a0abaaef39f6cb1aa46fc9adbd85be329637f01e0844c39e43bdac660db311a20
7
+ data.tar.gz: 7c618af918fd6a19228f152fd456a8a4f2d99bbeceae1aec4d2aa6706f11f2138ba575390d68076f2d07e29fe09fbcdce75c64baed06a887becb752662f391bd
data/.gitignore CHANGED
@@ -6,6 +6,7 @@ Gemfile.lock
6
6
  # testing
7
7
  .rspec_status
8
8
  /spec/reports/
9
+ /log
9
10
 
10
11
  # documentation & coverage
11
12
  /.yardoc
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Documentation](https://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.info/gems/ruby_smart-simple_logger)
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/ruby_smart-simple_logger.svg?kill_cache=1)](https://badge.fury.io/rb/ruby_smart-simple_logger)
7
- [![License](https://img.shields.io/github/license/ruby-smart/simple_logger)](docs/LICENSE.txt)
7
+ [![License](https://img.shields.io/badge/license-MIT-green)](docs/LICENSE.txt)
8
8
 
9
9
  [![Coverage Status](https://coveralls.io/repos/github/ruby-smart/simple_logger/badge.svg?branch=main&kill_cache=1)](https://coveralls.io/github/ruby-smart/simple_logger?branch=main)
10
10
  [![Tests](https://github.com/ruby-smart/simple_logger/actions/workflows/ruby.yml/badge.svg)](https://github.com/ruby-smart/simple_logger/actions/workflows/ruby.yml)
@@ -147,7 +147,7 @@ MyCustomLogger.info "Very nice here"
147
147
  # => creates a logfile @ log/my_app/tasks/special_task.log
148
148
  ```
149
149
 
150
- This is already done for the `SimpleLogger` module - so you can directly access the methods:
150
+ This is already done for the `SimpleLogger` _(or `Debugger`)_ module - so you can directly access the methods:
151
151
  ```ruby
152
152
  require 'simple_logger'
153
153
 
@@ -171,6 +171,14 @@ other_logger2 = SimpleLogger.new :rails
171
171
  other_logger2.info "directly logs to the rails logger"
172
172
  ```
173
173
 
174
+ Alternatives with 'Debugger':
175
+ ```ruby
176
+ require 'debugger'
177
+
178
+ Debugger.debug "some debug"
179
+ Debugger.error "that failed ..."
180
+ ```
181
+
174
182
  -----
175
183
 
176
184
  ## Builtins
@@ -294,7 +302,7 @@ noformat_logger.debug "some debug without color and mask - uses the default form
294
302
 
295
303
  ### Module Builtin
296
304
 
297
- Providing a ```Module``` will also create and write to a new logfile.
305
+ Providing a ```module``` will also create and write to a new logfile.
298
306
  The path depends on the provided module name.
299
307
 
300
308
  **Example:**
@@ -335,7 +343,9 @@ logger.debug "debug message"
335
343
  ### passthrough Format
336
344
 
337
345
  The **passthrough** format is mostly used to just 'passthrough' all args to the device _(proc, memory, file, etc.)_ without formatting anything.
338
- This will just provide an array of args.
346
+ This will simply provide an array of args.
347
+
348
+ _Using this format will prevent **newlines** and does not recognize the `:nl` / `:clr` option._
339
349
 
340
350
  ```ruby
341
351
  logger = ::SimpleLogger.new(:stdout, format: :passthrough, payload: false)
@@ -349,6 +359,8 @@ logger.debug "debug message"
349
359
  The **plain** format is only used to forward the provided **data**, without severity, time, etc.
350
360
  This is the default behaviour of the SimpleLogger - which is used to build `scene`, masks, ...
351
361
 
362
+ _Using this format will prevent **newlines** and does not recognize the `:nl` / `:clr` option._
363
+
352
364
  ```ruby
353
365
  logger = ::SimpleLogger.new(:stdout, format: :plain, payload: false)
354
366
 
@@ -368,6 +380,8 @@ payload_logger.debug "debug message"
368
380
 
369
381
  The **memory** format is only used by the memory-device to store severity, time & data as an array.
370
382
 
383
+ _Using this format will prevent **newlines** and does not recognize the `:nl` / `:clr` option._
384
+
371
385
  ```ruby
372
386
  logger = ::SimpleLogger.new(:stdout, format: :memory, payload: false)
373
387
 
@@ -419,7 +433,7 @@ logger = ::SimpleLogger.new(payload: false)
419
433
  logger = ::SimpleLogger.new(:stdout, payload: false)
420
434
  ```
421
435
 
422
- ### format _(for default formatter ONLY)_
436
+ ### format
423
437
 
424
438
  Provide a other format.
425
439
  Possible values: ```:default, :passthrough, :plain, :memory, :datalog```
@@ -428,7 +442,7 @@ logger = ::SimpleLogger.new(format: :default)
428
442
  logger = ::SimpleLogger.new(:memory, format: :passthrough)
429
443
  ```
430
444
 
431
- ### nl _(for default formatter ONLY)_
445
+ ### nl
432
446
 
433
447
  Enable / disable NewLine for formatter.
434
448
  ```ruby
@@ -445,7 +459,7 @@ Provide a callback for the ```:proc``` builtin.
445
459
  logger = ::SimpleLogger.new(:proc, proc: lambda{|data| ... })
446
460
  ```
447
461
 
448
- ### stdout _(:memory-builtin ONLY)_
462
+ ### stdout _(:memory & Module-builtin ONLY)_
449
463
 
450
464
  Enable STDOUT as MultiDevice for the memory builtin.
451
465
  ```ruby
@@ -454,8 +468,8 @@ logger = ::SimpleLogger.new(:memory, stdout: true)
454
468
  # same as above
455
469
  logger = ::SimpleLogger.new(
456
470
  ::SimpleLogger::Devices::MultiDevice.new.
457
- register(::SimpleLogger::Devices::MemoryDevice.new, ::SimpleLogger::Formatter.new(format: :memory, nl: false)).
458
- register(STDOUT, ::SimpleLogger::Formatter.new(format: :default, nl: true, clr: (opts[:clr] != nil)))
471
+ register(::SimpleLogger::Devices::MemoryDevice.new, ::SimpleLogger::Formatter.new(format: :memory)).
472
+ register(STDOUT, ::SimpleLogger::Formatter.new(format: :default, nl: true, clr: opts[:clr]))
459
473
  )
460
474
  ```
461
475
 
@@ -491,24 +505,6 @@ Provide a custom formatter instance.
491
505
  logger = ::SimpleLogger.new(formatter: My::Custom::Formatter.new)
492
506
  ```
493
507
 
494
- ### clr
495
-
496
- Disable color for payload and formatter.
497
-
498
- ```ruby
499
- logger = ::SimpleLogger.new(clr: false)
500
- ```
501
-
502
- ### payload
503
-
504
- Disable payload _(mask & scenes)_ for logger
505
-
506
- ```ruby
507
- logger = ::SimpleLogger.new(payload: false)
508
- logger.debug "some debug without payload"
509
- # some debug without payload
510
- ```
511
-
512
508
  ### inspect
513
509
 
514
510
  Disable inspect for logger
@@ -711,6 +707,51 @@ The following PRE-defined scenes are available. _(You can define your own scenes
711
707
  # 50 chars -> __________________________________________________
712
708
  ```
713
709
 
710
+ ### processed(name, opts)
711
+ ```ruby
712
+ require 'simple_logger'
713
+ l = SimpleLogger.new(:stdout, payload: false)
714
+
715
+ l.processed("Process Alpha", timer: true) do
716
+ l.info "find files"
717
+ l.info "found 34 files"
718
+
719
+ l.processed("extracting ...", timer: true) do
720
+ l.info "10% done"
721
+ l.info "20% done"
722
+ l.info "100% done"
723
+
724
+ # returns true to the processed state
725
+ true
726
+ end
727
+
728
+ l.processed("transforming ...") do
729
+ l.error "bad memory"
730
+ l.info "rolling back"
731
+ # returns false to the processed state
732
+ false
733
+ end
734
+
735
+ # returns nil to the processed state
736
+ nil
737
+ end
738
+
739
+
740
+ # ╔ START - Process Alpha
741
+ # ╟ find files
742
+ # ╟ found 34 files
743
+ # ║ ┌ START - extracting ...
744
+ # ║ ├ 10% done
745
+ # ║ ├ 20% done
746
+ # ║ ├ 100% done
747
+ # ║ └ END - SUCCESS (duration: 0.000267545)
748
+ # ║ ┌ START - transforming ...
749
+ # ║ ├ bad memory
750
+ # ║ ├ rolling back
751
+ # ║ └ END - FAILED
752
+ # ╚ END - Process Alpha (duration: 0.001040807)
753
+ ```
754
+
714
755
  ### _other useful methods_
715
756
 
716
757
  - line
data/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # RubySmart::SimpleLogger - CHANGELOG
2
2
 
3
+ ## [1.1.1] - 2023-02-07
4
+ * **[fix]** 'ruby 2.6.x' kwargs for `::Logger::LogDevice` messed up with 'binmode'
5
+
6
+ ## [1.1.0] - 2023-02-07
7
+ * **[add]** `#processed` method for logger
8
+ * **[ref]** `Debugger` to enforce a 'DEBUG' severity
9
+ * **[ref]** `RubySmart::SimpleLogger::Formatter` with simplified formats
10
+ * **[ref]** 'default' format to only
11
+ * **[ref]** builtin for 'modules' to directly work with 'stdout' option
12
+ * **[ref]** handling of logger-newlines 'nl'-option
13
+ * **[fix]** 'inspector' detection
14
+ * **[fix]** `RubySmart::SimpleLogger::KlassLogger.new` not 'dup' klass_logger_opts (now prevents reference manipulation)
15
+
3
16
  ## [1.0.0] - 2023-01-29
4
17
  * **[add]** full documentation
5
18
  * **[add]** add colors, if gem `awesome_print` ist missing
data/docs/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022 Ruby Smart
3
+ Copyright (c) 2023 Ruby Smart
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/lib/debugger.rb CHANGED
@@ -12,6 +12,9 @@ GemInfo.safe_require 'awesome_print'
12
12
  class Debugger
13
13
  extend ::RubySmart::SimpleLogger::KlassLogger
14
14
 
15
+ # force debugger to 'DEBUG' severity
16
+ self.klass_logger_opts = {level: ::RubySmart::SimpleLogger::Logger::DEBUG}
17
+
15
18
  # overwrite existing "debug" method (if Debase was loaded)
16
19
  def self.debug(*args)
17
20
  return false if args.none?
@@ -8,6 +8,10 @@ module RubySmart
8
8
  attr_reader :devices
9
9
  attr_reader :status
10
10
 
11
+ def self.register(*args)
12
+ new.register(*args)
13
+ end
14
+
11
15
  def initialize
12
16
  @devices = []
13
17
  @status = true
@@ -13,23 +13,22 @@ module RubySmart
13
13
 
14
14
  # prepare builtin defaults
15
15
  # @param [Hash] opts
16
- def _opts_builtin(opts)
17
- builtin = opts.delete(:builtin)
16
+ # @param [Object] builtin
17
+ def _opts_builtin(opts, builtin = nil)
18
+ builtin ||= opts.delete(:builtin)
18
19
 
19
20
  case builtin
20
21
  when nil
21
22
  # device is nil - resolve optimal device
22
- opts[:device] ||= if ::ThreadInfo.stdout?
23
- # colorize output
24
- opts[:clr] = true if opts[:clr].nil?
25
-
26
- STDOUT
27
- elsif ::ThreadInfo.rails? && ::Rails.logger
28
- ::RubySmart::SimpleLogger::Devices::MultiDevice.new.register(::Rails.logger.instance_variable_get(:@logdev).dev)
29
- else
30
- ::RubySmart::SimpleLogger::Devices::MemoryDevice.new
31
- end
23
+ if ::ThreadInfo.stdout?
24
+ _opts_builtin(opts, :stdout)
25
+ elsif ::ThreadInfo.rails? && ::Rails.logger
26
+ _opts_builtin(opts, :rails)
27
+ else
28
+ _opts_builtin(opts, :memory)
29
+ end
32
30
  when :stdout
31
+ # set device ONLY if unset in opts
33
32
  opts[:device] ||= STDOUT
34
33
  # colorize output
35
34
  opts[:clr] = true if opts[:clr].nil?
@@ -38,31 +37,67 @@ module RubySmart
38
37
  # colorize output
39
38
  opts[:clr] = true if opts[:clr].nil?
40
39
  when :rails
41
- opts[:device] ||= ::RubySmart::SimpleLogger::Devices::MultiDevice.new.register(::Rails.logger.instance_variable_get(:@logdev).dev)
40
+ # set device ONLY if unset in opts
41
+ opts[:device] ||= ::RubySmart::SimpleLogger::Devices::MultiDevice.register(::Rails.logger.instance_variable_get(:@logdev).dev)
42
42
  when :proc
43
43
  # auto sets related opts for proc device
44
44
  opts[:payload] = false
45
+ opts[:nl] = false
45
46
  opts[:format] ||= :passthrough
46
47
 
47
- # force set device
48
+ # set device ONLY if unset in opts
48
49
  opts[:device] ||= ::RubySmart::SimpleLogger::Devices::ProcDevice.new(opts[:proc])
49
50
  when :memory
50
51
  # auto sets related opts for memory device
51
52
  opts[:payload] = false
52
53
 
53
- # set device
54
+ # set device ONLY if unset in opts
54
55
  opts[:device] ||= if opts[:stdout]
55
- # IMPORTANT: There will be a 'default' formatter created, which will passthrough all data to the device
56
- opts[:format] ||= :passthrough
56
+ # store original format
57
+ stdout_format = opts[:format] || :plain
58
+
59
+ # force 'passthrough', as format, since this is required for multi-devices
60
+ opts[:format] = :passthrough
57
61
 
58
62
  # special case handling to additionally stdout logs
59
- ::RubySmart::SimpleLogger::Devices::MultiDevice.new.
60
- register(::RubySmart::SimpleLogger::Devices::MemoryDevice.new, ::RubySmart::SimpleLogger::Formatter.new(format: :memory, nl: false)).
61
- register(STDOUT, ::RubySmart::SimpleLogger::Formatter.new(format: :default, nl: true, clr: (opts[:clr] != nil)))
63
+ ::RubySmart::SimpleLogger::Devices::MultiDevice.new
64
+ .register(::RubySmart::SimpleLogger::Devices::MemoryDevice.new, ::RubySmart::SimpleLogger::Formatter.new(format: :memory))
65
+ .register(STDOUT, ::RubySmart::SimpleLogger::Formatter.new(format: stdout_format, nl: _nl(opts), clr: opts[:clr]))
62
66
  else
63
67
  opts[:format] ||= :memory
64
68
  ::RubySmart::SimpleLogger::Devices::MemoryDevice.new
65
69
  end
70
+ when Module
71
+ # set device ONLY if unset in opts
72
+ opts[:device] ||= if opts[:stdout]
73
+ # store original format
74
+ device_format = opts[:format] || :plain
75
+
76
+ # force 'passthrough', as format, since this is required for multi-devices
77
+ opts[:format] = :passthrough
78
+
79
+ # colorize output
80
+ opts[:clr] = true if opts[:clr].nil?
81
+
82
+ # special case handling to additionally stdout logs
83
+ ::RubySmart::SimpleLogger::Devices::MultiDevice.register(
84
+ if GemInfo.match?(RUBY_VERSION, '< 2.7')
85
+ ::Logger::LogDevice.new(_logdev(builtin),
86
+ shift_age: opts[:shift_age] || 0,
87
+ shift_size: opts[:shift_size] || 1048576,
88
+ shift_period_suffix: opts[:shift_period_suffix])
89
+ else
90
+ ::Logger::LogDevice.new(_logdev(builtin),
91
+ shift_age: opts[:shift_age] || 0,
92
+ shift_size: opts[:shift_size] || 1048576,
93
+ shift_period_suffix: opts[:shift_period_suffix],
94
+ binmode: opts[:binmode])
95
+ end,
96
+ ::RubySmart::SimpleLogger::Formatter.new(format: device_format, nl: _nl(opts), clr: false))
97
+ .register(STDOUT, ::RubySmart::SimpleLogger::Formatter.new(format: device_format, nl: _nl(opts), clr: opts[:clr]))
98
+ else
99
+ builtin
100
+ end
66
101
  else
67
102
  # forward provided device ONLY if unset in opts
68
103
  opts[:device] ||= builtin
@@ -141,25 +176,36 @@ module RubySmart
141
176
  # clean & rewrite level (possible symbols) to real level
142
177
  opts[:level] = _level(opts[:level] || :debug)
143
178
 
179
+ # clean & rewrite nl
180
+ opts[:nl] = _nl(opts)
181
+
182
+ # rewrite format
183
+ opts[:format] ||= :plain
184
+
144
185
  # provide custom formatter and forward special opts (format, nl, clr)
145
- opts[:formatter] ||= ::RubySmart::SimpleLogger::Formatter.new({ format: :plain, nl: false, clr: false }.merge(opts.slice(:format, :nl, :clr)))
186
+ opts[:formatter] ||= ::RubySmart::SimpleLogger::Formatter.new(opts)
146
187
 
147
188
  # ignore payload and send data directly to the logdev
148
189
  @ignore_payload = true if opts[:payload].is_a?(FalseClass)
149
190
 
150
- # set the inspector to be used for data inspection
151
- @inspector = opts[:inspector]
152
-
153
- # disable inspector
154
- @inspector = :to_s if opts[:inspect] == false
155
-
156
- # # build logdev
157
- # opts[:logdev] = _logdev(opts[:device])
191
+ # set the inspector to be used for data inspection.
192
+ # 'disable' inspector, if false was provided - which simply results in +#to_s+
193
+ @inspector = (opts[:inspect] === false) ? :to_s : opts[:inspector]
158
194
 
159
195
  # simple return opts
160
196
  opts
161
197
  end
162
198
 
199
+ # returns the +nl+ (new line) flag, depending on the provided options.
200
+ # recognizes +:nl+ and +:payload+ options.
201
+ # @param [Hash] opts
202
+ # @return [Boolean]
203
+ def _nl(opts)
204
+ return opts[:nl] unless opts[:nl].nil?
205
+
206
+ opts[:payload].is_a?(FalseClass)
207
+ end
208
+
163
209
  # merge all provided hashes into one single hash
164
210
  #
165
211
  # @example
@@ -20,6 +20,12 @@ module RubySmart
20
20
  m
21
21
  end
22
22
  end
23
+
24
+ # returns a hash with total amounts per logged type (key)
25
+ # @return [Hash]
26
+ def log_stats
27
+ logs_to_h.reduce({}) { |m, (sev, logs)| m[sev] = logs.count; m }
28
+ end
23
29
  end
24
30
  end
25
31
  end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module RubySmart
6
+ module SimpleLogger
7
+ module Extensions
8
+ module Processed
9
+ def self.included(base)
10
+ base.extend ClassMethods
11
+ base.include InstanceMethods
12
+ base.class_eval do
13
+ # set default box chars
14
+ self.box_chars = {
15
+ __default__: %w(╟ ├),
16
+ __processed__: %w(║ │),
17
+ start: %w(╔ ┌),
18
+ end: %w(╚ └)
19
+ }.freeze
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ def box_chars
25
+ class_variable_get('@@box_chars')
26
+ end
27
+
28
+ def box_chars=(chars)
29
+ class_variable_set('@@box_chars', chars)
30
+ end
31
+ end
32
+
33
+ module InstanceMethods
34
+ # returns the current processed level.
35
+ # by providing a handle it will either increase or decrease the current level.
36
+ # @param [nil, Symbol] handle - optional handle to increase or decrease the current lvl (+:up+ / +:down+)
37
+ # @return [Integer]
38
+ def processed_lvl(handle = nil)
39
+ @processed_lvl ||= -1
40
+
41
+ case handle
42
+ when :up
43
+ @processed_lvl += 1
44
+ when :down
45
+ @processed_lvl -= 1 if @processed_lvl >= 0
46
+ else
47
+ # nothing here ...
48
+ end
49
+
50
+ @processed_lvl
51
+ end
52
+
53
+ # returns true if the processed state is active.
54
+ # @return [Boolean]
55
+ def processed?
56
+ processed_lvl >= 0
57
+ end
58
+
59
+ private
60
+
61
+ # transforms the provided data into a 'processed' string and forces the data to be transformed to string.
62
+ # simple returns the provided data, if currently not processed.
63
+ # @param [Object] data
64
+ # @param [Hash] opts
65
+ # @return [Object,String]
66
+ def _pcd(data, opts)
67
+ # check for active pcd (processed)
68
+ return data if opts[:pcd] == false || !processed?
69
+
70
+ # resolve lvl, once
71
+ lvl = opts[:lvl] || processed_lvl
72
+
73
+ # create final string
74
+ lvl.times.map { |i| "#{_pcd_box_char(:__processed__, i)} " }.join + _pcd_box_char(opts[:pcd], lvl) + " #{data}"
75
+ end
76
+
77
+ # returns the processed box character for provided key and position.
78
+ # returns the +:__default__+, if provided key was not found.
79
+ # returns the max-pos char, if current pos was not found.
80
+ # @param [Symbol] key
81
+ # @param [Integer] pos
82
+ # @return [String]
83
+ def _pcd_box_char(key, pos = 0)
84
+ chars = self.class.box_chars[key] || self.class.box_chars[:__default__]
85
+ chars[pos] || chars[-1]
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -53,7 +53,7 @@ module RubySmart
53
53
  # prevent logging nil data
54
54
  return false if data.nil?
55
55
 
56
- add level, data
56
+ add level, _pcd(data, opts)
57
57
  return true
58
58
  end
59
59
 
@@ -207,7 +207,7 @@ module RubySmart
207
207
  txt = str.dup
208
208
 
209
209
  # SPECIAL: prevent subject being parsed longer as the mask#length
210
- opts[:subject] = opts[:subject][0, (mask[:length] - 4 - mask[:char].length * 2)] if opts[:subject] && mask[:length] && opts[:subject].length > mask[:length]
210
+ opts[:subject] = opts[:subject].to_s[0, (mask[:length] - 4 - mask[:char].length * 2)] if opts[:subject] && mask[:length] && opts[:subject].to_s.length > mask[:length]
211
211
 
212
212
  str.scan(/%\{(\w+)\}/) do |mm|
213
213
  next unless mm.length > 0 && mm[0]
@@ -19,30 +19,25 @@ module RubySmart
19
19
 
20
20
  # set default formats
21
21
  self.formats = {
22
- # the ruby default's logging format (except to format the severity to 7-chars)
23
- default: {
24
- str: "%s, [%s #%d] %7s -- %s: %s",
25
- cb: lambda { |severity, time, progname, data| [severity[0], format_datetime(time), $$, severity, progname, msg2str(data)] }
22
+ # the ruby default's logging format -except the reformatted severity to 7-chars (instead of 5)
23
+ default: -> (severity, time, progname, data) {
24
+ _nl data2array(data, false).map { |str|
25
+ str == '' ? str : _clr(format('%s, [%s #%d] %7s -- %s: ', severity[0], format_datetime(time), $$, severity, progname), severity) + _declr(str)
26
+ }
26
27
  },
27
- # all provided args as array
28
- passthrough: {
29
- str: false, # no formatting
30
- cb: lambda { |*args| args }
31
- },
32
- # the plain data (msg) only, no severity, etc.
33
- plain: {
34
- str: false, # no formatting
35
- cb: lambda { |_severity, _time, _progname, data| data }
36
- },
37
- # special array data for memory-logging
38
- memory: {
39
- str: false, # no formatting
40
- cb: lambda { |severity, time, _progname, data| [severity.downcase.to_sym, time, data] }
41
- },
42
- # special datalog data with all provided data in additional brackets -> [data] [data] [data]
43
- datalog: {
44
- str: "[%7s] [%s] [#%d] [%s]",
45
- cb: lambda { |severity, time, _progname, data| [severity, format_datetime(time, true), $$, msg2str(data, true)] }
28
+
29
+ # simply 'passthrough' all args, without any formatting
30
+ passthrough: -> (*args) { args },
31
+
32
+ # just forward the formatted data, without any other args (no severity, time, progname)
33
+ plain: -> (_severity, _time, _progname, data) { _nl _declr(data.to_s) },
34
+
35
+ # specialized array for memory-logging
36
+ memory: -> (severity, time, _progname, data) { [severity.downcase.to_sym, time, data] },
37
+
38
+ # specialized string as datalog with every provided data in additional brackets -> [data] [data] [data]
39
+ datalog: -> (severity, time, _progname, data) {
40
+ _nl _declr(format('[#%d] [%s] [%s] [%s]', $$, format_datetime(time, true), severity, data2datalog(data)))
46
41
  }
47
42
  }
48
43
 
@@ -66,23 +61,16 @@ module RubySmart
66
61
  opts[:nl] = true if opts[:nl].nil?
67
62
  opts[:format] = :default if opts[:format].nil?
68
63
 
69
- @opts = opts
64
+ # only store required options
65
+ @opts = opts.slice(:nl, :format, :clr)
70
66
  end
71
67
 
72
- # standard call method - used to format provided terms
68
+ # standard call method - used to format provided params
73
69
  def call(severity, time, progname, data)
74
- if current_format_str
75
- str = current_format_str % instance_exec(severity, time, progname, data, &current_format_cb)
76
- str << "\n" if opts[:nl]
77
-
78
- # check for colorized output
79
- (opts[:clr] && SEVERITY_COLORS[severity]) ? str.send(SEVERITY_COLORS[severity]) : str
80
- else
81
- instance_exec(severity, time, progname, data, &current_format_cb)
82
- end
70
+ instance_exec(severity, time, progname, data, &current_formatter)
83
71
  end
84
72
 
85
- # returns all formats
73
+ # returns all class formats
86
74
  # @return [Hash] formats
87
75
  def formats
88
76
  self.class.formats
@@ -109,25 +97,72 @@ module RubySmart
109
97
  @opts.merge!(opts)
110
98
  end
111
99
 
112
- # clears auto-generated / cached data
100
+ # clears current formatter
113
101
  def clear!
114
- @current_format = nil
102
+ @current_formatter = nil
115
103
  end
116
104
 
117
105
  private
118
106
 
119
- def current_format
120
- @current_format ||= self.formats.key?(opts[:format]) ? self.formats[opts[:format]] : self.formats.values.first
107
+ # returns the current formatter callback
108
+ # @return [Proc]
109
+ def current_formatter
110
+ @current_formatter ||= self.formats[opts[:format]] || self.formats.values.first
111
+ end
112
+
113
+ # splits-up the provided data into a flat array.
114
+ # each will be split by new-line char +\n+.
115
+ # @param [Object] data
116
+ # @param [Boolean] allow_array
117
+ # @return [Array<String>]
118
+ def data2array(data, allow_array = true)
119
+ case data
120
+ when ::String
121
+ data.split("\n", -1)
122
+ when ::Array
123
+ # prevent to split-up arrays into multiple lines for this format:
124
+ # a array should +not+ be multi-lined
125
+ return data2array(data.inspect) unless allow_array
126
+
127
+ data.map { |item| data2array(item) }.flatten
128
+ when ::Exception
129
+ [
130
+ "exception: #{data.class}",
131
+ data2array(data.message),
132
+ data.backtrace || []
133
+ ].flatten
134
+ else
135
+ data2array(data.inspect)
136
+ end
121
137
  end
122
138
 
123
- def current_format_str
124
- current_format[:str]
139
+ # splits-up the provided data into a single string with each data item in brackets -> [data] [data] [data]
140
+ # @param [Object] data
141
+ # @return [String]
142
+ def data2datalog(data)
143
+ data2array(data).join('] [')
125
144
  end
126
145
 
127
- def current_format_cb
128
- current_format[:cb]
146
+ # formats the provided format string with args.
147
+ # @param [String] format
148
+ # @param [Array] args
149
+ # @return [String]
150
+ def format(format, *args)
151
+ format % args
129
152
  end
130
153
 
154
+ # def current_format_str
155
+ # current_format[:str]
156
+ # end
157
+ #
158
+ # def current_format_cb
159
+ # current_format[:cb]
160
+ # end
161
+ #
162
+ # def current_format_data(data)
163
+ # (current_format[:data] ? current_format[:data].(data) : data).to_s.split("\n")
164
+ # end
165
+
131
166
  def format_datetime(time, short = false)
132
167
  if short
133
168
  time.strftime("%Y-%m-%d %H:%M:%S")
@@ -136,16 +171,41 @@ module RubySmart
136
171
  end
137
172
  end
138
173
 
139
- def msg2str(msg, join = false)
140
- case msg
141
- when ::String
142
- msg
143
- when ::Array
144
- join ? msg.join('] [') : msg.inspect
145
- when ::Exception
146
- "#{ msg.message } (#{ msg.class })\n" + (msg.backtrace || []).join("\n")
174
+ # returns the formatted string with a new-line.
175
+ # depends, on the +:nl+ option.
176
+ # @param [String, Array] data
177
+ # @return [String]
178
+ def _nl(data)
179
+ # convert to string
180
+ data = data.join("\n") if data.is_a?(Array)
181
+
182
+ # check for +nl+ flag
183
+ return data unless opts[:nl]
184
+
185
+ data + "\n"
186
+ end
187
+
188
+ # returns the formatted string with a color-code
189
+ # depends, on the +:clr+ option.
190
+ # @param [String] str
191
+ # @param [String<uppercase>] severity
192
+ # @return [String]
193
+ def _clr(str, severity)
194
+ if opts[:clr] && (clr = SEVERITY_COLORS[severity])
195
+ str.send(clr)
196
+ else
197
+ _declr(str)
198
+ end
199
+ end
200
+
201
+ # de-colorizes provided string
202
+ # @param [String] str
203
+ # @return [String]
204
+ def _declr(str)
205
+ if opts[:clr]
206
+ str
147
207
  else
148
- msg.inspect
208
+ str.gsub(/\e\[[\d;]+m/, '')
149
209
  end
150
210
  end
151
211
  end
@@ -9,8 +9,8 @@ module RubySmart
9
9
 
10
10
  module VERSION
11
11
  MAJOR = 1
12
- MINOR = 0
13
- TINY = 0
12
+ MINOR = 1
13
+ TINY = 1
14
14
  PRE = nil
15
15
 
16
16
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -15,12 +15,13 @@ module RubySmart
15
15
  end
16
16
 
17
17
  def klass_logger_opts=(opts)
18
+ clear!
18
19
  class_variable_set('@@klass_logger_opts', opts)
19
20
  end
20
21
 
21
22
  # delegate new method to logger
22
23
  def new(*args)
23
- args = [nil, self.klass_logger_opts] if args.length == 0
24
+ args = [nil, self.klass_logger_opts.dup] if args.length == 0
24
25
  RubySmart::SimpleLogger::Logger.new(*args)
25
26
  end
26
27
 
@@ -3,6 +3,7 @@
3
3
  require_relative 'extensions/helper'
4
4
  require_relative 'extensions/logs'
5
5
  require_relative 'extensions/mask'
6
+ require_relative 'extensions/processed'
6
7
  require_relative 'extensions/scene'
7
8
  require_relative 'extensions/severity'
8
9
  require_relative 'extensions/simple_log'
@@ -25,6 +26,7 @@ module RubySmart
25
26
  include Extensions::Helper
26
27
  include Extensions::Logs
27
28
  include Extensions::Mask
29
+ include Extensions::Processed
28
30
  include Extensions::Scene
29
31
  include Extensions::Severity
30
32
  include Extensions::SimpleLog
@@ -36,7 +38,7 @@ module RubySmart
36
38
  attr_reader :logdev
37
39
 
38
40
  # defines a uniq key to parse the data
39
- PAYLOAD_DATA_KEY = :_data
41
+ PAYLOAD_DATA_KEY = :__data__
40
42
 
41
43
  # initialize new Logger
42
44
  # @param [Object, Symbol, nil] builtin
@@ -11,7 +11,7 @@ module RubySmart
11
11
  # > ================================================= [Debug] ================================================
12
12
  # > "DEBUGGED DATA" <- analyzed by awesome_print#ai method
13
13
  # > ==========================================================================================================
14
- base.scene :debug, { level: :debug, inspect: true, payload: [[:mask, ' [%{subject}] '], :_data, :mask] } do |data, subject = 'Debug', opts = {}|
14
+ base.scene :debug, { level: :debug, inspect: true, payload: [[:mask, ' [%{subject}] '], :__data__, :mask] } do |data, subject = 'Debug', opts = {}|
15
15
  self.log data, _scene_opt(:debug, { subject: subject }, opts)
16
16
  end
17
17
 
@@ -22,7 +22,7 @@ module RubySmart
22
22
  # > ================================================= [Info] =================================================
23
23
  # > DATA
24
24
  # > ==========================================================================================================
25
- base.scene :info, { level: :info, mask: { clr: :cyan }, payload: [[:mask, ' [%{subject}] '], :_data, :mask] } do |data, subject = 'Info', opts = {}|
25
+ base.scene :info, { level: :info, mask: { clr: :cyan }, payload: [[:mask, ' [%{subject}] '], :__data__, :mask] } do |data, subject = 'Info', opts = {}|
26
26
  self.log data, _scene_opt(:info, { subject: subject }, opts)
27
27
  end
28
28
 
@@ -33,7 +33,7 @@ module RubySmart
33
33
  # > ================================================= [Warn] =================================================
34
34
  # > DATA
35
35
  # > ==========================================================================================================
36
- base.scene :warn, { level: :warn, mask: { clr: :yellow }, payload: [[:mask, ' [%{subject}] '], :_data, :mask] } do |data, subject = 'Warn', opts = {}|
36
+ base.scene :warn, { level: :warn, mask: { clr: :yellow }, payload: [[:mask, ' [%{subject}] '], :__data__, :mask] } do |data, subject = 'Warn', opts = {}|
37
37
  self.log data, _scene_opt(:warn, { subject: subject }, opts)
38
38
  end
39
39
 
@@ -44,7 +44,7 @@ module RubySmart
44
44
  # > ================================================ [Error] =================================================
45
45
  # > DATA
46
46
  # > ==========================================================================================================
47
- base.scene :error, { level: :error, mask: { clr: :red }, payload: [[:mask, ' [%{subject}] '], :_data, :mask] } do |data, subject = 'Error', opts = {}|
47
+ base.scene :error, { level: :error, mask: { clr: :red }, payload: [[:mask, ' [%{subject}] '], :__data__, :mask] } do |data, subject = 'Error', opts = {}|
48
48
  self.log data, _scene_opt(:error, { subject: subject }, opts)
49
49
  end
50
50
 
@@ -55,7 +55,7 @@ module RubySmart
55
55
  # > ================================================ [Fatal] =================================================
56
56
  # > DATA
57
57
  # > ==========================================================================================================
58
- base.scene :fatal, { level: :fatal, mask: { clr: :bg_red }, payload: [[:mask, ' [%{subject}] '], :_data, :mask] } do |data, subject = 'Fatal', opts = {}|
58
+ base.scene :fatal, { level: :fatal, mask: { clr: :bg_red }, payload: [[:mask, ' [%{subject}] '], :__data__, :mask] } do |data, subject = 'Fatal', opts = {}|
59
59
  self.log data, _scene_opt(:fatal, { subject: subject }, opts)
60
60
  end
61
61
 
@@ -66,7 +66,7 @@ module RubySmart
66
66
  # > ================================================ [Success] ================================================
67
67
  # > DATA
68
68
  # > ===========================================================================================================
69
- base.scene :success, { level: :success, mask: { clr: :green }, payload: [[:mask, ' [%{subject}] '], :_data, :mask] } do |data, subject = 'Success', opts = {}|
69
+ base.scene :success, { level: :success, mask: { clr: :green }, payload: [[:mask, ' [%{subject}] '], :__data__, :mask] } do |data, subject = 'Success', opts = {}|
70
70
  self.log data, _scene_opt(:success, { subject: subject }, opts)
71
71
  end
72
72
 
@@ -273,15 +273,50 @@ module RubySmart
273
273
  perc = 0 if perc < 0
274
274
  perc = 100 if perc > 100
275
275
 
276
- pmask_left_length = (pmask_length * perc / 100)
276
+ pmask_left_length = (pmask_length * perc / 100)
277
277
  # reduce 1 char for the arrow '>'
278
- pmask_left_length -= 1 if pmask_left_length > 0
278
+ pmask_left_length -= 1 if pmask_left_length > 0
279
279
  pmask_right_length = pmask_length - pmask_left_length - 1
280
280
 
281
281
  progress_string = _clr(('=' * pmask_left_length) + '>', :green) + _clr('-' * pmask_right_length, :red)
282
- perc_string = perc.to_s.rjust(3,' ')
282
+ perc_string = perc.to_s.rjust(3, ' ')
283
283
  self.log nil, _scene_opt(:progress, { name: _clr(_lgth(name, 48), :cyan), perc: perc_string, progress: progress_string }, opts)
284
284
  end
285
+
286
+ # processed method
287
+ # log level @ info
288
+ # prints: a processed output with unicode box-chars (e.g. ║ )
289
+ #
290
+ # ╔ START job
291
+ # ╟ doing some cool log
292
+ # ╟ doing some extra log
293
+ # ╚ END job (duration: 4.34223)
294
+ base.scene :processed, { level: :info } do |name, opts = {}, &block|
295
+ # resolve the current process-level
296
+ lvl = processed_lvl(:up)
297
+
298
+ # start the timer, if it should - directly sets a timer key to be reused in the +:clear+ method
299
+ if (timer_key = (opts[:timer] ? "processed_#{lvl}" : nil))
300
+ self.timer(:start, timer_key) if timer_key
301
+ end
302
+
303
+ self.log("START - #{name}", _scene_opt(:processed, { pcd: :start }))
304
+
305
+ end_str = case block.call
306
+ when true
307
+ "END - SUCCESS"
308
+ when false
309
+ "END - FAILED"
310
+ else
311
+ "END - #{name}"
312
+ end
313
+
314
+ self.log("#{end_str} #{(timer_key ? "(duration: #{self.timer(:clear, timer_key, :humanized => true)})" : '')}", _scene_opt(:processed, { pcd: :end }))
315
+
316
+ processed_lvl(:down)
317
+
318
+ true
319
+ end
285
320
  end
286
321
  end
287
322
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_smart-simple_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Gonsior
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-29 00:00:00.000000000 Z
11
+ date: 2023-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_smart-support
@@ -124,6 +124,7 @@ files:
124
124
  - lib/ruby_smart/simple_logger/extensions/helper.rb
125
125
  - lib/ruby_smart/simple_logger/extensions/logs.rb
126
126
  - lib/ruby_smart/simple_logger/extensions/mask.rb
127
+ - lib/ruby_smart/simple_logger/extensions/processed.rb
127
128
  - lib/ruby_smart/simple_logger/extensions/scene.rb
128
129
  - lib/ruby_smart/simple_logger/extensions/severity.rb
129
130
  - lib/ruby_smart/simple_logger/extensions/simple_log.rb
@@ -160,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
161
  - !ruby/object:Gem::Version
161
162
  version: '0'
162
163
  requirements: []
163
- rubygems_version: 3.3.7
164
+ rubygems_version: 3.3.26
164
165
  signing_key:
165
166
  specification_version: 4
166
167
  summary: A simple, multifunctional logging library for Ruby.