extended_logger 0.2.7 → 0.3.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: 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