cogger 0.23.0 → 0.24.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
  SHA256:
3
- metadata.gz: 206ff070eb7f86523ea8ce73f13b12ca5eaa8e13d81d8adf389e69d984193d7d
4
- data.tar.gz: 5445cfff99f24c1af2fed78cc741ef0c469718c80fa54c5a4c1dff99069085f5
3
+ metadata.gz: 842b2f64a772746d63f841f53e74e644479a2df6ee539ad17b7f1695cd65930e
4
+ data.tar.gz: f12f15f27394bc984e32466101da2fbba972fb4f581d23a9c69cb9885b5c73e3
5
5
  SHA512:
6
- metadata.gz: fbbae623ca9b520bbe356f9fa37f35b1e3520b66e4deebeae2bc4d8dc8700ffa08531efde1c7db5ac49a37a428544ea1430b032594e90eed44ac006c1016a111
7
- data.tar.gz: 6c2a1e66c79d661e4131fb2a14d20984fcf945dac6746efd010043b7eaa4c62c69a1a451681cba7da531e8042639de0cc685ec46e92601820f2762c3f99585cd
6
+ metadata.gz: d4f48bc1845ac01851158ac17c027165335b617883e078e343a202d1e490d36fb4ab24fe4b238de6e4043213043d1be71b9b0b7d71eac958ae7b089d2de00d09
7
+ data.tar.gz: 3e6e608feec69ad5389176a02454e67521da40f8fb89112036c48aa78169a44edec3d3c0ef601524f195c0b22a9b14216a8e64631bd96ad72eba54f02995321c
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  = Cogger
12
12
 
13
- Cogger is a portmanteau for custom logger (i.e. `[c]ustom + l[ogger] = cogger`) which enhances Ruby's native {logger_link} functionality with additional features such as dynamic emojis, colorized text, structured JSON, multiple outputs, and much more. 🚀
13
+ Cogger is a portmanteau for custom logger (i.e. `[c]ustom + l[ogger] = cogger`) which enhances Ruby's native {logger_link} functionality with additional features such as dynamic emojis, colorized text, structured JSON, multiple streams, and much more. 🚀
14
14
 
15
15
  toc::[]
16
16
 
@@ -19,7 +19,7 @@ toc::[]
19
19
  * Enhances Ruby's default {logger_link} with additional functionality and firepower.
20
20
  * Provides dynamic/specific emoji output.
21
21
  * Provides dynamic/specific colorized output via the {tone_link} gem.
22
- * Provides customizable templates which leverage native {format_link}.
22
+ * Provides customizable templates which leverage the {format_link}.
23
23
  * Provides customizable formatters for simple, color, emoji, JSON, and/or custom formats.
24
24
  * Provides multiple streams so you can log the same information to several outputs at once.
25
25
  * Provides global and individual log entry tagging.
@@ -28,7 +28,7 @@ toc::[]
28
28
 
29
29
  == Screenshots
30
30
 
31
- image::https://alchemists.io/images/projects/cogger/screenshots/demo.png[Rack,width=713,height=1110]
31
+ image::https://alchemists.io/images/projects/cogger/screenshots/demo.png[Rack,width=724,height=1118]
32
32
 
33
33
  == Requirements
34
34
 
@@ -73,7 +73,7 @@ All behavior is provided by creating an instance of `Cogger`. Example:
73
73
  [source,ruby]
74
74
  ----
75
75
  logger = Cogger.new
76
- logger.info "Demo" # "Demo"
76
+ logger.info "Demo" # 🟢 [console] Demo
77
77
  ----
78
78
 
79
79
  If you set your logging level to `debug`, you can walk through each level:
@@ -213,10 +213,10 @@ Here's a detailed breakdown of the above:
213
213
 
214
214
  * *Universal*: Applies color universally to the _entire_ template and requires you to:
215
215
  ** Wrap your entire template in a and start (`<dynamic>`) and end tag (`</dynamic>`) which works much like an HTML tag in this context.
216
- ** Your tag names must either be `<dynamic></dynamic>`, any default color (example: `<green></green>`), or alias (i.e. `<your_alias></your_alias>`) as supported by the {tone_link} gem.
216
+ ** Your tag names must either be dynamic based on log level: `<dynamic></dynamic>`, a specific color: `<green></green>`, or an alias (example: `<your_alias></your_alias>`) as supported by the {tone_link} gem.
217
217
  * *Individual*: Individual templates allow you to apply color to _specific_ attributes and require you to:
218
- ** Format your attributes as `attribute:directive`. The colon delimiter is required to separate your attribute for your color choice.
219
- ** The color value (what follows after the colon) can be `dynamic`, any default color (example: `green`), or alias (i.e. `your_alias`) as supported by the {tone_link} gem.
218
+ ** Format your attributes as `%<attribute:directive>s`. The colon delimiter is required to separate your attribute for your color choice.
219
+ ** The color value (what follows after the colon) can be `dynamic`, any color (example: `green`), or an alias (i.e. `your_alias`) as supported by the {tone_link} gem.
220
220
 
221
221
  In addition to the general categorization of universal and individual tags, each support the following directives:
222
222
 
@@ -380,10 +380,17 @@ Symbols or strings can be used interchangeably when adding/getting formatters. A
380
380
 
381
381
  [source,ruby]
382
382
  ----
383
- Cogger::Formatters::Color::TEMPLATE # "%<message:dynamic>s"
384
- Cogger::Formatters::Emoji::TEMPLATE # "%<emoji:dynamic>s %<message:dynamic>s"
385
- Cogger::Formatters::JSON::TEMPLATE # nil
386
- Cogger::Formatters::Simple::TEMPLATE # "%<message>s"
383
+ Cogger::Formatters::Color::TEMPLATE
384
+ # "<dynamic>[</dynamic>%<id:dynamic>s<dynamic>]</dynamic> %<message:dynamic>s"
385
+
386
+ Cogger::Formatters::Emoji::TEMPLATE
387
+ # "%<emoji:dynamic>s <dynamic>[</dynamic>%<id:dynamic>s<dynamic>]</dynamic> %<message:dynamic>s"
388
+
389
+ Cogger::Formatters::JSON::TEMPLATE
390
+ # nil
391
+
392
+ Cogger::Formatters::Simple::TEMPLATE
393
+ # "[%<id>s] %<message>s"
387
394
  ----
388
395
 
389
396
  💡 When you find yourself customizing any of the default formatters, you can reduce typing by adding your custom configuration to the registry and then referring to it via it's associated key when initializing a new logger.
@@ -457,7 +464,7 @@ The emoji formatter is enabled by default and is the equivalent of initializing
457
464
  ----
458
465
  logger = Cogger.new
459
466
  logger = Cogger.new formatter: :emoji
460
- logger = Cogger.new formatter: Cogger::Formatters::Emoji.new("%<emoji:dynamic>s %<message:dynamic>s")
467
+ logger = Cogger.new formatter: Cogger::Formatters::Emoji.new
461
468
  ----
462
469
 
463
470
  All of the above examples are identical so you can see how different formatters can be used and customized further. The default emojis are registered as follows:
@@ -1042,6 +1049,8 @@ bin/rake
1042
1049
 
1043
1050
  == link:https://alchemists.io/policies/contributions[Contributions]
1044
1051
 
1052
+ == link:https://alchemists.io/policies/developer_certificate_of_origin[Developer Certificate of Origin]
1053
+
1045
1054
  == link:https://alchemists.io/projects/cogger/versions[Versions]
1046
1055
 
1047
1056
  == link:https://alchemists.io/community[Community]
data/cogger.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "cogger"
5
- spec.version = "0.23.0"
5
+ spec.version = "0.24.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/cogger"
@@ -4,7 +4,7 @@ module Cogger
4
4
  module Formatters
5
5
  # Formats by color.
6
6
  class Color
7
- TEMPLATE = "[%<id:dynamic>s] %<message:dynamic>s"
7
+ TEMPLATE = "<dynamic>[</dynamic>%<id:dynamic>s<dynamic>]</dynamic> %<message:dynamic>s"
8
8
 
9
9
  def initialize template = TEMPLATE, processor: Processors::Color.new
10
10
  @template = template
@@ -4,7 +4,8 @@ module Cogger
4
4
  module Formatters
5
5
  # Formats by emoji and color.
6
6
  class Emoji < Color
7
- TEMPLATE = "%<emoji:dynamic>s [%<id:dynamic>s] %<message:dynamic>s"
7
+ TEMPLATE = "%<emoji:dynamic>s <dynamic>[</dynamic>%<id:dynamic>s<dynamic>]</dynamic> " \
8
+ "%<message:dynamic>s"
8
9
 
9
10
  def initialize(template = TEMPLATE, ...)
10
11
  super
@@ -10,9 +10,9 @@ module Cogger
10
10
  TEMPLATE = nil
11
11
 
12
12
  def initialize template = TEMPLATE,
13
- parser: Parsers::Individual.new,
13
+ parser: Parsers::KeyExtractor.new,
14
14
  sanitizer: Kit::Sanitizer
15
- @positions = template ? parser.call(template).last.keys : Core::EMPTY_ARRAY
15
+ @positions = template ? parser.call(template) : Core::EMPTY_ARRAY
16
16
  @sanitizer = sanitizer
17
17
  end
18
18
 
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cogger
4
+ module Formatters
5
+ module Parsers
6
+ # An abstrct class with default functionality.
7
+ class Abstract
8
+ def initialize registry: Cogger, colorizer: Kit::Colorizer, expressor: Regexp
9
+ @registry = registry
10
+ @colorizer = colorizer
11
+ @expressor = expressor
12
+ end
13
+
14
+ def call(_template, **)
15
+ fail NoMethodError,
16
+ "`#{self.class}##{__method__} #{method(__method__).parameters}` must be implemented."
17
+ end
18
+
19
+ protected
20
+
21
+ attr_reader :registry, :colorizer, :expressor
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cogger
4
+ module Formatters
5
+ module Parsers
6
+ # Parses template literals, emojis, and keys for specific and dynamic colors.
7
+ class Combined
8
+ STEPS = [Element.new, Emoji.new, Specific.new].freeze
9
+
10
+ def initialize steps: STEPS
11
+ @steps = steps
12
+ end
13
+
14
+ def call(template, **attributes)
15
+ steps.reduce(template.dup) { |modification, step| step.call modification, **attributes }
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :steps
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cogger
4
+ module Formatters
5
+ module Parsers
6
+ # Parses template elements for specific and dynamic colors.
7
+ class Element < Abstract
8
+ PATTERN = %r(
9
+ < # Tag open start.
10
+ (?<name>\w+) # Tag open name.
11
+ > # Tag open end.
12
+ (?<content>.+?) # Content.
13
+ </ # Tag close start.
14
+ \w+ # Tag close.
15
+ > # Tag close end.
16
+ )mx
17
+
18
+ def initialize pattern: PATTERN
19
+ super()
20
+ @pattern = pattern
21
+ end
22
+
23
+ def call(template, **)
24
+ template.gsub! pattern do
25
+ captures = expressor.last_match.named_captures
26
+ color = colorizer.call(captures["name"], **)
27
+ registry.color[captures["content"], color]
28
+ end
29
+
30
+ template
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :pattern
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cogger
4
+ module Formatters
5
+ module Parsers
6
+ # Parses template emojis for specific and dynamic colors.
7
+ class Emoji < Abstract
8
+ PATTERN = /
9
+ %< # Start.
10
+ emoji # Name.
11
+ : # Delimiter.
12
+ (?<color>\w+) # Color.
13
+ >s # End.
14
+ /x
15
+
16
+ def initialize pattern: PATTERN
17
+ super()
18
+ @pattern = pattern
19
+ end
20
+
21
+ def call(template, **)
22
+ template.gsub! pattern do
23
+ captures = expressor.last_match.named_captures
24
+ color = colorizer.call(captures["color"], **)
25
+
26
+ registry.get_emoji color
27
+ end
28
+
29
+ template
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :pattern
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cogger
4
+ module Formatters
5
+ module Parsers
6
+ # Parses template and extracts keys.
7
+ class KeyExtractor
8
+ PATTERN = /
9
+ % # Start.
10
+ ? # Flag, width, or precision.
11
+ < # Reference start.
12
+ (?<name>\w+) # Name.
13
+ (?::[\w]+)? # Optional delimiter and or color.
14
+ > # Reference end.
15
+ ? # Specifier.
16
+ /x
17
+
18
+ def initialize pattern: PATTERN
19
+ @pattern = pattern
20
+ end
21
+
22
+ def call(template) = template.scan(pattern).map { |match| match.first.to_sym }
23
+
24
+ private
25
+
26
+ attr_reader :pattern
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "core"
4
+
5
+ module Cogger
6
+ module Formatters
7
+ module Parsers
8
+ # Parses template for specific and dynamic string format specifiers.
9
+ class Specific < Abstract
10
+ PATTERN = /
11
+ % # Start.
12
+ (?<flag>[\s#+-0*])? # Optional flag.
13
+ (?<width>\d+)? # Optional width.
14
+ \.? # Optional precision delimiter.
15
+ (?<precision>\d+)? # Optional precision value.
16
+ < # Reference start.
17
+ (?<name>\w+) # Name.
18
+ : # Delimiter.
19
+ (?<color>\w+) # Color.
20
+ > # Reference end.
21
+ (?<specifier>[ABEGXabcdefgiopsux]) # Specifier.
22
+ /x
23
+
24
+ def initialize pattern: PATTERN
25
+ super()
26
+ @pattern = pattern
27
+ end
28
+
29
+ # :reek:TooManyStatements
30
+ def call(template, **)
31
+ template.gsub! pattern do |match|
32
+ captures = expressor.last_match.named_captures
33
+ original_color = captures["color"]
34
+ color = colorizer.call(original_color, **)
35
+
36
+ match.sub! ":#{original_color}", Core::EMPTY_STRING
37
+ registry.color[match, color]
38
+ end
39
+
40
+ template
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :pattern
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,58 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "tone"
4
-
5
3
  module Cogger
6
4
  module Formatters
7
5
  module Processors
8
- # Processes emojis and colors.
6
+ # Processes template with entry input using all template parsers.
9
7
  class Color
10
- def initialize parser: Parsers::Dynamic.new,
11
- kit: {sanitizer: Kit::Sanitizer, colorizer: Kit::Colorizer},
12
- registry: Cogger
8
+ def initialize parser: Parsers::Combined.new, sanitizer: Kit::Sanitizer
13
9
  @parser = parser
14
- @kit = kit
15
- @registry = registry
10
+ @sanitizer = sanitizer
16
11
  end
17
12
 
18
13
  def call(template, *input)
19
14
  attributes = sanitizer.call(*input).tagged
20
-
21
- case parser.call template
22
- in [String => body, String => style] then universal body, style, **attributes
23
- in [String => body, Hash => styles] then individual body, attributes, styles
24
- # :nocov:
25
- end
15
+ [parser.call(template, **attributes), attributes]
26
16
  end
27
17
 
28
18
  private
29
19
 
30
- attr_reader :parser, :kit, :registry
31
-
32
- def universal body, style, **attributes
33
- [registry.color[body, colorizer.call(style, attributes)], attributes]
34
- end
35
-
36
- def individual body, attributes, styles
37
- attributes = attributes.each.with_object({}) do |(key, value), collection|
38
- collection[key] = registry.color[value, colorizer.call(styles[key], attributes)]
39
- end
40
-
41
- emojify attributes, styles
42
- [body, attributes]
43
- end
44
-
45
- def emojify attributes, styles
46
- style = styles[:emoji]
47
-
48
- return unless style
49
-
50
- attributes[:emoji] = registry.get_emoji colorizer.call(style, attributes)
51
- end
52
-
53
- def sanitizer = kit.fetch :sanitizer
54
-
55
- def colorizer = kit.fetch :colorizer
20
+ attr_reader :parser, :sanitizer
56
21
  end
57
22
  end
58
23
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cogger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -35,7 +35,7 @@ cert_chain:
35
35
  3n5C8/6Zh9DYTkpcwPSuIfAga6wf4nXc9m6JAw8AuMLaiWN/r/2s4zJsUHYERJEu
36
36
  gZGm4JqtuSg8pYjPeIJxS960owq+SfuC+jxqmRA54BisFCv/0VOJi7tiJVY=
37
37
  -----END CERTIFICATE-----
38
- date: 2024-08-16 00:00:00.000000000 Z
38
+ date: 2024-08-23 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: core
@@ -114,9 +114,12 @@ files:
114
114
  - lib/cogger/formatters/json.rb
115
115
  - lib/cogger/formatters/kit/colorizer.rb
116
116
  - lib/cogger/formatters/kit/sanitizer.rb
117
- - lib/cogger/formatters/parsers/dynamic.rb
118
- - lib/cogger/formatters/parsers/individual.rb
119
- - lib/cogger/formatters/parsers/universal.rb
117
+ - lib/cogger/formatters/parsers/abstract.rb
118
+ - lib/cogger/formatters/parsers/combined.rb
119
+ - lib/cogger/formatters/parsers/element.rb
120
+ - lib/cogger/formatters/parsers/emoji.rb
121
+ - lib/cogger/formatters/parsers/key_extractor.rb
122
+ - lib/cogger/formatters/parsers/specific.rb
120
123
  - lib/cogger/formatters/processors/color.rb
121
124
  - lib/cogger/formatters/simple.rb
122
125
  - lib/cogger/hub.rb
metadata.gz.sig CHANGED
Binary file
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cogger
4
- module Formatters
5
- module Parsers
6
- # Dynamically extracts the universal or individual template attributes for log entry parsing.
7
- class Dynamic
8
- # Order matters.
9
- DELEGATES = [Universal.new, Individual.new].freeze
10
-
11
- def initialize delegates: DELEGATES
12
- @delegates = delegates
13
- end
14
-
15
- def call(template) = parse(template) || template
16
-
17
- private
18
-
19
- attr_reader :delegates
20
-
21
- def parse template
22
- delegates.find do |delegate|
23
- result = delegate.call template
24
- break result unless result == template
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,62 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cogger
4
- module Formatters
5
- module Parsers
6
- # Sanitizes and extracts individual directives from a template.
7
- class Individual
8
- # rubocop:todo Lint/MixedRegexpCaptureTypes
9
- PATTERN = /
10
- % # Strict reference syntax.
11
- (?<flag>[\s#+-0*])? # Optional flag.
12
- (?<width>\d+)? # Optional width.
13
- \.? # Optional precision delimiter.
14
- (?<precision>\d+)? # Optional precision value.
15
- < # Reference start.
16
- ( # Conditional start.
17
- (?<key>\w+) # Key.
18
- : # Directive delimiter.
19
- (?<directive>\w+) # Value.
20
- | # Conditional.
21
- (?<key>\w+) # Key.
22
- ) # Conditional end.
23
- > # Reference end.
24
- (?<specifier>[ABEGXabcdefgiopsux]) # Specifier.
25
- /mx
26
- # rubocop:enable Lint/MixedRegexpCaptureTypes
27
-
28
- def initialize pattern: PATTERN
29
- @pattern = pattern
30
- end
31
-
32
- def call template
33
- attributes = {}
34
-
35
- return [template, attributes] unless template.match? pattern
36
-
37
- template = sanitize_and_extract template, attributes
38
- [template, attributes]
39
- end
40
-
41
- private
42
-
43
- attr_reader :pattern
44
-
45
- # :reek:FeatureEnvy
46
- # :reek:TooManyStatements
47
- def sanitize_and_extract template, attributes
48
- template.gsub pattern do
49
- captures = Regexp.last_match.named_captures symbolize_names: true
50
- attributes[captures[:key].to_sym] = captures[:directive]
51
-
52
- captures.reduce(+"%") do |body, (key, value)|
53
- next body if key == :directive
54
-
55
- body.concat key == :key ? "<#{value}>" : value.to_s
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
62
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "core"
4
-
5
- module Cogger
6
- module Formatters
7
- module Parsers
8
- # Sanitizes and extracts the universal directive a template.
9
- class Universal
10
- # rubocop:todo Lint/MixedRegexpCaptureTypes
11
- PATTERN = %r(
12
- ( # Conditional start.
13
- \A # Search start.
14
- < # Tag start.
15
- (?<directive>\w+) # Directive.
16
- > # Tag end.
17
- | # Conditional pipe.
18
- < # Tag start.
19
- / # Tag close.
20
- (?<directive>\w+) # Directive.
21
- > # Tag end.
22
- \Z # Search end.
23
- ) # Conditional end.
24
- )mx
25
- # rubocop:enable Lint/MixedRegexpCaptureTypes
26
-
27
- KEY = "directive"
28
-
29
- def initialize pattern: PATTERN, key: KEY
30
- @pattern = pattern
31
- @key = key
32
- end
33
-
34
- def call template
35
- return template unless template.match? pattern
36
-
37
- [template.gsub(pattern, Core::EMPTY_STRING), template.match(pattern)[key]]
38
- end
39
-
40
- private
41
-
42
- attr_reader :pattern, :key
43
- end
44
- end
45
- end
46
- end