lumberjack 1.4.2 → 2.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/ARCHITECTURE.md +524 -176
- data/CHANGELOG.md +89 -0
- data/README.md +604 -211
- data/UPGRADE_GUIDE.md +80 -0
- data/VERSION +1 -1
- data/lib/lumberjack/attribute_formatter.rb +451 -0
- data/lib/lumberjack/attributes_helper.rb +100 -0
- data/lib/lumberjack/context.rb +120 -23
- data/lib/lumberjack/context_logger.rb +620 -0
- data/lib/lumberjack/device/buffer.rb +209 -0
- data/lib/lumberjack/device/date_rolling_log_file.rb +10 -62
- data/lib/lumberjack/device/log_file.rb +76 -29
- data/lib/lumberjack/device/logger_wrapper.rb +137 -0
- data/lib/lumberjack/device/multi.rb +92 -30
- data/lib/lumberjack/device/null.rb +26 -8
- data/lib/lumberjack/device/size_rolling_log_file.rb +13 -54
- data/lib/lumberjack/device/test.rb +337 -0
- data/lib/lumberjack/device/writer.rb +184 -176
- data/lib/lumberjack/device.rb +134 -15
- data/lib/lumberjack/device_registry.rb +90 -0
- data/lib/lumberjack/entry_formatter.rb +357 -0
- data/lib/lumberjack/fiber_locals.rb +55 -0
- data/lib/lumberjack/forked_logger.rb +143 -0
- data/lib/lumberjack/formatter/date_time_formatter.rb +14 -3
- data/lib/lumberjack/formatter/exception_formatter.rb +12 -2
- data/lib/lumberjack/formatter/id_formatter.rb +13 -1
- data/lib/lumberjack/formatter/inspect_formatter.rb +14 -1
- data/lib/lumberjack/formatter/multiply_formatter.rb +10 -0
- data/lib/lumberjack/formatter/object_formatter.rb +13 -1
- data/lib/lumberjack/formatter/pretty_print_formatter.rb +15 -2
- data/lib/lumberjack/formatter/redact_formatter.rb +18 -3
- data/lib/lumberjack/formatter/round_formatter.rb +12 -0
- data/lib/lumberjack/formatter/string_formatter.rb +9 -1
- data/lib/lumberjack/formatter/strip_formatter.rb +13 -1
- data/lib/lumberjack/formatter/structured_formatter.rb +18 -2
- data/lib/lumberjack/formatter/tagged_message.rb +10 -32
- data/lib/lumberjack/formatter/tags_formatter.rb +32 -0
- data/lib/lumberjack/formatter/truncate_formatter.rb +8 -1
- data/lib/lumberjack/formatter.rb +271 -141
- data/lib/lumberjack/formatter_registry.rb +84 -0
- data/lib/lumberjack/io_compatibility.rb +133 -0
- data/lib/lumberjack/local_log_template.rb +209 -0
- data/lib/lumberjack/log_entry.rb +154 -79
- data/lib/lumberjack/log_entry_matcher/score.rb +276 -0
- data/lib/lumberjack/log_entry_matcher.rb +126 -0
- data/lib/lumberjack/logger.rb +328 -556
- data/lib/lumberjack/message_attributes.rb +38 -0
- data/lib/lumberjack/rack/context.rb +66 -15
- data/lib/lumberjack/rack.rb +0 -2
- data/lib/lumberjack/remap_attribute.rb +24 -0
- data/lib/lumberjack/severity.rb +52 -15
- data/lib/lumberjack/tag_context.rb +8 -71
- data/lib/lumberjack/tag_formatter.rb +22 -188
- data/lib/lumberjack/tags.rb +15 -21
- data/lib/lumberjack/template.rb +252 -62
- data/lib/lumberjack/template_registry.rb +60 -0
- data/lib/lumberjack/utils.rb +198 -48
- data/lib/lumberjack.rb +167 -59
- data/lumberjack.gemspec +4 -2
- metadata +41 -15
- data/lib/lumberjack/device/rolling_log_file.rb +0 -145
- data/lib/lumberjack/rack/request_id.rb +0 -31
- data/lib/lumberjack/rack/unit_of_work.rb +0 -21
- data/lib/lumberjack/tagged_logger_support.rb +0 -81
- data/lib/lumberjack/tagged_logging.rb +0 -29
metadata
CHANGED
@@ -1,15 +1,28 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lumberjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Durand
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: logger
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '0'
|
13
26
|
- !ruby/object:Gem::Dependency
|
14
27
|
name: bundler
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,7 +37,6 @@ dependencies:
|
|
24
37
|
- - ">="
|
25
38
|
- !ruby/object:Gem::Version
|
26
39
|
version: '0'
|
27
|
-
description:
|
28
40
|
email:
|
29
41
|
- bbdurand@gmail.com
|
30
42
|
executables: []
|
@@ -35,17 +47,27 @@ files:
|
|
35
47
|
- CHANGELOG.md
|
36
48
|
- MIT_LICENSE.txt
|
37
49
|
- README.md
|
50
|
+
- UPGRADE_GUIDE.md
|
38
51
|
- VERSION
|
39
52
|
- lib/lumberjack.rb
|
53
|
+
- lib/lumberjack/attribute_formatter.rb
|
54
|
+
- lib/lumberjack/attributes_helper.rb
|
40
55
|
- lib/lumberjack/context.rb
|
56
|
+
- lib/lumberjack/context_logger.rb
|
41
57
|
- lib/lumberjack/device.rb
|
58
|
+
- lib/lumberjack/device/buffer.rb
|
42
59
|
- lib/lumberjack/device/date_rolling_log_file.rb
|
43
60
|
- lib/lumberjack/device/log_file.rb
|
61
|
+
- lib/lumberjack/device/logger_wrapper.rb
|
44
62
|
- lib/lumberjack/device/multi.rb
|
45
63
|
- lib/lumberjack/device/null.rb
|
46
|
-
- lib/lumberjack/device/rolling_log_file.rb
|
47
64
|
- lib/lumberjack/device/size_rolling_log_file.rb
|
65
|
+
- lib/lumberjack/device/test.rb
|
48
66
|
- lib/lumberjack/device/writer.rb
|
67
|
+
- lib/lumberjack/device_registry.rb
|
68
|
+
- lib/lumberjack/entry_formatter.rb
|
69
|
+
- lib/lumberjack/fiber_locals.rb
|
70
|
+
- lib/lumberjack/forked_logger.rb
|
49
71
|
- lib/lumberjack/formatter.rb
|
50
72
|
- lib/lumberjack/formatter/date_time_formatter.rb
|
51
73
|
- lib/lumberjack/formatter/exception_formatter.rb
|
@@ -60,20 +82,25 @@ files:
|
|
60
82
|
- lib/lumberjack/formatter/strip_formatter.rb
|
61
83
|
- lib/lumberjack/formatter/structured_formatter.rb
|
62
84
|
- lib/lumberjack/formatter/tagged_message.rb
|
85
|
+
- lib/lumberjack/formatter/tags_formatter.rb
|
63
86
|
- lib/lumberjack/formatter/truncate_formatter.rb
|
87
|
+
- lib/lumberjack/formatter_registry.rb
|
88
|
+
- lib/lumberjack/io_compatibility.rb
|
89
|
+
- lib/lumberjack/local_log_template.rb
|
64
90
|
- lib/lumberjack/log_entry.rb
|
91
|
+
- lib/lumberjack/log_entry_matcher.rb
|
92
|
+
- lib/lumberjack/log_entry_matcher/score.rb
|
65
93
|
- lib/lumberjack/logger.rb
|
94
|
+
- lib/lumberjack/message_attributes.rb
|
66
95
|
- lib/lumberjack/rack.rb
|
67
96
|
- lib/lumberjack/rack/context.rb
|
68
|
-
- lib/lumberjack/
|
69
|
-
- lib/lumberjack/rack/unit_of_work.rb
|
97
|
+
- lib/lumberjack/remap_attribute.rb
|
70
98
|
- lib/lumberjack/severity.rb
|
71
99
|
- lib/lumberjack/tag_context.rb
|
72
100
|
- lib/lumberjack/tag_formatter.rb
|
73
|
-
- lib/lumberjack/tagged_logger_support.rb
|
74
|
-
- lib/lumberjack/tagged_logging.rb
|
75
101
|
- lib/lumberjack/tags.rb
|
76
102
|
- lib/lumberjack/template.rb
|
103
|
+
- lib/lumberjack/template_registry.rb
|
77
104
|
- lib/lumberjack/utils.rb
|
78
105
|
- lumberjack.gemspec
|
79
106
|
homepage: https://github.com/bdurand/lumberjack
|
@@ -83,7 +110,6 @@ metadata:
|
|
83
110
|
homepage_uri: https://github.com/bdurand/lumberjack
|
84
111
|
source_code_uri: https://github.com/bdurand/lumberjack
|
85
112
|
changelog_uri: https://github.com/bdurand/lumberjack/blob/main/CHANGELOG.md
|
86
|
-
post_install_message:
|
87
113
|
rdoc_options: []
|
88
114
|
require_paths:
|
89
115
|
- lib
|
@@ -91,16 +117,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
117
|
requirements:
|
92
118
|
- - ">="
|
93
119
|
- !ruby/object:Gem::Version
|
94
|
-
version: 2.
|
120
|
+
version: '2.7'
|
95
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
122
|
requirements:
|
97
123
|
- - ">="
|
98
124
|
- !ruby/object:Gem::Version
|
99
125
|
version: '0'
|
100
126
|
requirements: []
|
101
|
-
rubygems_version: 3.
|
102
|
-
signing_key:
|
127
|
+
rubygems_version: 3.6.9
|
103
128
|
specification_version: 4
|
104
|
-
summary:
|
105
|
-
|
129
|
+
summary: Extension of Ruby’s standard Logger for advanced, structured logging. Includes
|
130
|
+
log entry attributes, context isolation, customizable formatters, flexible output
|
131
|
+
devices, and testing tools.
|
106
132
|
test_files: []
|
@@ -1,145 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lumberjack
|
4
|
-
class Device
|
5
|
-
# This is an abstract class for a device that appends entries to a file and periodically archives
|
6
|
-
# the existing file and starts a one. Subclasses must implement the roll_file? and archive_file_suffix
|
7
|
-
# methods.
|
8
|
-
#
|
9
|
-
# The :keep option can be used to specify a maximum number of rolled log files to keep.
|
10
|
-
# Older files will be deleted based on the time they were created. The default is to keep all files.
|
11
|
-
#
|
12
|
-
# The :min_roll_check option can be used to specify the number of seconds between checking
|
13
|
-
# the file to determine if it needs to be rolled. The default is to check at most once per second.
|
14
|
-
class RollingLogFile < LogFile
|
15
|
-
attr_reader :path
|
16
|
-
attr_accessor :keep
|
17
|
-
|
18
|
-
def initialize(path, options = {})
|
19
|
-
@path = File.expand_path(path)
|
20
|
-
@keep = options[:keep]
|
21
|
-
super
|
22
|
-
@file_inode = begin
|
23
|
-
stream.lstat.ino
|
24
|
-
rescue
|
25
|
-
nil
|
26
|
-
end
|
27
|
-
@@rolls = []
|
28
|
-
@next_stat_check = Time.now.to_f
|
29
|
-
@min_roll_check = (options[:min_roll_check] || 1.0).to_f
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns a suffix that will be appended to the file name when it is archived.. The suffix should
|
33
|
-
# change after it is time to roll the file. The log file will be renamed when it is rolled.
|
34
|
-
def archive_file_suffix
|
35
|
-
raise NotImplementedError
|
36
|
-
end
|
37
|
-
|
38
|
-
# Return +true+ if the file should be rolled.
|
39
|
-
def roll_file?
|
40
|
-
raise NotImplementedError
|
41
|
-
end
|
42
|
-
|
43
|
-
# Roll the log file by renaming it to the archive file name and then re-opening a stream to the log
|
44
|
-
# file path. Rolling a file is safe in multi-threaded or multi-process environments.
|
45
|
-
def roll_file! # :nodoc:
|
46
|
-
do_once(stream) do
|
47
|
-
archive_file = "#{path}.#{archive_file_suffix}"
|
48
|
-
stream.flush
|
49
|
-
current_inode = begin
|
50
|
-
File.stat(path).ino
|
51
|
-
rescue
|
52
|
-
nil
|
53
|
-
end
|
54
|
-
if @file_inode && current_inode == @file_inode && !File.exist?(archive_file) && File.exist?(path)
|
55
|
-
begin
|
56
|
-
File.rename(path, archive_file)
|
57
|
-
after_roll
|
58
|
-
cleanup_files!
|
59
|
-
rescue SystemCallError
|
60
|
-
# Ignore rename errors since it indicates the file was already rolled
|
61
|
-
end
|
62
|
-
end
|
63
|
-
reopen_file
|
64
|
-
end
|
65
|
-
rescue => e
|
66
|
-
$stderr.write("Failed to roll file #{path}: #{e.inspect}\n#{e.backtrace.join("\n")}\n")
|
67
|
-
end
|
68
|
-
|
69
|
-
protected
|
70
|
-
|
71
|
-
# This method will be called after a file has been rolled. Subclasses can
|
72
|
-
# implement code to reset the state of the device. This method is thread safe.
|
73
|
-
def after_roll
|
74
|
-
end
|
75
|
-
|
76
|
-
# Handle rolling the file before flushing.
|
77
|
-
def before_flush # :nodoc:
|
78
|
-
if @min_roll_check <= 0.0 || Time.now.to_f >= @next_stat_check
|
79
|
-
@next_stat_check += @min_roll_check
|
80
|
-
path_inode = begin
|
81
|
-
File.lstat(path).ino
|
82
|
-
rescue
|
83
|
-
nil
|
84
|
-
end
|
85
|
-
if path_inode != @file_inode
|
86
|
-
@file_inode = path_inode
|
87
|
-
reopen_file
|
88
|
-
elsif roll_file?
|
89
|
-
roll_file!
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def reopen_file
|
97
|
-
old_stream = stream
|
98
|
-
new_stream = File.open(path, "a", encoding: EXTERNAL_ENCODING)
|
99
|
-
new_stream.sync = true if buffer_size > 0
|
100
|
-
@file_inode = begin
|
101
|
-
new_stream.lstat.ino
|
102
|
-
rescue
|
103
|
-
nil
|
104
|
-
end
|
105
|
-
self.stream = new_stream
|
106
|
-
old_stream.close
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def cleanup_files!
|
111
|
-
if keep
|
112
|
-
files = Dir.glob("#{path}.*").collect { |f| [f, File.ctime(f)] }.sort { |a, b| b.last <=> a.last }.collect { |a| a.first }
|
113
|
-
if files.size > keep
|
114
|
-
files[keep, files.length].each do |f|
|
115
|
-
File.delete(f)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def do_once(file)
|
122
|
-
begin
|
123
|
-
file.flock(File::LOCK_EX)
|
124
|
-
rescue SystemCallError
|
125
|
-
# Most likely can't lock file because the stream is closed
|
126
|
-
return
|
127
|
-
end
|
128
|
-
begin
|
129
|
-
verify = begin
|
130
|
-
file.lstat
|
131
|
-
rescue
|
132
|
-
nil
|
133
|
-
end
|
134
|
-
# Execute only if the file we locked is still the same one that needed to be rolled
|
135
|
-
yield if verify && verify.ino == @file_inode && verify.size > 0
|
136
|
-
ensure
|
137
|
-
begin
|
138
|
-
file.flock(File::LOCK_UN)
|
139
|
-
rescue
|
140
|
-
nil
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lumberjack
|
4
|
-
module Rack
|
5
|
-
# Support for using the Rails ActionDispatch request id in the log.
|
6
|
-
# The format is expected to be a random UUID and only the first chunk is used for terseness
|
7
|
-
# if the abbreviated argument is true.
|
8
|
-
#
|
9
|
-
# @deprecated Use tags instead of request id for unit of work. Will be removed in version 2.0.
|
10
|
-
class RequestId
|
11
|
-
REQUEST_ID = "action_dispatch.request_id"
|
12
|
-
|
13
|
-
def initialize(app, abbreviated = false)
|
14
|
-
Lumberjack::Utils.deprecated("Lumberjack::Rack::RequestId", "Lumberjack::Rack::RequestId will be removed in version 2.0") do
|
15
|
-
@app = app
|
16
|
-
@abbreviated = abbreviated
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def call(env)
|
21
|
-
request_id = env[REQUEST_ID]
|
22
|
-
if request_id && @abbreviated
|
23
|
-
request_id = request_id.split("-", 2).first
|
24
|
-
end
|
25
|
-
Lumberjack.unit_of_work(request_id) do
|
26
|
-
@app.call(env)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lumberjack
|
4
|
-
module Rack
|
5
|
-
# @deprecated Use the Lumberjack::Rack::Context middleware instead to set a global tag
|
6
|
-
# with an identifier to tie log entries together in a unit of work. Will be removed in version 2.0.
|
7
|
-
class UnitOfWork
|
8
|
-
def initialize(app)
|
9
|
-
Lumberjack::Utils.deprecated("Lumberjack::Rack::UnitOfWork", "Lumberjack::Rack::UnitOfWork will be removed in version 2.0") do
|
10
|
-
@app = app
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def call(env)
|
15
|
-
Lumberjack.unit_of_work do
|
16
|
-
@app.call(env)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "delegate"
|
4
|
-
require "forwardable"
|
5
|
-
|
6
|
-
module Lumberjack
|
7
|
-
# Methods to make Lumberjack::Logger API compatible with ActiveSupport::TaggedLogger.
|
8
|
-
module TaggedLoggerSupport
|
9
|
-
class Formatter < DelegateClass(Lumberjack::Formatter)
|
10
|
-
extend Forwardable
|
11
|
-
def_delegators :@logger, :tagged, :push_tags, :pop_tags, :clear_tags!
|
12
|
-
|
13
|
-
def initialize(formatter:, logger:)
|
14
|
-
@logger = logger
|
15
|
-
@formatter = formatter
|
16
|
-
super(formatter)
|
17
|
-
end
|
18
|
-
|
19
|
-
def current_tags
|
20
|
-
tags = @logger.instance_variable_get(:@tags)
|
21
|
-
if tags.is_a?(Hash)
|
22
|
-
Array(tags["tagged"])
|
23
|
-
else
|
24
|
-
[]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def tags_text
|
29
|
-
tags = current_tags
|
30
|
-
if tags.any?
|
31
|
-
tags.collect { |tag| "[#{tag}] " }.join
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def __formatter
|
36
|
-
@formatter
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# Compatibility with ActiveSupport::TaggedLogging which only supports adding tags as strings.
|
41
|
-
# Tags will be added to the "tagged" key in the logger's tags hash as an array.
|
42
|
-
def tagged(*tags, &block)
|
43
|
-
tagged_values = Array(tag_value("tagged"))
|
44
|
-
flattened_tags = tags.flatten.collect(&:to_s).reject do |tag|
|
45
|
-
tag.respond_to?(:blank?) ? tag.blank? : tag.empty?
|
46
|
-
end
|
47
|
-
tagged_values += flattened_tags unless flattened_tags.empty?
|
48
|
-
|
49
|
-
if block || in_tag_context?
|
50
|
-
tag("tagged" => tagged_values, &block)
|
51
|
-
else
|
52
|
-
tag_globally("tagged" => tagged_values)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def push_tags(*tags)
|
57
|
-
tagged(*tags)
|
58
|
-
end
|
59
|
-
|
60
|
-
def pop_tags(size = 1)
|
61
|
-
tagged_values = tag_value("tagged")
|
62
|
-
return unless tagged_values.is_a?(Array)
|
63
|
-
|
64
|
-
tagged_values = ((tagged_values.size > size) ? tagged_values[0, tagged_values.size - size] : nil)
|
65
|
-
|
66
|
-
if in_tag_context?
|
67
|
-
tag("tagged" => tagged_values)
|
68
|
-
else
|
69
|
-
tag_globally("tagged" => tagged_values)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def clear_tags!
|
74
|
-
if in_tag_context?
|
75
|
-
tag("tagged" => nil)
|
76
|
-
else
|
77
|
-
tag_globally("tagged" => nil)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Lumberjack
|
4
|
-
# Monkey patch for ActiveSupport::TaggedLogger so it doesn't blow up when
|
5
|
-
# a Lumberjack logger is trying to be wrapped. This module will be automatically
|
6
|
-
# included in ActiveSupport::TaggedLogger if activesupport is already loaded.
|
7
|
-
module TaggedLogging
|
8
|
-
class << self
|
9
|
-
def included(base)
|
10
|
-
base.singleton_class.send(:prepend, ClassMethods)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
def new(logger)
|
16
|
-
if logger.is_a?(Lumberjack::Logger)
|
17
|
-
logger = logger.tagged_logger! unless logger.respond_to?(:tagged)
|
18
|
-
logger
|
19
|
-
else
|
20
|
-
super
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
if defined?(ActiveSupport::TaggedLogging)
|
28
|
-
ActiveSupport::TaggedLogging.include(Lumberjack::TaggedLogging)
|
29
|
-
end
|