extended_logger 0.3.0 → 0.5.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: 12acc57301fb31c71adadd859ed1e9227adf4e38
4
- data.tar.gz: 15e746abb842188e8c1f2d4786f9c7161d35dc60
3
+ metadata.gz: 47bdad0e0a33ecdf506b71aa4bb4784085583b19
4
+ data.tar.gz: 7e3ae841f32d58d983af5d7062e4e18145ddba1a
5
5
  SHA512:
6
- metadata.gz: 19703c7afe912c2c68227efc333641b5d520f98688f73ca23c05261f6bb5984d93e2e6796af3d4593006db05bcd631c9dc66e07bc4d7864358b0aa4c8f4813ec
7
- data.tar.gz: c32d52b617a488dd072899e87e2f1d09a268e4a3a71d4878bbd5186d20e060b9d97e8ea2f26fbc696451765414aa46d829ba40966d234843454920124d74ceb2
6
+ metadata.gz: 7f993016f5115afb6b3cf8a63a37dfc09209bdca075a1eff70666b0de2704502569325f811d1e7a61e9991091768615b11cc10b8c82ca81ff75e549ba21b3226
7
+ data.tar.gz: 998ee7a2958d74795175ff3e69e138651b6eeeb40df13d506f81b28e6c53f367e611c36f4737deba6d3918ea65ef78fe29809770d46460d7f5d45cbd6b312cb4
@@ -0,0 +1,124 @@
1
+ class ExtendedLogger
2
+ class ColorScheme
3
+ attr_reader :map
4
+
5
+ def initialize map
6
+ @map = map
7
+ end
8
+
9
+ def self.build symbol_map
10
+ code_map = {}
11
+
12
+ symbol_map.each do |label, (fg_sym, bg_sym)|
13
+ fg = Colors.index fg_sym
14
+ bg = Colors.index bg_sym
15
+
16
+ code_map[label] = [fg, bg]
17
+ end
18
+
19
+ new code_map
20
+ end
21
+
22
+ def color_code code
23
+ if code
24
+ code.to_s 16
25
+ else
26
+ '?'.freeze
27
+ end
28
+ end
29
+
30
+ def colorize severity, text
31
+ fg, bg = map[severity]
32
+
33
+ if bg
34
+ if bg > 8
35
+ text.insert 0, "\e[4#{bg - 8}m"
36
+ else
37
+ text.insert 0, "\e[4#{bg}m"
38
+ end
39
+ end
40
+
41
+ if fg
42
+ if fg > 8
43
+ text.insert 0, "\e[1;3#{fg - 8}m"
44
+ else
45
+ text.insert 0, "\e[0;3#{fg}m"
46
+ end
47
+ end
48
+
49
+ if fg or bg
50
+ text << "\e[0m"
51
+ end
52
+
53
+ text
54
+ end
55
+
56
+ def dump
57
+ output = ''
58
+ output.force_encoding 'US-ASCII'
59
+
60
+ map.each do |level, (fg, bg)|
61
+ fg_code = color_code fg
62
+ bg_code = color_code bg
63
+
64
+ output << ',' unless output.empty?
65
+ output << "#{level}=#{fg_code};#{bg_code}"
66
+ end
67
+
68
+ output
69
+ end
70
+
71
+ def self.decode code
72
+ return if code == '?'.freeze
73
+ code.to_i 16
74
+ end
75
+
76
+ def self.load data
77
+ map = {}
78
+
79
+ values = data.split ','.freeze
80
+
81
+ values.each do |assignment|
82
+ match_data = AssignmentPattern.match assignment
83
+
84
+ label = match_data[:label]
85
+ fg = decode match_data[:fg_code]
86
+ bg = decode match_data[:bg_code]
87
+
88
+ map[label] = [fg, bg]
89
+ end
90
+
91
+ new map
92
+ end
93
+
94
+ Colors = %i(
95
+ black
96
+ red
97
+ green
98
+ brown
99
+ blue
100
+ magenta
101
+ cyan
102
+ gray
103
+
104
+ dark_gray
105
+ bright_red
106
+ bright_green
107
+ yellow
108
+ bright_blue
109
+ bright_magenta
110
+ bright_cyan
111
+ white
112
+ )
113
+
114
+ AssignmentPattern = %r{\A
115
+ (?<label>[_A-Z]+)
116
+ =
117
+ (?<fg_code>[?[:xdigit:]])+
118
+ ;
119
+ (?<bg_code>[?[:xdigit:]]+)\z
120
+ }nx
121
+
122
+ Null = self.new Hash.new
123
+ end
124
+ end
@@ -0,0 +1,35 @@
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
@@ -0,0 +1,49 @@
1
+ class ExtendedLogger
2
+ module Controls
3
+ module ColorSchemes
4
+ def self.normal_verbose
5
+ color_scheme = ExtendedLogger::ColorScheme.build(
6
+ 'NORMAL' => [:gray, :none],
7
+ 'VERBOSE' => [:none, :gray],
8
+ )
9
+ end
10
+ end
11
+
12
+ module Loggers
13
+ class NormalVerbose < ExtendedLogger
14
+ self.levels = %w(VERBOSE NORMAL)
15
+ end
16
+ end
17
+
18
+ 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"
29
+ end
30
+ end
31
+
32
+ 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
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,38 +1,46 @@
1
- class ExtendedLogger < Logger
2
- attr_accessor :always_evaluate
1
+ class ExtendedLogger
2
+ include LoggerSubstitute
3
+ extend PerClassLogging
3
4
 
4
- def initialize *;
5
- super
5
+ attr_accessor :always_interpolate
6
+ attr_writer :color_scheme
6
7
 
7
- formatter_cls = self.class.const_get :Formatter
8
- @formatter = formatter_cls.new @default_formatter
9
- end
8
+ def self.build io, always_interpolate: nil, color_scheme: nil
9
+ instance = new io
10
+
11
+ instance.always_interpolate = true if always_interpolate
12
+
13
+ if color_scheme
14
+ color_scheme = ColorScheme.load color_scheme if color_scheme.is_a? String
15
+ instance.color_scheme = color_scheme
16
+ end
10
17
 
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
18
  instance
16
19
  end
17
20
 
18
21
  def add severity, *, &block
19
- block.call if block_given? and always_evaluate and severity < @level
22
+ if always_interpolate and severity < level
23
+ block.() if block
24
+ end
25
+
20
26
  super
21
27
  end
22
28
 
23
- def apply_extensions always_evaluate: nil, color_swatch: nil
24
- always_evaluate ||= false
25
-
26
- self.always_evaluate = always_evaluate
29
+ def color_scheme
30
+ @color_scheme ||= ColorScheme::Null
31
+ end
27
32
 
28
- formatter.color_swatch = Colors.unpack color_swatch if color_swatch
33
+ def format severity, *arguments
34
+ formatted_message = super
35
+ color_scheme.colorize severity, formatted_message
29
36
  end
30
37
 
31
- def formatter= internal_formatter
32
- formatter.internal_formatter = internal_formatter
38
+ def self.levels= levels
39
+ ConfigureLevels.configure_levels self, levels
33
40
  end
34
41
 
35
- def self.define &block
36
- Define.(block)
42
+ # ExtendedLogger::Logger can be used in place of ::Logger
43
+ class Logger < ExtendedLogger
44
+ self.levels = %w(DEBUG INFO WARN ERROR FATAL)
37
45
  end
38
46
  end
@@ -1,39 +1,27 @@
1
1
  class ExtendedLogger
2
- class Formatter
3
- attr_writer :color_swatch
4
- attr_accessor :internal_formatter
5
-
6
- def initialize internal_formatter
7
- @internal_formatter = internal_formatter
8
- end
9
-
10
- def call severity, *arguments, message
11
- output = ''
12
-
13
- message = '(empty log message)' if message.empty?
14
-
15
- message.gsub! "\r".freeze, "\\r".freeze
16
-
17
- message.each_line do |line|
18
- line = $/.inspect[1...-1] if line == $/
19
- line.chomp! if line.end_with? $/
20
-
21
- formatted_line = internal_formatter.(severity, *arguments, line)
22
- output.concat formatted_line
2
+ class Formatter < ::Logger::Formatter
3
+ BlankLine = /\A[[:blank:]]*\z/n
4
+ LineEnding = /[[:blank:]]*\r*[\r\n]/n
5
+ Separator = "\n".freeze
6
+
7
+ def call *arguments, message
8
+ if BlankLine.match message.to_s
9
+ super *arguments, '(empty log message)'.freeze
10
+ else
11
+ message.gsub! LineEnding do |line_ending|
12
+ quoted = line_ending.inspect[1...-1]
13
+ quoted << Separator
14
+ quoted
15
+ end
16
+
17
+ lines = message.split Separator
18
+
19
+ lines.reduce String.new do |output, line|
20
+ formatted_line = super *arguments, line
21
+ output << formatted_line
22
+ output
23
+ end
23
24
  end
24
-
25
- color = color_swatch[severity] || color_swatch['ANY'.freeze]
26
- Colors.apply output, **color if color
27
-
28
- output
29
- end
30
-
31
- def color_swatch
32
- @color_swatch ||= {}
33
- end
34
-
35
- def datetime_format= value
36
- internal_formatter.datetime_format = value
37
25
  end
38
26
  end
39
27
  end
@@ -0,0 +1,97 @@
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.new
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
@@ -0,0 +1,40 @@
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
@@ -1,9 +1,10 @@
1
1
  require 'logger'
2
+ require 'time'
2
3
 
3
- require 'extended_logger/extended_logger'
4
-
5
- require 'extended_logger/colors'
6
- require 'extended_logger/colors/pack'
7
- require 'extended_logger/colors/unpack'
8
- require 'extended_logger/define'
4
+ require 'extended_logger/color_scheme'
5
+ require 'extended_logger/configure_levels'
9
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'
metadata CHANGED
@@ -1,32 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extended_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.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-09 00:00:00.000000000 Z
11
+ date: 2016-01-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: |
14
- extended-logger provides a richer logger implementation than the built in ruby
15
- logger, offering more log levels and colors. In addition, loggers can be
16
- constructed for your classes and modules, which include the constant name in
17
- output for easy filtering.
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.
17
+
18
+ '
18
19
  email: nathanladd+github@gmail.com
19
20
  executables: []
20
21
  extensions: []
21
22
  extra_rdoc_files: []
22
23
  files:
23
24
  - 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
25
+ - lib/extended_logger/color_scheme.rb
26
+ - lib/extended_logger/configure_levels.rb
27
+ - lib/extended_logger/controls.rb
28
28
  - lib/extended_logger/extended_logger.rb
29
29
  - lib/extended_logger/formatter.rb
30
+ - lib/extended_logger/logger_substitute.rb
31
+ - lib/extended_logger/per_class_logging.rb
30
32
  homepage: https://github.com/ntl/extended-logger
31
33
  licenses:
32
34
  - MIT
@@ -47,9 +49,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
49
  version: '0'
48
50
  requirements: []
49
51
  rubyforge_project:
50
- rubygems_version: 2.4.5.1
52
+ rubygems_version: 2.5.1
51
53
  signing_key:
52
54
  specification_version: 4
53
- summary: Provides an extended logger offering more features than the ruby logger
55
+ summary: An alternative to the built-in Logger
54
56
  test_files: []
55
- has_rdoc:
@@ -1,47 +0,0 @@
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
@@ -1,55 +0,0 @@
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
@@ -1,50 +0,0 @@
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
@@ -1,55 +0,0 @@
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