ruby_smart-simple_logger 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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