dry-logger 1.0.0.rc1 → 1.0.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 +4 -4
- data/CHANGELOG.md +16 -2
- data/lib/dry/logger/backends/core.rb +38 -0
- data/lib/dry/logger/backends/proxy.rb +38 -0
- data/lib/dry/logger/backends/stream.rb +6 -11
- data/lib/dry/logger/clock.rb +47 -0
- data/lib/dry/logger/constants.rb +55 -3
- data/lib/dry/logger/dispatcher.rb +85 -14
- data/lib/dry/logger/entry.rb +27 -33
- data/lib/dry/logger/formatters/colors.rb +84 -0
- data/lib/dry/logger/formatters/json.rb +27 -1
- data/lib/dry/logger/formatters/rack.rb +10 -2
- data/lib/dry/logger/formatters/string.rb +93 -26
- data/lib/dry/logger/formatters/structured.rb +16 -5
- data/lib/dry/logger/formatters/template.rb +92 -0
- data/lib/dry/logger/global.rb +123 -0
- data/lib/dry/logger/version.rb +1 -1
- data/lib/dry/logger.rb +45 -59
- metadata +10 -4
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "json"
|
4
|
+
|
5
|
+
require "dry/logger/constants"
|
4
6
|
require "dry/logger/formatters/structured"
|
5
7
|
|
6
8
|
module Dry
|
@@ -16,7 +18,31 @@ module Dry
|
|
16
18
|
# @since 0.1.0
|
17
19
|
# @api private
|
18
20
|
def format(entry)
|
19
|
-
|
21
|
+
hash = format_values(entry).compact
|
22
|
+
hash.update(hash.delete(:exception)) if entry.exception?
|
23
|
+
::JSON.dump(hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @since 0.1.0
|
27
|
+
# @api private
|
28
|
+
def format_severity(value)
|
29
|
+
value.upcase
|
30
|
+
end
|
31
|
+
|
32
|
+
# @since 0.1.0
|
33
|
+
# @api private
|
34
|
+
def format_exception(value)
|
35
|
+
{
|
36
|
+
exception: value.class,
|
37
|
+
message: value.message,
|
38
|
+
backtrace: value.backtrace || EMPTY_ARRAY
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# @since 0.1.0
|
43
|
+
# @api private
|
44
|
+
def format_time(value)
|
45
|
+
value.getutc.iso8601
|
20
46
|
end
|
21
47
|
end
|
22
48
|
end
|
@@ -12,10 +12,18 @@ module Dry
|
|
12
12
|
#
|
13
13
|
# @see String
|
14
14
|
class Rack < String
|
15
|
+
# @see String#initialize
|
15
16
|
# @since 1.0.0
|
16
17
|
# @api private
|
17
|
-
def
|
18
|
-
|
18
|
+
def initialize(**options)
|
19
|
+
super
|
20
|
+
@template = Template[Logger.templates[:rack]]
|
21
|
+
end
|
22
|
+
|
23
|
+
# @api 1.0.0
|
24
|
+
# @api private
|
25
|
+
def format_params(value)
|
26
|
+
return value unless value.empty?
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "set"
|
4
|
+
|
5
|
+
require_relative "template"
|
6
|
+
require_relative "structured"
|
4
7
|
|
5
8
|
module Dry
|
6
9
|
module Logger
|
@@ -12,10 +15,6 @@ module Dry
|
|
12
15
|
# @since 1.0.0
|
13
16
|
# @api public
|
14
17
|
class String < Structured
|
15
|
-
# @since 1.0.0
|
16
|
-
# @api private
|
17
|
-
SEPARATOR = " "
|
18
|
-
|
19
18
|
# @since 1.0.0
|
20
19
|
# @api private
|
21
20
|
HASH_SEPARATOR = ","
|
@@ -24,9 +23,16 @@ module Dry
|
|
24
23
|
# @api private
|
25
24
|
EXCEPTION_SEPARATOR = ": "
|
26
25
|
|
27
|
-
# @since 1.
|
26
|
+
# @since 1.2.0
|
28
27
|
# @api private
|
29
|
-
|
28
|
+
DEFAULT_SEVERITY_COLORS = {
|
29
|
+
DEBUG => :cyan,
|
30
|
+
INFO => :magenta,
|
31
|
+
WARN => :yellow,
|
32
|
+
ERROR => :red,
|
33
|
+
FATAL => :red,
|
34
|
+
UNKNOWN => :blue
|
35
|
+
}.freeze
|
30
36
|
|
31
37
|
# @since 1.0.0
|
32
38
|
# @api private
|
@@ -34,47 +40,108 @@ module Dry
|
|
34
40
|
|
35
41
|
# @since 1.0.0
|
36
42
|
# @api private
|
37
|
-
def initialize(template:
|
43
|
+
def initialize(template: Logger.templates[:default], **options)
|
38
44
|
super(**options)
|
39
|
-
@template = template
|
45
|
+
@template = Template[template]
|
46
|
+
end
|
47
|
+
|
48
|
+
# @since 1.0.0
|
49
|
+
# @api private
|
50
|
+
def colorize?
|
51
|
+
options[:colorize].equal?(true)
|
40
52
|
end
|
41
53
|
|
42
54
|
private
|
43
55
|
|
44
56
|
# @since 1.0.0
|
45
57
|
# @api private
|
46
|
-
def
|
47
|
-
|
58
|
+
def format_severity(value)
|
59
|
+
output = value.upcase
|
60
|
+
|
61
|
+
if colorize?
|
62
|
+
Colors.call(severity_colors[LEVELS[value]], output)
|
63
|
+
else
|
64
|
+
output
|
65
|
+
end
|
48
66
|
end
|
49
67
|
|
50
68
|
# @since 1.0.0
|
51
69
|
# @api private
|
52
|
-
def
|
70
|
+
def format(entry)
|
53
71
|
if entry.exception?
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
else
|
59
|
-
"#{entry.message}#{SEPARATOR}#{format_payload(entry)}"
|
60
|
-
end
|
72
|
+
head = template % template_data(entry, exclude: %i[exception])
|
73
|
+
tail = format_exception(entry.exception)
|
74
|
+
|
75
|
+
"#{head}#{NEW_LINE}#{TAB}#{tail}"
|
61
76
|
else
|
62
|
-
|
77
|
+
template % template_data(entry)
|
63
78
|
end
|
64
79
|
end
|
65
80
|
|
66
81
|
# @since 1.0.0
|
67
82
|
# @api private
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
83
|
+
def format_tags(value)
|
84
|
+
Array(value)
|
85
|
+
.map { |tag|
|
86
|
+
case tag
|
87
|
+
when Hash then format_payload(tag)
|
88
|
+
else
|
89
|
+
tag.to_s
|
90
|
+
end
|
91
|
+
}
|
92
|
+
.join(SEPARATOR)
|
93
|
+
end
|
94
|
+
|
95
|
+
# @since 1.0.0
|
96
|
+
# @api private
|
97
|
+
def format_exception(value)
|
98
|
+
[
|
99
|
+
"#{value.message} (#{value.class})",
|
100
|
+
format_backtrace(value.backtrace || EMPTY_BACKTRACE)
|
101
|
+
].join(NEW_LINE)
|
102
|
+
end
|
103
|
+
|
104
|
+
# @since 1.0.0
|
105
|
+
# @api private
|
106
|
+
def format_payload(payload)
|
107
|
+
payload.map { |key, value| "#{key}=#{value.inspect}" }.join(SEPARATOR)
|
108
|
+
end
|
109
|
+
|
110
|
+
# @since 1.0.0
|
111
|
+
# @api private
|
112
|
+
def format_backtrace(value)
|
113
|
+
value.map { |line| "#{TAB}#{line}" }.join(NEW_LINE)
|
114
|
+
end
|
115
|
+
|
116
|
+
# @since 1.0.0
|
117
|
+
# @api private
|
118
|
+
def template_data(entry, exclude: EMPTY_ARRAY)
|
119
|
+
data = format_values(entry)
|
120
|
+
payload = data.except(:message, *entry.meta.keys, *template.tokens, *exclude)
|
121
|
+
data[:payload] = format_payload(payload)
|
122
|
+
|
123
|
+
if template.include?(:tags)
|
124
|
+
data[:tags] = format_tags(entry.tags)
|
125
|
+
end
|
126
|
+
|
127
|
+
if data[:message]
|
128
|
+
data.except(*payload.keys)
|
129
|
+
elsif template.include?(:message)
|
130
|
+
data[:message] = data.delete(:payload)
|
131
|
+
data[:payload] = nil
|
132
|
+
data
|
133
|
+
else
|
134
|
+
data
|
135
|
+
end
|
72
136
|
end
|
73
137
|
|
74
138
|
# @since 1.0.0
|
75
139
|
# @api private
|
76
|
-
def
|
77
|
-
|
140
|
+
def severity_colors
|
141
|
+
@severity_colors ||= DEFAULT_SEVERITY_COLORS.merge(
|
142
|
+
(options[:severity_colors] || EMPTY_HASH)
|
143
|
+
.to_h { |key, value| [LEVELS[key.to_s], value] }
|
144
|
+
)
|
78
145
|
end
|
79
146
|
end
|
80
147
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "logger"
|
4
|
+
|
5
|
+
require "dry/logger/constants"
|
4
6
|
require "dry/logger/filter"
|
5
7
|
|
6
8
|
module Dry
|
@@ -8,6 +10,8 @@ module Dry
|
|
8
10
|
module Formatters
|
9
11
|
# Default structured formatter which receives {Logger::Entry} from the backends.
|
10
12
|
#
|
13
|
+
# This class can be used as the base class for your custom formatters.
|
14
|
+
#
|
11
15
|
# @see http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger/Formatter.html
|
12
16
|
#
|
13
17
|
# @since 1.0.0
|
@@ -21,10 +25,6 @@ module Dry
|
|
21
25
|
# @api private
|
22
26
|
NOOP_FILTER = -> message { message }
|
23
27
|
|
24
|
-
# @since 1.0.0
|
25
|
-
# @api private
|
26
|
-
NEW_LINE = $/ # rubocop:disable Style/SpecialGlobalVars
|
27
|
-
|
28
28
|
# @since 1.0.0
|
29
29
|
# @api private
|
30
30
|
attr_reader :filter
|
@@ -52,7 +52,7 @@ module Dry
|
|
52
52
|
# @return [String]
|
53
53
|
# @api public
|
54
54
|
def call(_severity, _time, _progname, entry)
|
55
|
-
format(entry.filter(filter))
|
55
|
+
format(entry.filter(filter)) + NEW_LINE
|
56
56
|
end
|
57
57
|
|
58
58
|
# Format entry into a loggable object
|
@@ -63,7 +63,18 @@ module Dry
|
|
63
63
|
# @return [Entry]
|
64
64
|
# @api public
|
65
65
|
def format(entry)
|
66
|
+
format_values(entry)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @since 1.0.0
|
70
|
+
# @api private
|
71
|
+
def format_values(entry)
|
66
72
|
entry
|
73
|
+
.to_h
|
74
|
+
.map { |key, value|
|
75
|
+
[key, respond_to?(meth = "format_#{key}", true) ? __send__(meth, value) : value]
|
76
|
+
}
|
77
|
+
.to_h
|
67
78
|
end
|
68
79
|
end
|
69
80
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "dry/logger/constants"
|
5
|
+
require_relative "colors"
|
6
|
+
|
7
|
+
module Dry
|
8
|
+
module Logger
|
9
|
+
module Formatters
|
10
|
+
# Basic string formatter.
|
11
|
+
#
|
12
|
+
# This formatter returns log entries in key=value format.
|
13
|
+
#
|
14
|
+
# @since 1.0.0
|
15
|
+
# @api public
|
16
|
+
class Template
|
17
|
+
# @since 1.0.0
|
18
|
+
# @api private
|
19
|
+
TOKEN_REGEXP = /%<(\w*)>s/.freeze
|
20
|
+
|
21
|
+
# @since 1.0.0
|
22
|
+
# @api private
|
23
|
+
MESSAGE_TOKEN = "%<message>s"
|
24
|
+
|
25
|
+
# @since 1.0.0
|
26
|
+
# @api private
|
27
|
+
attr_reader :value
|
28
|
+
|
29
|
+
# @since 1.0.0
|
30
|
+
# @api private
|
31
|
+
attr_reader :tokens
|
32
|
+
|
33
|
+
# @since 1.0.0
|
34
|
+
# @api private
|
35
|
+
def self.[](value)
|
36
|
+
cache.fetch(value) {
|
37
|
+
cache[value] = (colorized?(value) ? Template::Colorized : Template).new(value)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
# @since 1.0.0
|
42
|
+
# @api private
|
43
|
+
private_class_method def self.colorized?(value)
|
44
|
+
Colors::COLORS.keys.any? { |color| value.include?("<#{color}>") }
|
45
|
+
end
|
46
|
+
|
47
|
+
# @since 1.0.0
|
48
|
+
# @api private
|
49
|
+
private_class_method def self.cache
|
50
|
+
@cache ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
# @since 1.0.0
|
54
|
+
# @api private
|
55
|
+
class Colorized < Template
|
56
|
+
# @since 1.0.0
|
57
|
+
# @api private
|
58
|
+
def initialize(value)
|
59
|
+
super(Colors.evaluate(value))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @since 1.0.0
|
64
|
+
# @api private
|
65
|
+
def initialize(value)
|
66
|
+
@value = value
|
67
|
+
@tokens = value.scan(TOKEN_REGEXP).flatten(1).map(&:to_sym).to_set
|
68
|
+
end
|
69
|
+
|
70
|
+
# @since 1.0.0
|
71
|
+
# @api private
|
72
|
+
def %(tokens)
|
73
|
+
output = value % tokens
|
74
|
+
output.strip!
|
75
|
+
output.split(NEW_LINE).map(&:rstrip).join(NEW_LINE)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @since 1.0.0
|
79
|
+
# @api private
|
80
|
+
def colorize(color, input)
|
81
|
+
"\e[#{Colors[color.to_sym]}m#{input}\e[0m"
|
82
|
+
end
|
83
|
+
|
84
|
+
# @since 1.0.0
|
85
|
+
# @api private
|
86
|
+
def include?(token)
|
87
|
+
tokens.include?(token)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
|
5
|
+
module Dry
|
6
|
+
module Logger
|
7
|
+
# Global setup methods
|
8
|
+
#
|
9
|
+
# @api public
|
10
|
+
module Global
|
11
|
+
# Register a new formatter
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# class MyFormatter < Dry::Logger::Formatters::Structured
|
15
|
+
# def format_message(value)
|
16
|
+
# "WOAH: #{message}"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# def format_time(value)
|
20
|
+
# Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Dry::Logger.register_formatter(:my_formatter, MyFormatter)
|
25
|
+
#
|
26
|
+
# logger = Dry.Logger(:app, formatter: :my_formatter, template: :details)
|
27
|
+
#
|
28
|
+
# logger.info "Hello World"
|
29
|
+
# # [test] [INFO] [2022-11-15 10:06:29] WOAH: Hello World
|
30
|
+
#
|
31
|
+
# @since 1.0.0
|
32
|
+
# @return [Hash]
|
33
|
+
# @api public
|
34
|
+
def register_formatter(name, formatter)
|
35
|
+
formatters[name] = formatter
|
36
|
+
formatters
|
37
|
+
end
|
38
|
+
|
39
|
+
# Register a new template
|
40
|
+
#
|
41
|
+
# @example basic template
|
42
|
+
# Dry::Logger.register_template(:request, "[%<severity>s] %<verb>s %<path>s")
|
43
|
+
#
|
44
|
+
# logger = Dry.Logger(:my_app, template: :request)
|
45
|
+
#
|
46
|
+
# logger.info(verb: "GET", path: "/users")
|
47
|
+
# # [INFO] GET /users
|
48
|
+
#
|
49
|
+
# @example template with colors
|
50
|
+
# Dry::Logger.register_template(
|
51
|
+
# :request, "[%<severity>s] <green>%<verb>s</green> <blue>%<path>s</blue>"
|
52
|
+
# )
|
53
|
+
#
|
54
|
+
# @since 1.0.0
|
55
|
+
# @return [Hash]
|
56
|
+
# @api public
|
57
|
+
def register_template(name, template)
|
58
|
+
templates[name] = template
|
59
|
+
templates
|
60
|
+
end
|
61
|
+
|
62
|
+
# Build a logging backend instance
|
63
|
+
#
|
64
|
+
# @since 1.0.0
|
65
|
+
# @return [Backends::Stream]
|
66
|
+
# @api private
|
67
|
+
def new(stream: $stdout, **options)
|
68
|
+
backend =
|
69
|
+
case stream
|
70
|
+
when IO, StringIO then Backends::IO
|
71
|
+
when String, Pathname then Backends::File
|
72
|
+
else
|
73
|
+
raise ArgumentError, "unsupported stream type #{stream.class}"
|
74
|
+
end
|
75
|
+
|
76
|
+
formatter_spec = options[:formatter]
|
77
|
+
template_spec = options[:template]
|
78
|
+
|
79
|
+
template =
|
80
|
+
case template_spec
|
81
|
+
when Symbol then templates.fetch(template_spec)
|
82
|
+
when String then template_spec
|
83
|
+
when nil then templates[:default]
|
84
|
+
else
|
85
|
+
raise ArgumentError,
|
86
|
+
":template option must be a Symbol or a String (`#{template_spec}` given)"
|
87
|
+
end
|
88
|
+
|
89
|
+
formatter_options = {**options, template: template}
|
90
|
+
|
91
|
+
formatter =
|
92
|
+
case formatter_spec
|
93
|
+
when Symbol then formatters.fetch(formatter_spec).new(**formatter_options)
|
94
|
+
when Class then formatter_spec.new(**formatter_options)
|
95
|
+
when nil then formatters[:string].new(**formatter_options)
|
96
|
+
when ::Logger::Formatter then formatter_spec
|
97
|
+
else
|
98
|
+
raise ArgumentError, "Unsupported formatter option #{formatter_spec.inspect}"
|
99
|
+
end
|
100
|
+
|
101
|
+
backend_options = options.select { |key, _| BACKEND_OPT_KEYS.include?(key) }
|
102
|
+
|
103
|
+
backend.new(stream: stream, **backend_options, formatter: formatter)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Internal formatters registry
|
107
|
+
#
|
108
|
+
# @since 1.0.0
|
109
|
+
# @api private
|
110
|
+
def formatters
|
111
|
+
@formatters ||= {}
|
112
|
+
end
|
113
|
+
|
114
|
+
# Internal templates registry
|
115
|
+
#
|
116
|
+
# @since 1.0.0
|
117
|
+
# @api private
|
118
|
+
def templates
|
119
|
+
@templates ||= {}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/dry/logger/version.rb
CHANGED
data/lib/dry/logger.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "dry/logger/global"
|
3
4
|
require "dry/logger/constants"
|
5
|
+
require "dry/logger/clock"
|
4
6
|
require "dry/logger/dispatcher"
|
5
7
|
|
6
8
|
require "dry/logger/formatters/string"
|
@@ -40,74 +42,58 @@ module Dry
|
|
40
42
|
# logger.info(Hello: "World!")
|
41
43
|
# # {"progname":"my_app","severity":"INFO","time":"2022-11-06T10:11:29Z","Hello":"World!"}
|
42
44
|
#
|
45
|
+
# @example Setting up multiple backends
|
46
|
+
# logger = Dry.Logger(:my_app)
|
47
|
+
# add_backend(formatter: :string, template: :details)
|
48
|
+
# add_backend(formatter: :string, template: :details)
|
49
|
+
#
|
50
|
+
# @example Setting up conditional logging
|
51
|
+
# logger = Dry.Logger(:my_app) { |setup|
|
52
|
+
# setup.add_backend(formatter: :string, template: :details) { |b| b.log_if = :error?.to_proc }
|
53
|
+
# }
|
54
|
+
#
|
55
|
+
# @param [String, Symbol] id The dispatcher id, can be used as progname in log entries
|
56
|
+
# @param [Hash] options Options for backends and formatters
|
57
|
+
# @option options [Symbol] :level (:info) The minimum level that should be logged,
|
58
|
+
# @option options [Symbol] :stream (optional) The output stream, default is $stdout
|
59
|
+
# @option options [Symbol, Class, #call] :formatter (:string) The default formatter or its id,
|
60
|
+
# @option options [String, Symbol] :template (:default) The default template that should be used
|
61
|
+
# @option options [Boolean] :colorize (false) Enable/disable colorized severity
|
62
|
+
# @option options [Hash<Symbol=>Symbol>] :severity_colors ({}) A severity=>color mapping
|
63
|
+
# @option options [#call] :on_crash (Dry::Logger::Dispatcher::ON_CRASH) A crash-handling proc.
|
64
|
+
# This is used whenever logging crashes.
|
65
|
+
#
|
43
66
|
# @since 1.0.0
|
44
|
-
# @return [Dispatcher]
|
45
67
|
# @api public
|
46
|
-
|
47
|
-
|
68
|
+
# @return [Dispatcher]
|
69
|
+
def self.Logger(id, **options, &block)
|
70
|
+
Logger::Dispatcher.setup(id, **options, &block)
|
48
71
|
end
|
49
72
|
|
50
73
|
module Logger
|
51
|
-
|
52
|
-
#
|
53
|
-
# @example
|
54
|
-
# class MyFormatter < Dry::Logger::Formatters::Structured
|
55
|
-
# def format(entry)
|
56
|
-
# "WOAH: #{entry.message}"
|
57
|
-
# end
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# Dry::Logger.register_formatter(MyFormatter)
|
61
|
-
#
|
62
|
-
# @since 1.0.0
|
63
|
-
# @return [Hash]
|
64
|
-
# @api public
|
65
|
-
def self.register_formatter(name, formatter)
|
66
|
-
formatters[name] = formatter
|
67
|
-
formatters
|
68
|
-
end
|
69
|
-
|
70
|
-
# Build a logging backend instance
|
71
|
-
#
|
72
|
-
# @since 1.0.0
|
73
|
-
# @return [Backends::Stream]
|
74
|
-
# @api private
|
75
|
-
def self.new(stream: $stdout, **opts)
|
76
|
-
backend =
|
77
|
-
case stream
|
78
|
-
when IO, StringIO then Backends::IO
|
79
|
-
when String, Pathname then Backends::File
|
80
|
-
else
|
81
|
-
raise ArgumentError, "unsupported stream type #{stream.class}"
|
82
|
-
end
|
74
|
+
extend Global
|
83
75
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
when Symbol then formatters.fetch(formatter_opt).new(**opts)
|
89
|
-
when Class then formatter_opt.new(**opts)
|
90
|
-
when NilClass then formatters[:string].new(**opts)
|
91
|
-
when ::Logger::Formatter then formatter_opt
|
92
|
-
else
|
93
|
-
raise ArgumentError, "unsupported formatter option #{formatter_opt.inspect}"
|
94
|
-
end
|
76
|
+
# Built-in formatters
|
77
|
+
register_formatter(:string, Formatters::String)
|
78
|
+
register_formatter(:rack, Formatters::Rack)
|
79
|
+
register_formatter(:json, Formatters::JSON)
|
95
80
|
|
96
|
-
|
81
|
+
# Built-in templates
|
82
|
+
register_template(:default, "%<message>s %<payload>s")
|
97
83
|
|
98
|
-
|
99
|
-
end
|
84
|
+
register_template(:details, "[%<progname>s] [%<severity>s] [%<time>s] %<message>s %<payload>s")
|
100
85
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
86
|
+
register_template(:crash, <<~STR)
|
87
|
+
[%<progname>s] [%<severity>s] [%<time>s] Logging crashed
|
88
|
+
%<log_entry>s
|
89
|
+
%<message>s (%<exception>s)
|
90
|
+
%<backtrace>s
|
91
|
+
STR
|
108
92
|
|
109
|
-
|
110
|
-
|
111
|
-
|
93
|
+
register_template(:rack, <<~STR)
|
94
|
+
[%<progname>s] [%<severity>s] [%<time>s] \
|
95
|
+
%<verb>s %<status>s %<elapsed>s %<ip>s %<path>s %<length>s %<payload>s
|
96
|
+
%<params>s
|
97
|
+
STR
|
112
98
|
end
|
113
99
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -36,17 +36,23 @@ files:
|
|
36
36
|
- README.md
|
37
37
|
- dry-logger.gemspec
|
38
38
|
- lib/dry/logger.rb
|
39
|
+
- lib/dry/logger/backends/core.rb
|
39
40
|
- lib/dry/logger/backends/file.rb
|
40
41
|
- lib/dry/logger/backends/io.rb
|
42
|
+
- lib/dry/logger/backends/proxy.rb
|
41
43
|
- lib/dry/logger/backends/stream.rb
|
44
|
+
- lib/dry/logger/clock.rb
|
42
45
|
- lib/dry/logger/constants.rb
|
43
46
|
- lib/dry/logger/dispatcher.rb
|
44
47
|
- lib/dry/logger/entry.rb
|
45
48
|
- lib/dry/logger/filter.rb
|
49
|
+
- lib/dry/logger/formatters/colors.rb
|
46
50
|
- lib/dry/logger/formatters/json.rb
|
47
51
|
- lib/dry/logger/formatters/rack.rb
|
48
52
|
- lib/dry/logger/formatters/string.rb
|
49
53
|
- lib/dry/logger/formatters/structured.rb
|
54
|
+
- lib/dry/logger/formatters/template.rb
|
55
|
+
- lib/dry/logger/global.rb
|
50
56
|
- lib/dry/logger/version.rb
|
51
57
|
homepage: https://dry-rb.org/gems/dry-logger
|
52
58
|
licenses:
|
@@ -67,9 +73,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
67
73
|
version: '3.0'
|
68
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
75
|
requirements:
|
70
|
-
- - "
|
76
|
+
- - ">="
|
71
77
|
- !ruby/object:Gem::Version
|
72
|
-
version:
|
78
|
+
version: '0'
|
73
79
|
requirements: []
|
74
80
|
rubygems_version: 3.1.6
|
75
81
|
signing_key:
|