ruby_smart-simple_logger 1.0.0

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 (36) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +38 -0
  3. data/.gitignore +25 -0
  4. data/.rspec +3 -0
  5. data/.yardopts +5 -0
  6. data/Gemfile +7 -0
  7. data/README.md +739 -0
  8. data/Rakefile +8 -0
  9. data/bin/console +8 -0
  10. data/bin/setup +8 -0
  11. data/docs/CHANGELOG.md +17 -0
  12. data/docs/CODE_OF_CONDUCT.md +84 -0
  13. data/docs/LICENSE.txt +21 -0
  14. data/lib/debugger.rb +20 -0
  15. data/lib/ruby_smart/simple_logger/core_ext/ruby/string.rb +43 -0
  16. data/lib/ruby_smart/simple_logger/devices/memory_device.rb +43 -0
  17. data/lib/ruby_smart/simple_logger/devices/multi_device.rb +69 -0
  18. data/lib/ruby_smart/simple_logger/devices/proc_device.rb +37 -0
  19. data/lib/ruby_smart/simple_logger/extensions/helper.rb +259 -0
  20. data/lib/ruby_smart/simple_logger/extensions/logs.rb +26 -0
  21. data/lib/ruby_smart/simple_logger/extensions/mask.rb +53 -0
  22. data/lib/ruby_smart/simple_logger/extensions/scene.rb +77 -0
  23. data/lib/ruby_smart/simple_logger/extensions/severity.rb +62 -0
  24. data/lib/ruby_smart/simple_logger/extensions/simple_log.rb +224 -0
  25. data/lib/ruby_smart/simple_logger/extensions/timer.rb +63 -0
  26. data/lib/ruby_smart/simple_logger/formatter.rb +153 -0
  27. data/lib/ruby_smart/simple_logger/gem_version.rb +23 -0
  28. data/lib/ruby_smart/simple_logger/klass_logger.rb +45 -0
  29. data/lib/ruby_smart/simple_logger/logger.rb +74 -0
  30. data/lib/ruby_smart/simple_logger/scenes.rb +288 -0
  31. data/lib/ruby_smart/simple_logger/version.rb +12 -0
  32. data/lib/ruby_smart/simple_logger.rb +25 -0
  33. data/lib/ruby_smart-simple_logger.rb +3 -0
  34. data/lib/simple_logger.rb +7 -0
  35. data/ruby_smart-simple_logger.gemspec +43 -0
  36. metadata +167 -0
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ module Extensions
6
+ module Mask
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ base.include InstanceMethods
10
+ base.class_eval do
11
+ # defines the default mask to be used
12
+ #
13
+ # @option [String] :char - the character to be used as mask
14
+ # @option [Integer] :length - the mask length (amount of mask chars be line)
15
+ # @option [Symbol] :clr - the color to be used by printing the mask
16
+ self.mask = { char: '=', length: 100, clr: :blue }
17
+ end
18
+ end
19
+
20
+ module ClassMethods
21
+ def mask
22
+ class_variable_get('@@mask')
23
+ end
24
+
25
+ def mask=(mask)
26
+ class_variable_set('@@mask', mask)
27
+ end
28
+ end
29
+
30
+ module InstanceMethods
31
+ # combined getter & setter for instances mask
32
+ # new mask is merged with existing
33
+ #
34
+ # @example
35
+ # mask
36
+ # > {char: '=', length: 100}
37
+ #
38
+ # mask(clr: :blue, length: 10)
39
+ # mask
40
+ # > {char: '=', length: 10, clr: :blue}
41
+ #
42
+ # @param [nil, Hash] mask
43
+ # @return [Hash] mask
44
+ def mask(mask = nil)
45
+ return (@mask || self.class.mask) if mask.nil?
46
+
47
+ @mask = (@mask || self.class.mask).merge(mask)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ module Extensions
6
+ module Scene
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ base.include InstanceMethods
10
+ base.class_eval do
11
+ # holds the default scene options
12
+ # [Hash] scenes
13
+ self.scenes = {}
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ # returns all registered scene default options
19
+ # @return [Hash] scenes
20
+ def scenes
21
+ class_variable_get('@@scenes')
22
+ end
23
+
24
+ # sets scene options
25
+ # @param [Hash] scenes
26
+ def scenes=(scenes)
27
+ class_variable_set('@@scenes', scenes)
28
+ end
29
+
30
+ # registers a new scene by provided key & options
31
+ # also defines this method by provided block
32
+ #
33
+ # @example
34
+ # scene :line, { level: :debug } do |data, opts = {}|
35
+ # self.log data, _scene_opt(:line, opts)
36
+ # end
37
+ #
38
+ # @param [Symbol] key - name of the scene method
39
+ # @param [Hash] opts - scene default options
40
+ # @param [Proc] block - scene block to define a appropriate method
41
+ # @return [Boolean] created result
42
+ def scene(key, opts = {}, &block)
43
+ # protect overwrite existing methods
44
+ # but allow all severities (levels)
45
+ return false if instance_methods.include?(key) && !self::LEVEL.key?(key)
46
+
47
+ # register scene default options
48
+ self.scenes[key] = opts
49
+
50
+ # define (or overwrite) this method, if a block was provided
51
+ define_method(key, &block) if block_given?
52
+
53
+ # returns success result
54
+ true
55
+ end
56
+ end
57
+
58
+ module InstanceMethods
59
+ # returns all registered scene default options
60
+ # @return [Hash] scenes
61
+ def scenes
62
+ self.class.scenes
63
+ end
64
+
65
+ private
66
+
67
+ # resolves scene options by provided key & merges them with additional options
68
+ # @param [Symbol] key
69
+ # @param [Array<Hash>] opts
70
+ def _scene_opt(key, *opts)
71
+ _opt((scenes[key] || {}), *opts)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module RubySmart
6
+ module SimpleLogger
7
+ module Extensions
8
+ module Severity
9
+ # include log level constants from original logger severity
10
+ include ::Logger::Severity
11
+
12
+ # add severity success (sub-kind of info = 1)
13
+ SUCCESS = 1.1
14
+
15
+ # creates an severity hash
16
+ # {
17
+ # 0 => 'DEBUG',
18
+ # 1 => 'INFO',
19
+ # 1.1 => 'SUCCESS',
20
+ # 2 => 'WARN',
21
+ # ...
22
+ # }
23
+ SEVERITIES = %w(DEBUG INFO SUCCESS WARN ERROR FATAL UNKNOWN).map { |sev| [const_get(sev), sev] }.to_h.freeze
24
+
25
+ # creates an level hash from SEVERITIES
26
+ LEVEL = SEVERITIES.reduce({}) { |m, (lvl, sev)| m[sev.downcase.to_sym] = lvl; m }.freeze
27
+
28
+ private
29
+
30
+ # overwrite original method to provide additional severities
31
+ #
32
+ # @example
33
+ # format_severity(1.1)
34
+ # > 'SUCCESS'
35
+ #
36
+ # @param [Numeric] severity
37
+ # @return [String (frozen)] severity name
38
+ def format_severity(severity)
39
+ self.class::SEVERITIES[severity] || 'UNKNOWN'
40
+ end
41
+
42
+ # resolves the severity level by provided Number, Symbol or String
43
+ #
44
+ # @param [Numeric, String, Symbol] sev - severity to resolve
45
+ # @return [Numeric,nil] severity level
46
+ def _level(sev)
47
+ # no sev provided
48
+ return UNKNOWN if sev.nil?
49
+ # numeric and valid
50
+ return sev if sev.is_a?(Numeric) && SEVERITIES.key?(sev)
51
+
52
+ key = sev.to_s.downcase.to_sym
53
+ # symbol (:success) and valid
54
+ return LEVEL[key] if LEVEL.key?(key)
55
+
56
+ # fallback to unknown
57
+ UNKNOWN
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,224 @@
1
+ # frozen_string_literal: false
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ module Extensions
6
+ module SimpleLog
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ base.include InstanceMethods
10
+ base.class_eval do
11
+ # defines the default inspector to be used
12
+ #
13
+ # :auto
14
+ self.inspector = :auto
15
+
16
+ # this will overwrite the default log method from the Ruby Logger
17
+ # but makes it still accessible through: #_log
18
+ alias_method :_log, :log
19
+ alias_method :log, :simple_log
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ def inspector
25
+ class_variable_get('@@inspector')
26
+ end
27
+
28
+ def inspector=(inspector)
29
+ class_variable_set('@@inspector', inspector)
30
+ end
31
+ end
32
+
33
+ module InstanceMethods
34
+ # Acts as the MAIN logging method and sends the data to the device
35
+ # - checks provided level before logging
36
+ # - creates & formats payload
37
+ #
38
+ # @param [Object] data
39
+ # @param [Hash] opts
40
+ # @option opts [Symbol, Numeric, String] :level - which level is logging
41
+ # @option opts [Array] :payload - payload for logging multilines (scene)
42
+ # @option opts [Symbol] :inspect - inspection method for data
43
+ # @option opts [Symbol] :formatter - formatter type
44
+ # @option opts [Hash] :mask - mask data
45
+ # @return [Boolean] logging result
46
+ def simple_log(data, opts = {})
47
+ # resolve & check level
48
+ level = _level(opts[:level])
49
+ return false if level < self.level
50
+
51
+ # prevents data from being transformed into payload
52
+ if ignore_payload? || opts[:payload].is_a?(FalseClass)
53
+ # prevent logging nil data
54
+ return false if data.nil?
55
+
56
+ add level, data
57
+ return true
58
+ end
59
+
60
+ # create a default payload, if nothing was provided
61
+ # :_ -> alias for log data
62
+ opts[:payload] ||= [self.class::PAYLOAD_DATA_KEY]
63
+
64
+ # create a default mask, if nothing was provided
65
+ opts[:mask] ||= self.mask
66
+
67
+ # create payloads and log each payload
68
+ # returns the payload boolean result
69
+ _payloads(opts.delete(:payload), opts, data) do |p|
70
+ add level, p
71
+ end
72
+
73
+ # returns true as logging result
74
+ true
75
+ end
76
+
77
+ # returns true if no payload should be created - instead the data will be send directly to the logdev
78
+ # forces the *simple_log* method to prevent building payloads from schemes - it just forwards the level & data to the logdev
79
+ #
80
+ # @return [Boolean]
81
+ def ignore_payload?
82
+ !!@ignore_payload
83
+ end
84
+
85
+ # resolve an inspector method for data inspection
86
+ # @return [Symbol, nil]
87
+ def inspector
88
+ # return or resolve inspector
89
+ @inspector ||= if self.class.inspector == :auto
90
+ # provide awesome_print support
91
+ Object.respond_to?(:ai) ? :ai : :inspect
92
+ else
93
+ self.class.inspector || :inspect
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ # parses each payload and creates a callback
100
+ #
101
+ # @param [Array] payloads
102
+ # @param [Hash] opts
103
+ # @param [Object] data
104
+ def _payloads(payloads, opts, data)
105
+ payloads.each do |payload|
106
+ # IMPORTANT: Do NOT remove this - prevents frozen string literal problem on other file sources
107
+ str = ''
108
+ if payload == self.class::PAYLOAD_DATA_KEY
109
+ # checks, if we should inspect the data
110
+ str << _parse_data(data, (opts[:inspect] ? (opts[:inspector] || self.inspector) : nil))
111
+ else
112
+ str << _parse_payload(payload, opts)
113
+ end
114
+
115
+ # always append newline - except it is forced excluded
116
+ str << "\n" if opts[:nl] != false
117
+
118
+ yield str
119
+ end
120
+
121
+ true
122
+ end
123
+
124
+ # just parses the data and calls an inspection method, if provided
125
+ #
126
+ # @param [Object] data
127
+ # @param [Symbol, nil] inspector - the inspection method to be called (e.g. :ai, :inspect, :to_s) - if not provided it tries to auto-resolve
128
+ # @return [String] stringified data
129
+ def _parse_data(data, inspector = nil)
130
+ (inspector ? data.send(inspector) : data).to_s
131
+ end
132
+
133
+ # parses a single payload with provided options
134
+ #
135
+ # @example
136
+ # _parse_payload(:mask, opts)
137
+ #
138
+ # _parse_payload({mask: ' [%{subject}] '}, opts)
139
+ #
140
+ # _parse_payload([:mask, ' [%{subject}] '], opts)
141
+ #
142
+ # @param [Array, Hash, Symbol, String] payload
143
+ # @param [Hash] opts
144
+ # @return [String] str
145
+ def _parse_payload(payload, opts)
146
+ # resolve type & additional sub-payloads (fraction)
147
+ payload = payload.to_a[0] if payload.is_a?(Hash)
148
+ type, fraction = (payload.is_a?(Array) ? payload : [payload, nil])
149
+
150
+ # prevent type case - type is the fraction
151
+ return type if type.is_a?(String)
152
+
153
+ case type
154
+ when :mask, :_mask
155
+ # resolve mask data
156
+ mask = self.mask.merge(opts[:mask])
157
+
158
+ # resolve text from fraction
159
+ # this could also be a payload
160
+ txt = _parse_payload({ _txt: fraction }, opts)
161
+
162
+ # clean possible colored text - sucks but necessary :(
163
+ txt.gsub!(/\e\[[\d;]+m?/, '')
164
+
165
+ # check for provided txt length - this will decide if it's a full-line mask
166
+ if txt.length == 0
167
+ _clr((mask[:char] * mask[:length]), mask[:clr])
168
+ else
169
+ # text size is to large for mask
170
+ txt = txt[0, (mask[:length] - 1)] if txt.length > mask[:length]
171
+ txt_lh = (txt.length / 2).floor
172
+
173
+ left_mask = mask[:char] * ((mask[:length] / 2) - txt_lh)
174
+ right_mask = mask[:char] * (mask[:length] - left_mask.length - txt.length)
175
+
176
+ _clr("#{left_mask}#{txt}#{right_mask}", mask[:clr])
177
+ # _clr(left_mask, mask[:clr]) + _clr(txt, mask[:clr]) + _clr(right_mask, mask[:clr])
178
+ end
179
+ when :txt, :_txt
180
+ txt = _parse_payload(fraction, opts)
181
+ txt = _parse_opts(txt, opts)
182
+ return '' if txt.length == 0
183
+
184
+ # force string to exact length
185
+ txt = txt.ljust(opts[:length], ' ')[0..(opts[:length] - 1)] if opts[:length]
186
+
187
+ _clr(txt, opts[:clr])
188
+ when :concat
189
+ fraction = [fraction] unless fraction.is_a?(Array)
190
+ fraction.map { |f| _parse_payload(f, opts) }.join
191
+ when :blank, :_blank
192
+ ''
193
+ else
194
+ # unknown type will be resolved by returning as string
195
+ fraction.nil? ? type.to_s : fraction.to_s
196
+ end
197
+ end
198
+
199
+ # parses wildcards ( %{xyz} ) from provided text by using the option keys
200
+ #
201
+ # @param [String] str
202
+ # @param [Hash] opts
203
+ # @return [String] parsed txt
204
+ def _parse_opts(str, opts = {})
205
+ mask = opts[:mask] || { length: 0 }
206
+ str = str.to_s
207
+ txt = str.dup
208
+
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]
211
+
212
+ str.scan(/%\{(\w+)\}/) do |mm|
213
+ next unless mm.length > 0 && mm[0]
214
+ m = mm[0].to_sym
215
+ txt.gsub!("%{#{m}}", (opts[m] ? opts[m].to_s : ''))
216
+ end
217
+
218
+ txt
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ module Extensions
6
+ module Timer
7
+ def timer(action, key = :default, opts = {})
8
+ @timers ||= {}
9
+ @timers[key] ||= {
10
+ start: nil,
11
+ stop: nil,
12
+ measure: 0
13
+ }
14
+
15
+ case action
16
+ when :restart
17
+ @timers[key][:start] = Time.now
18
+ @timers[key][:stop] = nil
19
+ @timers[key][:measure] = 0
20
+
21
+ true
22
+ when :start, :continue
23
+ @timers[key][:start] = Time.now
24
+ @timers[key][:stop] = nil
25
+
26
+ true
27
+ when :stop
28
+ return false if !@timers[key][:start] || @timers[key][:stop]
29
+ @timers[key][:stop] = Time.now
30
+ @timers[key][:measure] += @timers[key][:stop] - @timers[key][:start]
31
+
32
+ true
33
+ when :pause
34
+ return false if !@timers[key][:start] || @timers[key][:stop]
35
+
36
+ @timers[key][:measure] += Time.now - @timers[key][:start]
37
+ @timers[key][:start] = nil
38
+ @timers[key][:stop] = nil
39
+
40
+ true
41
+ when :clear
42
+ self.timer(:stop, key)
43
+ current = self.timer(:current, key)
44
+ @timers.delete(key)
45
+
46
+ # time_ago_in_words in only available if activesupport & actionview gems are loaded
47
+ if opts[:humanized] && respond_to?(:time_ago_in_words)
48
+ time_ago_in_words(current.to_i.seconds.from_now, include_seconds: true)
49
+ else
50
+ current
51
+ end
52
+ when :current
53
+ current = @timers[key][:measure]
54
+ current += Time.now - @timers[key][:start] if @timers[key][:start] && @timers[key][:stop].nil?
55
+ current
56
+ else
57
+ nil
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: false
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ class Formatter
6
+ class << self
7
+ # returns all registered formats
8
+ # @return [Hash] formats
9
+ def formats
10
+ class_variable_get('@@formats')
11
+ end
12
+
13
+ # sets formats
14
+ # @param [Hash] formats
15
+ def formats=(formats)
16
+ class_variable_set('@@formats', formats)
17
+ end
18
+ end
19
+
20
+ # set default formats
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)] }
26
+ },
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)] }
46
+ }
47
+ }
48
+
49
+ # defines the severity colors
50
+ SEVERITY_COLORS = {
51
+ 'DEBUG' => :blue,
52
+ 'INFO' => :cyan,
53
+ 'WARN' => :yellow,
54
+ 'ERROR' => :red,
55
+ 'FATAL' => :bg_red,
56
+ 'SUCCESS' => :green
57
+ }
58
+
59
+ # initialize with options
60
+ # @param [Hash] opts
61
+ # @option opts [Symbol] :format - define other format
62
+ # @option opts [Boolean] :nl - create newline after each call (default: true)
63
+ # @option opts [Boolean] :clr - colorizes the whole output (default: false)
64
+ def initialize(opts = {})
65
+ # set default opts
66
+ opts[:nl] = true if opts[:nl].nil?
67
+ opts[:format] = :default if opts[:format].nil?
68
+
69
+ @opts = opts
70
+ end
71
+
72
+ # standard call method - used to format provided terms
73
+ 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
83
+ end
84
+
85
+ # returns all formats
86
+ # @return [Hash] formats
87
+ def formats
88
+ self.class.formats
89
+ end
90
+
91
+ # combined getter & setter for options
92
+ # new options are merged with existing
93
+ #
94
+ # @example
95
+ # opts
96
+ # > {formatter: :default, nl: true}
97
+ #
98
+ # opts(nl: false, test: 45)
99
+ # opts
100
+ # > {formatter: :default, nl: false, test: 45}
101
+ #
102
+ # @param [nil, Hash] opts
103
+ # @return [Hash] opts
104
+ def opts(opts = nil)
105
+ return @opts if opts.nil?
106
+
107
+ clear!
108
+
109
+ @opts.merge!(opts)
110
+ end
111
+
112
+ # clears auto-generated / cached data
113
+ def clear!
114
+ @current_format = nil
115
+ end
116
+
117
+ private
118
+
119
+ def current_format
120
+ @current_format ||= self.formats.key?(opts[:format]) ? self.formats[opts[:format]] : self.formats.values.first
121
+ end
122
+
123
+ def current_format_str
124
+ current_format[:str]
125
+ end
126
+
127
+ def current_format_cb
128
+ current_format[:cb]
129
+ end
130
+
131
+ def format_datetime(time, short = false)
132
+ if short
133
+ time.strftime("%Y-%m-%d %H:%M:%S")
134
+ else
135
+ time.strftime("%Y-%m-%dT%H:%M:%S.%6N")
136
+ end
137
+ end
138
+
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")
147
+ else
148
+ msg.inspect
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ # Returns the version of the currently loaded module as a <tt>Gem::Version</tt>
6
+ def self.gem_version
7
+ Gem::Version.new VERSION::STRING
8
+ end
9
+
10
+ module VERSION
11
+ MAJOR = 1
12
+ MINOR = 0
13
+ TINY = 0
14
+ PRE = nil
15
+
16
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
17
+
18
+ def self.to_s
19
+ STRING
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: false
2
+
3
+ module RubySmart
4
+ module SimpleLogger
5
+ module KlassLogger
6
+ def self.extended(base)
7
+ base.send(:include, RubySmart::SimpleLogger::Logger::Severity)
8
+ base.class_eval do
9
+ self.klass_logger_opts = {}
10
+ end
11
+ end
12
+
13
+ def klass_logger_opts
14
+ class_variable_get('@@klass_logger_opts')
15
+ end
16
+
17
+ def klass_logger_opts=(opts)
18
+ class_variable_set('@@klass_logger_opts', opts)
19
+ end
20
+
21
+ # delegate new method to logger
22
+ def new(*args)
23
+ args = [nil, self.klass_logger_opts] if args.length == 0
24
+ RubySmart::SimpleLogger::Logger.new(*args)
25
+ end
26
+
27
+ def klass_logger
28
+ @klass_logger ||= self.new
29
+ end
30
+
31
+ def clear!
32
+ @klass_logger = nil
33
+ end
34
+
35
+ def method_missing(name, *args, &block)
36
+ return self.klass_logger.send(name, *args) if self.klass_logger.respond_to? name
37
+ super
38
+ end
39
+
40
+ def respond_to?(method_name, _include_private = false)
41
+ self.klass_logger.respond_to? method_name
42
+ end
43
+ end
44
+ end
45
+ end