File: string.rb

package info (click to toggle)
ruby-dry-logger 1.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 156 kB
  • sloc: ruby: 802; makefile: 4
file content (149 lines) | stat: -rw-r--r-- 3,650 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# frozen_string_literal: true

require "set"

require_relative "template"
require_relative "structured"

module Dry
  module Logger
    module Formatters
      # Basic string formatter.
      #
      # This formatter returns log entries in key=value format.
      #
      # @since 1.0.0
      # @api public
      class String < Structured
        # @since 1.0.0
        # @api private
        HASH_SEPARATOR = ","

        # @since 1.0.0
        # @api private
        EXCEPTION_SEPARATOR = ": "

        # @since 1.2.0
        # @api private
        DEFAULT_SEVERITY_COLORS = {
          DEBUG => :cyan,
          INFO => :magenta,
          WARN => :yellow,
          ERROR => :red,
          FATAL => :red,
          UNKNOWN => :blue
        }.freeze

        # @since 1.0.0
        # @api private
        attr_reader :template

        # @since 1.0.0
        # @api private
        def initialize(template: Logger.templates[:default], **options)
          super(**options)
          @template = Template[template]
        end

        # @since 1.0.0
        # @api private
        def colorize?
          options[:colorize].equal?(true)
        end

        private

        # @since 1.0.0
        # @api private
        def format_severity(value)
          output = value.upcase

          if colorize?
            Colors.call(severity_colors[LEVELS[value]], output)
          else
            output
          end
        end

        # @since 1.0.0
        # @api private
        def format(entry)
          if entry.exception?
            head = template % template_data(entry, exclude: %i[exception])
            tail = format_exception(entry.exception)

            "#{head}#{NEW_LINE}#{TAB}#{tail}"
          else
            template % template_data(entry)
          end
        end

        # @since 1.0.0
        # @api private
        def format_tags(value)
          Array(value)
            .map { |tag|
              case tag
              when Hash then format_payload(tag)
              else
                tag.to_s
              end
            }
            .join(SEPARATOR)
        end

        # @since 1.0.0
        # @api private
        def format_exception(value)
          [
            "#{value.message} (#{value.class})",
            format_backtrace(value.backtrace || EMPTY_BACKTRACE)
          ].join(NEW_LINE)
        end

        # @since 1.0.0
        # @api private
        def format_payload(payload)
          payload.map { |key, value| "#{key}=#{value.inspect}" }.join(SEPARATOR)
        end

        # @since 1.0.0
        # @api private
        def format_backtrace(value)
          value.map { |line| "#{TAB}#{line}" }.join(NEW_LINE)
        end

        # @since 1.0.0
        # @api private
        def template_data(entry, exclude: EMPTY_ARRAY)
          data = format_values(entry)
          payload = data.except(:message, *entry.meta.keys, *template.tokens, *exclude)
          data[:payload] = format_payload(payload)

          if template.include?(:tags)
            data[:tags] = format_tags(entry.tags)
          end

          if data[:message]
            data.except(*payload.keys)
          elsif template.include?(:message)
            data[:message] = data.delete(:payload)
            data[:payload] = nil
            data
          else
            data
          end
        end

        # @since 1.0.0
        # @api private
        def severity_colors
          @severity_colors ||= DEFAULT_SEVERITY_COLORS.merge(
            (options[:severity_colors] || EMPTY_HASH)
              .to_h { |key, value| [LEVELS[key.to_s], value] }
          )
        end
      end
    end
  end
end