extended_logger 0.2.7 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 69fbd42275b49a88b59b5c6c9304b1c85802ec13
4
- data.tar.gz: df224b6d6ab28e632911b59f567afc139c29b664
3
+ metadata.gz: 12acc57301fb31c71adadd859ed1e9227adf4e38
4
+ data.tar.gz: 15e746abb842188e8c1f2d4786f9c7161d35dc60
5
5
  SHA512:
6
- metadata.gz: 56c924b08014891c69e89515d24049c90f942767cdafdd12d5507359e164f382c69e2980e045171a68f6cb491ffeb97d8283865cf8c3d5b01c83f6f240c1e3a0
7
- data.tar.gz: d204424f8e5a9b97afcd95b48d2e463cfb462a5f36a6665d5aab55b5f5e6a7ffa99059d45182961ab0685801479437021a4ff803105514845fe9367110a1754b
6
+ metadata.gz: 19703c7afe912c2c68227efc333641b5d520f98688f73ca23c05261f6bb5984d93e2e6796af3d4593006db05bcd631c9dc66e07bc4d7864358b0aa4c8f4813ec
7
+ data.tar.gz: c32d52b617a488dd072899e87e2f1d09a268e4a3a71d4878bbd5186d20e060b9d97e8ea2f26fbc696451765414aa46d829ba40966d234843454920124d74ceb2
@@ -1,6 +1,9 @@
1
1
  require 'logger'
2
2
 
3
3
  require 'extended_logger/extended_logger'
4
- require 'extended_logger/factory'
4
+
5
+ require 'extended_logger/colors'
6
+ require 'extended_logger/colors/pack'
7
+ require 'extended_logger/colors/unpack'
8
+ require 'extended_logger/define'
5
9
  require 'extended_logger/formatter'
6
- require 'extended_logger/null_logger'
@@ -0,0 +1,50 @@
1
+ class ExtendedLogger
2
+ module Colors
3
+ extend self
4
+
5
+ def apply text, fg:, bg:;
6
+ fg = Colors.index fg
7
+ bg = Colors.index bg
8
+
9
+ if fg
10
+ if fg > 8 then fg = "1;3#{fg - 8}" else fg = "0;3#{fg}" end
11
+ text.insert 0, "\e[#{fg}m"
12
+ end
13
+
14
+ if bg
15
+ if bg > 8 then bg = "4#{bg - 8}" else bg = "4#{bg}" end
16
+ text.insert 0, "\e[#{bg}m"
17
+ end
18
+
19
+ text.insert -1, "\e[0m" if fg or bg
20
+ end
21
+
22
+ def pack mapping=nil
23
+ Pack.(mapping)
24
+ end
25
+
26
+ def unpack data
27
+ Unpack.(data)
28
+ end
29
+
30
+ Colors = %i(
31
+ black
32
+ red
33
+ green
34
+ brown
35
+ blue
36
+ magenta
37
+ cyan
38
+ gray
39
+
40
+ dark_gray
41
+ bright_red
42
+ bright_green
43
+ yellow
44
+ bright_blue
45
+ bright_magenta
46
+ bright_cyan
47
+ white
48
+ )
49
+ end
50
+ end
@@ -0,0 +1,47 @@
1
+ class ExtendedLogger
2
+ module Colors
3
+ class Pack
4
+ attr_reader :mapping
5
+
6
+ def initialize mapping
7
+ @mapping = mapping
8
+ end
9
+
10
+ def self.call mapping=nil
11
+ mapping ||= {}
12
+
13
+ instance = new mapping
14
+ instance.()
15
+ end
16
+
17
+ def call
18
+ output = ''.encode 'US-ASCII'
19
+
20
+ mapping.sort.each do |level_name, hash|
21
+ fg, bg = hash.values_at(:fg, :bg).map do |color_name|
22
+ color_code color_name
23
+ end
24
+
25
+ output << ',' unless output.empty?
26
+ output << "#{level_name.upcase}=#{fg};#{bg}"
27
+ end
28
+
29
+ Unpack.(output)
30
+
31
+ output
32
+ end
33
+
34
+ def color_code color_name
35
+ return '?'.freeze if color_name == :none
36
+
37
+ number = Colors.index color_name
38
+
39
+ unless number
40
+ raise ArgumentError, "#{color_name.inspect} is not a color code"
41
+ end
42
+
43
+ number.to_s 16
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,55 @@
1
+ class ExtendedLogger
2
+ module Colors
3
+ class Unpack
4
+ attr_reader :data
5
+
6
+ Pattern = %r{\A
7
+ (?<level_name>[A-Z_]+) # DEBUG
8
+ = # =
9
+ (?<fg>[?[:xdigit:]])+ # f
10
+ ; # ;
11
+ (?<bg>[?[:xdigit:]])+ # 8
12
+ \Z}xn
13
+
14
+ def initialize data
15
+ @data = data
16
+ end
17
+
18
+ def self.call string
19
+ instance = new string
20
+ instance.()
21
+ end
22
+
23
+ def call
24
+ output = {}
25
+ mappings = data.split ','.freeze
26
+
27
+ mappings.each do |mapping|
28
+ match_data = Pattern.match mapping
29
+
30
+ unless match_data
31
+ raise ArgumentError, "Invalid swatch #{data.inspect}"
32
+ end
33
+
34
+ level_name = match_data[:level_name]
35
+
36
+ if match_data[:fg] == '?'.freeze
37
+ fg = :none
38
+ else
39
+ fg = Colors.fetch match_data[:fg].to_i(16)
40
+ end
41
+
42
+ if match_data[:bg] == '?'.freeze
43
+ bg = :none
44
+ else
45
+ bg = Colors.fetch match_data[:bg].to_i(16)
46
+ end
47
+
48
+ output[level_name] = { :fg => fg, :bg => bg }
49
+ end
50
+
51
+ output
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,55 @@
1
+ class ExtendedLogger
2
+ class Define
3
+ attr_reader :block
4
+ attr_reader :cls
5
+
6
+ DefaultLogLevels = %i(debug debug? error error? fatal fatal? info info? warn warn?)
7
+
8
+ def initialize block, cls
9
+ @block = block
10
+ @cls = cls
11
+ end
12
+
13
+ def self.call block
14
+ cls = Class.new ExtendedLogger
15
+
16
+ instance = new block, cls
17
+ instance.()
18
+ end
19
+
20
+ def call
21
+ cls.send :undef_method, *DefaultLogLevels
22
+
23
+ instance_exec &block
24
+
25
+ null_logger = cls.new nil
26
+ cls.const_set :NullLogger, null_logger
27
+
28
+ cls
29
+ end
30
+
31
+ def default_formatter &block
32
+ formatter_cls = Class.new Formatter
33
+ formatter_cls.send :define_method, :call, &block
34
+ cls.const_set :Formatter, formatter_cls
35
+ end
36
+
37
+ def levels const_names
38
+ const_names.each_with_index do |const_name, level|
39
+ cls.const_set const_name, level
40
+
41
+ method_name = const_name.to_s.downcase
42
+
43
+ cls.send :define_method, method_name do |progname=nil, &block|
44
+ add level, nil, progname, &block
45
+ end
46
+
47
+ cls.send :define_method, "#{method_name}?" do
48
+ @level <= level
49
+ end
50
+ end
51
+
52
+ cls.const_set :UNKNOWN, const_names.size
53
+ end
54
+ end
55
+ end
@@ -1,93 +1,38 @@
1
1
  class ExtendedLogger < Logger
2
- class << self
3
- attr_accessor :default_log_level
2
+ attr_accessor :always_evaluate
4
3
 
5
- def configure receiver, attribute_name=nil, **overrides
6
- attribute_name ||= 'logger'.freeze
7
- setter = "#{attribute_name}=".freeze
4
+ def initialize *;
5
+ super
8
6
 
9
- logger = get receiver, **overrides
10
-
11
- receiver.public_send setter, logger
12
- end
13
-
14
- def get receiver, **overrides
15
- receiver_name =
16
- if receiver.is_a? Module
17
- receiver.name
18
- else
19
- receiver.class.name
20
- end
21
-
22
- logger = Factory.(**overrides)
23
- logger.progname = "(#{receiver_name})"
24
- logger
25
- end
26
-
27
- def instance
28
- @instance ||= Factory.()
29
- end
30
-
31
- def levels
32
- @levels ||= {
33
- -7 => 'OBSOLETE'.freeze,
34
- -6 => 'OPT_DATA'.freeze,
35
- -5 => 'OPT_TRACE'.freeze,
36
- -4 => 'OPT_DEBUG'.freeze,
37
- -3 => 'DATA'.freeze,
38
- -2 => 'TRACE'.freeze,
39
- -1 => 'DEBUG'.freeze,
40
- 0 => 'INFO'.freeze,
41
- 1 => 'PASS'.freeze,
42
- 2 => 'FAIL'.freeze,
43
- 3 => 'FOCUS'.freeze,
44
- 4 => 'WARN'.freeze,
45
- 5 => 'ERROR'.freeze,
46
- 6 => 'FATAL'.freeze,
47
- }
48
- end
49
-
50
- def level? level
51
- levels.key? level
52
- end
7
+ formatter_cls = self.class.const_get :Formatter
8
+ @formatter = formatter_cls.new @default_formatter
53
9
  end
54
10
 
55
- def datetime_format
56
- formatter.datetime_format
11
+ def self.build *arguments, initial_level: nil, **extensions
12
+ instance = new *arguments
13
+ instance.level = initial_level if initial_level
14
+ instance.apply_extensions **extensions
15
+ instance
57
16
  end
58
17
 
59
- def datetime_format= format
60
- formatter.datetime_format = format
18
+ def add severity, *, &block
19
+ block.call if block_given? and always_evaluate and severity < @level
20
+ super
61
21
  end
62
22
 
63
- def format_severity severity
64
- unless self.class.level? severity
65
- Kernel.warn "(extended-logger) Unknown log severity level #{severity.inspect}"
66
- end
67
-
68
- self.class.levels.fetch severity, 'ANY'.freeze
69
- end
23
+ def apply_extensions always_evaluate: nil, color_swatch: nil
24
+ always_evaluate ||= false
70
25
 
71
- def formatter= formatter
72
- if self.formatter.is_a? Formatter
73
- self.formatter.logger_formatter = formatter
74
- else
75
- super
76
- end
77
- end
26
+ self.always_evaluate = always_evaluate
78
27
 
79
- def io
80
- return unless @logdev
81
- @logdev.dev
28
+ formatter.color_swatch = Colors.unpack color_swatch if color_swatch
82
29
  end
83
30
 
84
- def unknown *arguments, &block
85
- add 7, *arguments, &block
31
+ def formatter= internal_formatter
32
+ formatter.internal_formatter = internal_formatter
86
33
  end
87
34
 
88
- levels.each do |level, name|
89
- define_method name.downcase do |*arguments, &block|
90
- add level, *arguments, &block
91
- end
35
+ def self.define &block
36
+ Define.(block)
92
37
  end
93
38
  end
@@ -1,97 +1,39 @@
1
1
  class ExtendedLogger
2
2
  class Formatter
3
- attr_writer :logger_formatter
4
- attr_writer :palette
3
+ attr_writer :color_swatch
4
+ attr_accessor :internal_formatter
5
5
 
6
- def call severity, *arguments
7
- log_entry = delegate severity, *arguments
8
- color log_entry, severity
6
+ def initialize internal_formatter
7
+ @internal_formatter = internal_formatter
9
8
  end
10
9
 
11
- def color log_entry, severity
12
- colorizer = palette[severity]
13
-
14
- if colorizer
15
- log_entry = "#{colorizer}#{log_entry}\e[0m"
16
- end
17
-
18
- log_entry
19
- end
20
-
21
- def datetime_format
22
- logger_formatter.datetime_format
23
- end
24
-
25
- def datetime_format= format
26
- logger_formatter.datetime_format = format
27
- end
28
-
29
- def delegate *arguments, message
30
- message = format_message message, arguments
31
- logger_formatter.(*arguments, message)
32
- end
33
-
34
- def format_message message, arguments
10
+ def call severity, *arguments, message
35
11
  output = ''
36
12
 
37
- message.each_line "\n".freeze do |line|
38
- if line == "\n".freeze
39
- line = "\\n"
40
- else
41
- line.gsub! "\r".freeze, "\\r".freeze
42
- end
13
+ message = '(empty log message)' if message.empty?
43
14
 
44
- if output.empty?
45
- output.concat line
46
- else
47
- formatted_line = logger_formatter.(*arguments, line.chomp("\n".freeze))
48
- output.concat formatted_line
49
- end
50
- end
15
+ message.gsub! "\r".freeze, "\\r".freeze
51
16
 
52
- output.chomp "\n".freeze
53
- end
17
+ message.each_line do |line|
18
+ line = $/.inspect[1...-1] if line == $/
19
+ line.chomp! if line.end_with? $/
54
20
 
55
- def logger_formatter
56
- @logger_formatter ||= Logger::Formatter.new
57
- end
21
+ formatted_line = internal_formatter.(severity, *arguments, line)
22
+ output.concat formatted_line
23
+ end
58
24
 
59
- def palette
60
- @palette ||= {}
61
- end
25
+ color = color_swatch[severity] || color_swatch['ANY'.freeze]
26
+ Colors.apply output, **color if color
62
27
 
63
- def self.ansi_colors
64
- @ansi_colors ||= %i(black red green yellow blue magenta cyan white)
28
+ output
65
29
  end
66
30
 
67
- def self.col fg, brightness, bg=nil
68
- brightness = { :bright => 1, :normal => 0 }.fetch brightness
69
- escape = "\e[#{brightness};3#{ansi_colors.index fg}m"
70
-
71
- if bg
72
- escape << "\e[4#{ansi_colors.index bg}m"
73
- end
74
-
75
- escape
31
+ def color_swatch
32
+ @color_swatch ||= {}
76
33
  end
77
34
 
78
- def self.default_palette
79
- @default_palette ||= {
80
- 'OBSOLETE' => col(:black, :normal),
81
- 'DATA' => col(:green, :normal),
82
- 'TRACE' => col(:cyan, :normal),
83
- 'DEBUG' => col(:blue, :normal),
84
- 'OPT_DATA' => col(:green, :normal, :white),
85
- 'OPT_TRACE' => col(:cyan, :normal, :white),
86
- 'OPT_DEBUG' => col(:blue, :normal, :white),
87
- 'PASS' => col(:white, :bright, :green),
88
- 'FAIL' => col(:white, :bright, :red),
89
- 'FOCUS' => col(:white, :bright, :blue),
90
- 'WARN' => col(:yellow, :normal),
91
- 'ERROR' => col(:red, :normal),
92
- 'FATAL' => col(:black, :bright, :red),
93
- 'ANY' => col(:white, :bright, :magenta),
94
- }
35
+ def datetime_format= value
36
+ internal_formatter.datetime_format = value
95
37
  end
96
38
  end
97
39
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extended_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Ladd
@@ -21,10 +21,12 @@ extensions: []
21
21
  extra_rdoc_files: []
22
22
  files:
23
23
  - lib/extended_logger.rb
24
+ - lib/extended_logger/colors.rb
25
+ - lib/extended_logger/colors/pack.rb
26
+ - lib/extended_logger/colors/unpack.rb
27
+ - lib/extended_logger/define.rb
24
28
  - lib/extended_logger/extended_logger.rb
25
- - lib/extended_logger/factory.rb
26
29
  - lib/extended_logger/formatter.rb
27
- - lib/extended_logger/null_logger.rb
28
30
  homepage: https://github.com/ntl/extended-logger
29
31
  licenses:
30
32
  - MIT
@@ -1,61 +0,0 @@
1
- class ExtendedLogger
2
- class Factory
3
- attr_reader :env
4
- attr_writer :device
5
- attr_writer :level
6
-
7
- def initialize env
8
- @env = env
9
- end
10
-
11
- def self.build env=nil, device: nil, level: nil
12
- env ||= ENV
13
- level ||= ExtendedLogger.default_log_level
14
-
15
- instance = new env
16
- instance.device = device if device
17
- instance.level = level if level
18
- instance
19
- end
20
-
21
- def self.call *arguments
22
- instance = build *arguments
23
- instance.()
24
- end
25
-
26
- def call
27
- logger = ExtendedLogger.new device
28
-
29
- formatter = Formatter.new
30
- formatter.palette = Formatter.default_palette if colors? logger.io
31
- logger.formatter = formatter
32
-
33
- level = self.level
34
- logger.level = level if level
35
-
36
- logger
37
- end
38
-
39
- def colors? io
40
- if io.tty?
41
- ENV['LOG_COLOR'] != 'off'
42
- else
43
- ENV['LOG_COLOR'] == 'on'
44
- end
45
- end
46
-
47
- def device
48
- @device || env['LOG_DEVICE'] || $stderr
49
- end
50
-
51
- def level
52
- level = @level || env['LOG_LEVEL']
53
-
54
- return unless level
55
- return level if level.is_a? Integer
56
-
57
- level , _ = ExtendedLogger.levels.rassoc level.upcase
58
- level
59
- end
60
- end
61
- end
@@ -1,3 +0,0 @@
1
- class ExtendedLogger
2
- NullLogger = self.new '/dev/null'
3
- end