extended_logger 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f455250170001f45e0124012bea062f08d8d072
4
- data.tar.gz: 783a45d09ed579227e8b343e3cd3732fae593fab
3
+ metadata.gz: 829c2ba09350eb621bb0694a0c099c7b392edf20
4
+ data.tar.gz: 43f5a2da899103fd2d42147909723229571a8d8c
5
5
  SHA512:
6
- metadata.gz: b5e3b1f15f2f8d7caa9416cc4c58e76296278daec801a54444203ac47b6685ec54961e7cfa1752f1b5fd6ee322d3a709701dfe892172ef41e5c64a4be8a1bc89
7
- data.tar.gz: 3df9a339830cf81d580f610da7fa88053c7b30cb559d960759ed709b56c28d25e7abc3482d3bed3ddacf0794091a6a320501b6bb7c19e4e75093bdfa982d3411
6
+ metadata.gz: 5c1b55af38672df94b92523b188bf26c36d97e333a225aed93d33c2901a043a0fab5e291749ecfdd91f3fca86e36fec9fd90cbe650e6039ab65cfb181026bd53
7
+ data.tar.gz: ee6f7448f2866dc7a4f5f23e6c92bec98cdbbd9ca34dc96efc93336961a68d2731fc29d7826481b5d092206f1e42c31fe4c5af67f6671232a7ecaf6ea8658d22
@@ -1,10 +1,15 @@
1
- require 'logger'
1
+ require 'English'
2
2
  require 'time'
3
3
 
4
- require 'extended_logger/color_scheme'
5
- require 'extended_logger/configure_levels'
6
- require 'extended_logger/formatter'
7
- require 'extended_logger/logger_substitute'
8
- require 'extended_logger/per_class_logging'
9
-
10
- require 'extended_logger/extended_logger'
4
+ require_relative './extended_logger/color_scheme'
5
+ require_relative './extended_logger/defaults'
6
+ require_relative './extended_logger/define'
7
+ require_relative './extended_logger/extended_logger'
8
+ require_relative './extended_logger/level'
9
+ require_relative './extended_logger/level/set'
10
+ require_relative './extended_logger/message'
11
+ require_relative './extended_logger/rule'
12
+ require_relative './extended_logger/serializer'
13
+ require_relative './extended_logger/serializer/text_formatter'
14
+ require_relative './extended_logger/sink'
15
+ require_relative './extended_logger/verbosity_threshold'
@@ -1,146 +1,118 @@
1
1
  class ExtendedLogger
2
2
  class ColorScheme
3
- attr_reader :map
3
+ def self.build values=nil
4
+ values ||= {}
4
5
 
5
- def initialize map
6
- @map = map
6
+ instance = new
7
+ Palette.apply values, instance
8
+ instance
7
9
  end
8
10
 
9
- def self.build symbol_map
10
- code_map = {}
11
+ def colorize message
12
+ value = get message.level.name
13
+ message.prose = value.colorize message.prose
14
+ end
11
15
 
12
- symbol_map.each do |label, (fg_sym, bg_sym)|
13
- fg = Colors.index fg_sym
14
- bg = Colors.index bg_sym
16
+ def get level_name
17
+ table[level_name]
18
+ end
19
+ alias_method :[], :get
15
20
 
16
- code_map[label] = [fg, bg]
17
- end
21
+ def reset
22
+ "\e[0m"
23
+ end
18
24
 
19
- new code_map
25
+ def set level_name, fg: nil, bg: nil
26
+ value = get level_name
27
+ value.fg = fg if fg
28
+ value.bg = bg if bg
20
29
  end
21
30
 
22
- def color_code code
23
- if code
24
- code.to_s 16
25
- else
26
- '?'.freeze
31
+ def table
32
+ @table ||= Hash.new do |hash, level_name|
33
+ hash[level_name] = Value.new
27
34
  end
28
35
  end
29
36
 
30
- def colorize severity, text
31
- text = text.dup
37
+ None = self.new
32
38
 
33
- fg, bg = map[severity]
39
+ module Palette
40
+ def self.apply values, color_scheme
41
+ values.each do |level_name, values|
42
+ values = { :fg => values } if values.is_a? Symbol
34
43
 
35
- if bg
36
- if bg > 8
37
- text.insert 0, "\e[4#{bg - 8}m"
38
- else
39
- text.insert 0, "\e[4#{bg}m"
40
- end
41
- end
44
+ values.each_key do |target|
45
+ color_name = values[target]
46
+ values[target] = Palette.get color_name
47
+ end
42
48
 
43
- if fg
44
- if fg > 8
45
- text.insert 0, "\e[1;3#{fg - 8}m"
46
- else
47
- text.insert 0, "\e[0;3#{fg}m"
49
+ color_scheme.set level_name, **values
48
50
  end
49
51
  end
50
52
 
51
- if fg or bg
52
- text << "\e[0m"
53
+ def self.get name
54
+ names.index name
53
55
  end
54
56
 
55
- text
57
+ def self.names
58
+ %i(
59
+ black
60
+ red
61
+ green
62
+ brown
63
+ blue
64
+ magenta
65
+ cyan
66
+ gray
67
+ dark_gray
68
+ bright_red
69
+ bright_green
70
+ yellow
71
+ bright_blue
72
+ bright_magenta
73
+ bright_cyan
74
+ white
75
+ )
76
+ end
56
77
  end
57
78
 
58
- def dump
59
- output = ''.encode 'US-ASCII'
79
+ Value = Struct.new :fg, :bg do
80
+ def colorize prose
81
+ return prose if fg.nil? and bg.nil?
60
82
 
61
- map.each do |level, (fg, bg)|
62
- fg_code = color_code fg
63
- bg_code = color_code bg
64
-
65
- output << ',' unless output.empty?
66
- output << "#{level}=#{fg_code};#{bg_code}"
83
+ new_prose = String.new
84
+ new_prose << escape_code
85
+ new_prose << prose
86
+ new_prose << reset
87
+ new_prose
67
88
  end
68
89
 
69
- output
70
- end
71
-
72
- def levels
73
- map.keys
74
- end
90
+ def escape_code
91
+ string = String.new "\e["
75
92
 
76
- def self.decode code
77
- return if code == '?'.freeze
78
- code.to_i 16
79
- end
80
-
81
- def self.load data
82
- map = {}
93
+ if fg
94
+ brightness, fg_color = fg.divmod 8
95
+ string << brightness.to_s
96
+ string << ';3'
97
+ string << fg_color.to_s
98
+ end
83
99
 
84
- values = data.split ','.freeze
100
+ if bg
101
+ string << ';' if fg
85
102
 
86
- values.each do |assignment|
87
- match_data = AssignmentPattern.match assignment
103
+ _, bg_color = bg.divmod 8
104
+ string << '4'
105
+ string << bg_color.to_s
106
+ end
88
107
 
89
- label = match_data[:label]
90
- fg = decode match_data[:fg_code]
91
- bg = decode match_data[:bg_code]
108
+ string << 'm'
92
109
 
93
- map[label] = [fg, bg]
110
+ string
94
111
  end
95
112
 
96
- new map
97
- end
98
-
99
- def self.resolve input
100
- case input
101
- when String then self.load input
102
- when true then Default
103
- else raise ArgumentError, "Cannot resolve color scheme for #{input.inspect}"
113
+ def reset
114
+ "\e[0m"
104
115
  end
105
116
  end
106
-
107
- AssignmentPattern = %r{\A
108
- (?<label>[_A-Z]+)
109
- =
110
- (?<fg_code>[?[:xdigit:]])+
111
- ;
112
- (?<bg_code>[?[:xdigit:]]+)\z
113
- }nx
114
-
115
- Colors = %i(
116
- black
117
- red
118
- green
119
- brown
120
- blue
121
- magenta
122
- cyan
123
- gray
124
-
125
- dark_gray
126
- bright_red
127
- bright_green
128
- yellow
129
- bright_blue
130
- bright_magenta
131
- bright_cyan
132
- white
133
- )
134
-
135
- Default = self.build(
136
- 'DEBUG' => [:cyan, nil],
137
- 'INFO' => [nil, nil],
138
- 'WARN' => [:brown, nil],
139
- 'ERROR' => [:red, nil],
140
- 'FATAL' => [:white, :red],
141
- 'ANY' => [:white, :blue],
142
- )
143
-
144
- Null = self.new Hash.new
145
117
  end
146
118
  end
@@ -1,48 +1,221 @@
1
+ require 'logger'
2
+
1
3
  class ExtendedLogger
2
4
  module Controls
3
5
  module ColorSchemes
4
- def self.normal_verbose
5
- color_scheme = ExtendedLogger::ColorScheme.build(
6
- 'NORMAL' => [:gray, :none],
7
- 'VERBOSE' => [:none, :gray],
6
+ def self.example
7
+ ColorScheme.build(
8
+ :verbose => { :fg => :black, :bg => :white },
9
+ :normal => { :fg => :white, :bg => :black },
8
10
  )
9
11
  end
12
+
13
+ module None
14
+ def self.value
15
+ ColorScheme::None
16
+ end
17
+ end
10
18
  end
11
19
 
12
- module Loggers
13
- class NormalVerbose < ExtendedLogger
14
- self.levels = %w(VERBOSE NORMAL)
20
+ module Formatters
21
+ module Plain
22
+ def self.value
23
+ -> message do
24
+ "#{message.level} -- #{message.prose}"
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ module Label
31
+ def self.value
32
+ 'SomeClass'
33
+ end
34
+ end
35
+
36
+ module Levels
37
+ def self.ruby_logger
38
+ Set.ruby_logger.get :info
39
+ end
40
+
41
+ def self.value label=nil
42
+ label ||= :normal
43
+ Set.get label
44
+ end
45
+
46
+ module Names
47
+ def self.ruby_logger
48
+ %i(debug info warn error fatal)
49
+ end
50
+
51
+ def self.value
52
+ %i(verbose normal)
53
+ end
54
+ end
55
+
56
+ module Set
57
+ def self.get name
58
+ example[name]
59
+ end
60
+
61
+ def self.ruby_logger
62
+ names = Names.ruby_logger
63
+ Level::Set.build names
64
+ end
65
+
66
+ def self.example
67
+ names = Names.value
68
+ Level::Set.build names, :default => :normal
69
+ end
70
+ end
71
+ end
72
+
73
+ class Logger < ExtendedLogger.define
74
+ def self.example device=nil
75
+ device ||= StringIO.new
76
+
77
+ instance = build device
78
+ instance.clock = Time::Clock
79
+ instance
15
80
  end
16
81
  end
17
82
 
18
83
  module Messages
19
- def self.multiline
20
- "crcrlf\r\r\n" +
21
- "crlf\r\n" +
22
- "cr\r" +
23
- "lf\n" +
24
- "\n\n" +
25
- " \n" +
26
- "\t\n" +
27
- " \t\n" +
28
- "\n"
84
+ def self.example prose: nil, level: nil, label: nil, time: nil
85
+ prose ||= Prose.example
86
+ level ||= Levels.value
87
+ time ||= Time.reference
88
+
89
+ if prose.is_a? Proc
90
+ block = prose
91
+ else
92
+ block = ->{ prose }
93
+ end
94
+
95
+ Message.new block, level, time, label
96
+ end
97
+
98
+ module Label
99
+ def self.value label=nil
100
+ label ||= Control::Label.value
101
+
102
+ Messages.example label: label
103
+ end
104
+ end
105
+
106
+ module RubyLogger
107
+ def self.value label=nil
108
+ level = Level.new :info
109
+
110
+ Messages.example level: level, label: label
111
+ end
29
112
  end
30
113
  end
31
114
 
32
115
  module Output
33
- def self.multiline
34
- <<-TEXT
35
- N, [2000-01-01##{$$}] NORMAL -- : crcrlf\\r\\r\\n
36
- N, [2000-01-01##{$$}] NORMAL -- : crlf\\r\\n
37
- N, [2000-01-01##{$$}] NORMAL -- : cr\\r
38
- N, [2000-01-01##{$$}] NORMAL -- : lf\\n
39
- N, [2000-01-01##{$$}] NORMAL -- : \\n
40
- N, [2000-01-01##{$$}] NORMAL -- : \\n
41
- N, [2000-01-01##{$$}] NORMAL -- : \\n
42
- N, [2000-01-01##{$$}] NORMAL -- : \\t\\n
43
- N, [2000-01-01##{$$}] NORMAL -- : \\t\\n
44
- N, [2000-01-01##{$$}] NORMAL -- : \\n
45
- TEXT
116
+ def self.value prose=nil
117
+ prose ||= Prose.example
118
+ "NORMAL -- #{prose}\n"
119
+ end
120
+
121
+ module Colorized
122
+ def self.value prose=nil
123
+ prose ||= Prose.example
124
+ colorized_prose = "\e[1;37;40m#{prose}\e[0m"
125
+
126
+ Output.value colorized_prose
127
+ end
128
+ end
129
+
130
+ module MultipleLines
131
+ def self.value
132
+ "NORMAL -- Multiple\nNORMAL -- line\nNORMAL -- message\n"
133
+ end
134
+ end
135
+
136
+ module RubyLogger
137
+ def self.log_format
138
+ @log_format ||= ::Logger::Formatter.new
139
+ end
140
+
141
+ def self.value progname=nil
142
+ severity = 'INFO'
143
+ time = Time::Clock.now
144
+ message = Prose.example
145
+
146
+ log_format.(severity, time, progname, message)
147
+ end
148
+ end
149
+
150
+ module RuleApplied
151
+ def self.value
152
+ prose = Prose.example
153
+ prose = prose.upcase
154
+
155
+ Output.value prose
156
+ end
157
+ end
158
+ end
159
+
160
+ module Prose
161
+ def self.example
162
+ SingleLine.value
163
+ end
164
+
165
+ module EscapeCodes
166
+ def self.value
167
+ "\t\r"
168
+ end
169
+ end
170
+
171
+ module MultipleLines
172
+ def self.value
173
+ "Multiple\nline\nmessage"
174
+ end
175
+ end
176
+
177
+ module SingleLine
178
+ def self.value
179
+ "Some log message"
180
+ end
181
+ end
182
+ end
183
+
184
+ module Rule
185
+ class Example
186
+ include ExtendedLogger::Rule
187
+
188
+ def call message
189
+ message.prose = message.prose.upcase
190
+ message
191
+ end
192
+ end
193
+ end
194
+
195
+ module Sink
196
+ def self.example device=nil, format: nil, rules: nil
197
+ format ||= Controls::Formatters::Plain.value
198
+ device ||= StringIO.new
199
+ levels = Controls::Levels::Set.example
200
+
201
+ ExtendedLogger::Sink.build(
202
+ device,
203
+ format: format,
204
+ levels: levels,
205
+ rules: rules,
206
+ )
207
+ end
208
+ end
209
+
210
+ module Time
211
+ module Clock
212
+ def self.now
213
+ Time.reference
214
+ end
215
+ end
216
+
217
+ def self.reference
218
+ ::Time.new 2000
46
219
  end
47
220
  end
48
221
  end
@@ -0,0 +1,21 @@
1
+ class ExtendedLogger
2
+ module Defaults
3
+ def self.color_scheme
4
+ ColorScheme::None
5
+ end
6
+
7
+ def self.log_format
8
+ @log_format ||= -> message do
9
+ time = message.time.strftime '%Y-%m-%dT%H:%M:%S.%6N'
10
+ level = message.level.to_s.rjust 5
11
+
12
+ "#{message.level.abbreviation}, [#{time} ##{$$}] #{level} -- #{message.label}: #{message.prose}"
13
+ end
14
+ end
15
+
16
+ def self.levels
17
+ level_names = %i(debug info warn error fatal)
18
+ Level::Set.build level_names
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ class ExtendedLogger
2
+ def self.define levels=nil, **defaults
3
+ levels ||= Defaults.levels
4
+
5
+ subclass = Class.new self
6
+ Define.(subclass, levels)
7
+ subclass
8
+ end
9
+
10
+ class Define
11
+ attr_reader :levels
12
+ attr_reader :subclass
13
+
14
+ def initialize subclass, levels, **defaults
15
+ @levels = levels
16
+ @subclass = subclass
17
+ end
18
+
19
+ def self.call *arguments
20
+ instance = new *arguments
21
+ instance.()
22
+ end
23
+
24
+ def call
25
+ levels = self.levels
26
+ subclass.send :define_method, :levels do levels end
27
+
28
+ levels.each do |level|
29
+ method_name = level.name
30
+
31
+ subclass.send :define_method, method_name do |*arguments, &block|
32
+ add level, *arguments, &block
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,46 +1,56 @@
1
1
  class ExtendedLogger
2
- include LoggerSubstitute
3
- extend PerClassLogging
2
+ attr_writer :clock
3
+ attr_accessor :label
4
+ attr_writer :level
5
+ attr_reader :sink
4
6
 
5
- attr_accessor :always_interpolate
6
- attr_writer :color_scheme
7
-
8
- def self.build io, always_interpolate: nil, color_scheme: nil
9
- instance = new io
10
-
11
- instance.always_interpolate = true if always_interpolate
7
+ def initialize sink
8
+ @sink = sink
9
+ end
12
10
 
13
- if color_scheme and io.tty?
14
- color_scheme = ColorScheme.resolve color_scheme
15
- instance.color_scheme = color_scheme
16
- end
11
+ def self.build *arguments
12
+ sink = Sink.build *arguments
17
13
 
14
+ instance = new sink
18
15
  instance
19
16
  end
20
17
 
21
- def add severity, *, &block
22
- if always_interpolate and severity < level
23
- block.() if block
24
- end
18
+ def add level, prose=nil, label: nil, &block
19
+ block ||= ->{ prose }
20
+ label ||= self.label
21
+
22
+ time = clock.now
25
23
 
26
- super
24
+ message = Message.new block, level, time, label
25
+
26
+ sink << message
27
+ end
28
+
29
+ def clock
30
+ @clock ||= Time
27
31
  end
28
32
 
29
- def color_scheme
30
- @color_scheme ||= ColorScheme::Null
33
+ def device
34
+ sink.device
31
35
  end
32
36
 
33
- def format severity, *arguments
34
- formatted_message = super
35
- color_scheme.colorize severity, formatted_message
37
+ def level
38
+ @level ||= levels.default
36
39
  end
37
40
 
38
- def self.levels= levels
39
- ConfigureLevels.configure_levels self, levels
41
+ def level= reference
42
+ @level = levels.resolve reference
40
43
  end
41
44
 
42
- # ExtendedLogger::Logger can be used in place of ::Logger
43
- class Logger < ExtendedLogger
44
- self.levels = %w(DEBUG INFO WARN ERROR FATAL)
45
+ module Assertions
46
+ def nothing_written?
47
+ written? ''
48
+ end
49
+
50
+ def written? expected_data
51
+ device.rewind
52
+ actual_data = device.read
53
+ actual_data == expected_data
54
+ end
45
55
  end
46
56
  end
@@ -0,0 +1,25 @@
1
+ class ExtendedLogger
2
+ class Level < Struct.new :name, :prev, :next
3
+ include Comparable
4
+
5
+ def <=> other
6
+ self.ordinal <=> other.ordinal
7
+ end
8
+
9
+ def abbreviation
10
+ label[0]
11
+ end
12
+
13
+ def ordinal
14
+ @ordinal ||= if prev then prev.ordinal + 1 else 0 end
15
+ end
16
+
17
+ def label
18
+ @label ||= name.to_s.upcase
19
+ end
20
+
21
+ def to_s
22
+ label
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,64 @@
1
+ class ExtendedLogger
2
+ class Level
3
+ class Set
4
+ attr_reader :default_name
5
+ attr_reader :names
6
+
7
+ def initialize names, default_name=nil
8
+ @default_name = default_name
9
+ @names = names
10
+ end
11
+
12
+ def self.build names, default: nil
13
+ default ||= names.first
14
+ new names, default
15
+ end
16
+
17
+ def == other
18
+ default_name == other.default_name and
19
+ names == other.names
20
+ end
21
+
22
+ def build_index
23
+ hash = {}
24
+
25
+ names.reduce nil do |previous_level, name|
26
+ level = Level.new name
27
+
28
+ level.prev = previous_level
29
+ previous_level.next = level if previous_level
30
+
31
+ hash[name] = level
32
+ level
33
+ end
34
+
35
+ hash
36
+ end
37
+
38
+ def default
39
+ get default_name
40
+ end
41
+
42
+ def each &block
43
+ index.each_value &block
44
+ end
45
+
46
+ def get name
47
+ index[name]
48
+ end
49
+ alias_method :[], :get
50
+
51
+ def index
52
+ @index ||= build_index
53
+ end
54
+
55
+ def resolve reference
56
+ if reference.is_a? Symbol
57
+ get reference
58
+ else
59
+ get reference.name
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,13 @@
1
+ class ExtendedLogger
2
+ Message = Struct.new :block, :level, :time, :label do
3
+ attr_writer :prose
4
+
5
+ def inspect
6
+ "#<ExtendedLogger::Message prose=#{prose.inspect}, level=#{level}, time=#{time.iso8601}, label=#{label.inspect}>"
7
+ end
8
+
9
+ def prose
10
+ @prose ||= block.()
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class ExtendedLogger
2
+ module Rule
3
+ def call _
4
+ fail "Not implemented"
5
+ end
6
+
7
+ module Assertions
8
+ def filter? message
9
+ if self.(message) then false else true end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ class ExtendedLogger
2
+ class Serializer
3
+ attr_writer :color_scheme
4
+ attr_reader :log_format
5
+
6
+ def initialize log_format
7
+ @log_format = log_format
8
+ end
9
+
10
+ def self.build log_format: nil, color_scheme: nil
11
+ log_format ||= Defaults.log_format
12
+
13
+ instance = new log_format
14
+ instance.color_scheme = color_scheme if color_scheme
15
+ instance
16
+ end
17
+
18
+ def call message
19
+ messages = format_text message
20
+
21
+ messages.reduce String.new do |string, message|
22
+ color_scheme.colorize message
23
+
24
+ string << log_format.(message)
25
+ string << "\n"
26
+ string
27
+ end
28
+ end
29
+
30
+ def color_scheme
31
+ @color_scheme ||= ColorScheme::None
32
+ end
33
+
34
+ def format_text message
35
+ lines = TextFormatter.(message.prose)
36
+
37
+ lines.map do |line|
38
+ line_message = message.dup
39
+ line_message.prose = line
40
+ line_message
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,37 @@
1
+ class ExtendedLogger
2
+ class Serializer
3
+ class TextFormatter
4
+ attr_reader :prose
5
+
6
+ def initialize prose
7
+ @prose = prose
8
+ end
9
+
10
+ def self.call prose
11
+ instance = new prose
12
+ instance.()
13
+ end
14
+
15
+ def call
16
+ return %w(<empty message>) if prose.nil? or prose.empty?
17
+
18
+ lines.map do |line|
19
+ line.chomp! if line.match %r{(?<!\r)\n}
20
+
21
+ if line.empty?
22
+ "\\n"
23
+ else
24
+ line = line.inspect
25
+ line.slice! 0, 1
26
+ line.slice! -1, 1
27
+ line
28
+ end
29
+ end
30
+ end
31
+
32
+ def lines
33
+ @lines ||= prose.each_line $INPUT_RECORD_SEPARATOR
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,50 @@
1
+ class ExtendedLogger
2
+ class Sink
3
+ attr_reader :device
4
+ attr_reader :levels
5
+ attr_writer :rules
6
+ attr_reader :serializer
7
+
8
+ def initialize device, levels, serializer
9
+ @device = device
10
+ @levels = levels
11
+ @serializer = serializer
12
+ end
13
+
14
+ def self.build device=nil, format: nil, levels: nil, rules: nil, serializer: nil
15
+ device ||= $stderr
16
+ levels ||= Defaults.levels
17
+ serializer ||= Serializer.build log_format: format
18
+
19
+ instance = new device, levels, serializer
20
+ instance.rules = rules if rules
21
+ instance
22
+ end
23
+
24
+ def << message
25
+ message = apply_rules message
26
+
27
+ verbosity_threshold.(message) or return
28
+
29
+ output = serializer.(message)
30
+
31
+ device.write output
32
+ end
33
+
34
+ def apply_rules message
35
+ rules.reduce message do |message, rule|
36
+ rule.(message) or return
37
+ end
38
+ end
39
+
40
+ def rules
41
+ @rules ||= []
42
+ end
43
+
44
+ def verbosity_threshold
45
+ @verbosity_threshold ||= VerbosityThreshold.new levels.default
46
+ end
47
+
48
+ Assertions = ExtendedLogger::Assertions
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ class ExtendedLogger
2
+ class VerbosityThreshold
3
+ include Rule
4
+
5
+ attr_accessor :level
6
+
7
+ def initialize level
8
+ @level = level
9
+ end
10
+
11
+ def call message
12
+ if message.level >= level
13
+ message
14
+ end
15
+ end
16
+
17
+ def lower
18
+ if level.prev
19
+ self.level = level.prev
20
+ end
21
+ end
22
+
23
+ def raise
24
+ if level.next
25
+ self.level = level.next
26
+ end
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,19 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extended_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Ladd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-16 00:00:00.000000000 Z
12
- dependencies: []
13
- description: 'An extended logger that provides a (mostly) substitutable alternative
14
- to ruby''s built in +Logger+ class. A number of useful extensions are provided,
15
- including colorized output, the ability to define custom log levels, multi-line
16
- formatting, and per-class logging.
11
+ date: 2016-02-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: test_bench
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: 'A logging library that provides more feature''s than ruby''s built in
28
+ logger; namely per-class logging, color schemes, and custom log levels.
17
29
 
18
30
  '
19
31
  email: nathanladd+github@gmail.com
@@ -23,12 +35,18 @@ extra_rdoc_files: []
23
35
  files:
24
36
  - lib/extended_logger.rb
25
37
  - lib/extended_logger/color_scheme.rb
26
- - lib/extended_logger/configure_levels.rb
27
38
  - lib/extended_logger/controls.rb
39
+ - lib/extended_logger/defaults.rb
40
+ - lib/extended_logger/define.rb
28
41
  - lib/extended_logger/extended_logger.rb
29
- - lib/extended_logger/formatter.rb
30
- - lib/extended_logger/logger_substitute.rb
31
- - lib/extended_logger/per_class_logging.rb
42
+ - lib/extended_logger/level.rb
43
+ - lib/extended_logger/level/set.rb
44
+ - lib/extended_logger/message.rb
45
+ - lib/extended_logger/rule.rb
46
+ - lib/extended_logger/serializer.rb
47
+ - lib/extended_logger/serializer/text_formatter.rb
48
+ - lib/extended_logger/sink.rb
49
+ - lib/extended_logger/verbosity_threshold.rb
32
50
  homepage: https://github.com/ntl/extended-logger
33
51
  licenses:
34
52
  - MIT
@@ -1,35 +0,0 @@
1
- class ExtendedLogger
2
- module ConfigureLevels
3
- def self.configure_levels target, labels
4
- levels = []
5
-
6
- labels.each_with_index do |label, severity|
7
- level_name = label.upcase
8
- levels << level_name
9
-
10
- configure_level target, level_name, severity
11
- end
12
-
13
- target.const_set :UNKNOWN, labels.size
14
-
15
- levels.each &:freeze
16
- levels.freeze
17
-
18
- target.send :define_singleton_method, :levels do levels end
19
- end
20
-
21
- def self.configure_level target, level_name, severity
22
- method_name = level_name.downcase
23
-
24
- target.send :define_method, "#{method_name}?" do
25
- level <= severity
26
- end
27
-
28
- target.send :define_method, method_name do |progname=nil, &block|
29
- add severity, nil, progname, &block
30
- end
31
-
32
- target.const_set level_name, severity
33
- end
34
- end
35
- end
@@ -1,49 +0,0 @@
1
- class ExtendedLogger
2
- class Formatter
3
- BlankLine = /\A[[:blank:]]*\z/n
4
- LineEnding = /[[:blank:]]*\r*[\r\n]/n
5
- Separator = "\n".freeze
6
-
7
- attr_accessor :internal_formatter
8
-
9
- def initialize internal_formatter
10
- @internal_formatter = internal_formatter
11
- end
12
-
13
- def self.build
14
- internal_formatter = ::Logger::Formatter.new
15
- new internal_formatter
16
- end
17
-
18
- def call *arguments
19
- format internal_formatter, *arguments
20
- end
21
-
22
- def datetime_format= format
23
- internal_formatter.datetime_format = format
24
- end
25
-
26
- def format formatter, *arguments, message
27
- message = message.to_s
28
- message = message.dup
29
-
30
- if BlankLine.match message.to_s
31
- formatter.(*arguments, '(empty log message)'.freeze)
32
- else
33
- message.gsub! LineEnding do |line_ending|
34
- quoted = line_ending.inspect[1...-1]
35
- quoted << Separator
36
- quoted
37
- end
38
-
39
- lines = message.split Separator
40
-
41
- lines.reduce String.new do |output, line|
42
- formatted_line = formatter.(*arguments, line)
43
- output << formatted_line
44
- output
45
- end
46
- end
47
- end
48
- end
49
- end
@@ -1,97 +0,0 @@
1
- class ExtendedLogger
2
- module LoggerSubstitute
3
- attr_writer :clock
4
- attr_reader :datetime_format
5
- attr_writer :formatter
6
- attr_reader :io
7
- attr_accessor :progname
8
-
9
- def initialize io
10
- @io = io
11
- end
12
-
13
- def add severity, message=nil, progname=nil, &block
14
- return if log_device.nil?
15
-
16
- severity ||= self.class.const_get :UNKNOWN
17
- return if severity < level
18
-
19
- progname ||= self.progname
20
-
21
- if message.nil?
22
- if block
23
- message = block.()
24
- else
25
- message = progname
26
- progname = self.progname
27
- end
28
- end
29
-
30
- severity_label = self.class.levels[severity] || 'ANY'.freeze
31
-
32
- formatted_message = format severity_label, clock.now, progname, message
33
-
34
- log_device.write formatted_message
35
- end
36
- alias_method :log, :add
37
-
38
- def clock
39
- @clock ||= Time
40
- end
41
-
42
- def close
43
- log_device.close
44
- end
45
-
46
- def datetime_format= format
47
- @datetime_format = format
48
- default_formatter.datetime_format = format
49
- end
50
-
51
- def default_formatter
52
- @default_formatter ||= Formatter.build
53
- end
54
-
55
- def format *arguments
56
- formatter.(*arguments)
57
- end
58
-
59
- def formatter
60
- @formatter ||= default_formatter
61
- end
62
-
63
- def level
64
- @level ||= 0
65
- end
66
- alias_method :sev_threshold, :level
67
-
68
- def level= severity_or_label
69
- if severity_or_label.respond_to? :to_int
70
- severity = severity_or_label.to_int
71
- end
72
-
73
- unless severity
74
- label = severity_or_label
75
- level = label.to_s.upcase
76
-
77
- severity = self.class.levels.index level
78
- end
79
-
80
- unless severity
81
- raise ArgumentError, "Not a severity: #{severity_or_label.inspect}"
82
- end
83
-
84
- @level = severity
85
- end
86
- alias_method :sev_threshold=, :level=
87
-
88
- def log_device
89
- return unless io
90
- @log_device ||= ::Logger::LogDevice.new io
91
- end
92
-
93
- def unknown progname=nil, &block
94
- add nil, nil, progname, &block
95
- end
96
- end
97
- end
@@ -1,40 +0,0 @@
1
- class ExtendedLogger
2
- module PerClassLogging
3
- attr_writer :logger
4
-
5
- def cache
6
- @cache ||= Hash.new do |hash, mod|
7
- logger = self.logger.dup
8
-
9
- logger.progname = mod
10
- logger.level -= verbosity
11
-
12
- hash[mod] = logger
13
- end
14
- end
15
-
16
- def configure logger
17
- self.logger = logger
18
-
19
- cache.clear
20
- end
21
-
22
- def get mod
23
- cache[mod]
24
- end
25
-
26
- def logger
27
- @logger ||= Logger.new $stderr
28
- end
29
-
30
- def verbosity
31
- @verbosity ||= 0
32
- end
33
-
34
- def verbosity= value
35
- @verbosity = value
36
-
37
- cache.clear
38
- end
39
- end
40
- end