timber 2.0.24 → 2.1.0.rc1
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/.travis.yml +2 -2
- data/CHANGELOG +3 -0
- data/README.md +314 -59
- data/bin/timber +11 -2
- data/lib/timber.rb +2 -7
- data/lib/timber/cli.rb +16 -28
- data/lib/timber/cli/api.rb +80 -14
- data/lib/timber/cli/api/application.rb +30 -0
- data/lib/timber/cli/config_file.rb +66 -0
- data/lib/timber/cli/file_helper.rb +43 -0
- data/lib/timber/cli/installer.rb +58 -0
- data/lib/timber/cli/installers.rb +37 -0
- data/lib/timber/cli/installers/other.rb +47 -0
- data/lib/timber/cli/installers/rails.rb +255 -0
- data/lib/timber/cli/installers/root.rb +189 -0
- data/lib/timber/cli/io.rb +97 -0
- data/lib/timber/cli/io/ansi.rb +22 -0
- data/lib/timber/cli/io/messages.rb +213 -0
- data/lib/timber/cli/os_helper.rb +53 -0
- data/lib/timber/config.rb +97 -43
- data/lib/timber/config/integrations.rb +63 -0
- data/lib/timber/config/integrations/rack.rb +74 -0
- data/lib/timber/context.rb +13 -10
- data/lib/timber/contexts.rb +1 -0
- data/lib/timber/contexts/custom.rb +16 -3
- data/lib/timber/contexts/http.rb +10 -3
- data/lib/timber/contexts/organization.rb +4 -0
- data/lib/timber/contexts/release.rb +46 -0
- data/lib/timber/contexts/runtime.rb +7 -1
- data/lib/timber/contexts/session.rb +8 -1
- data/lib/timber/contexts/system.rb +5 -1
- data/lib/timber/contexts/user.rb +9 -2
- data/lib/timber/current_context.rb +43 -11
- data/lib/timber/events/controller_call.rb +4 -0
- data/lib/timber/events/custom.rb +13 -5
- data/lib/timber/events/exception.rb +4 -0
- data/lib/timber/events/http_client_request.rb +4 -0
- data/lib/timber/events/http_client_response.rb +4 -0
- data/lib/timber/events/http_server_request.rb +5 -0
- data/lib/timber/events/http_server_response.rb +15 -3
- data/lib/timber/events/sql_query.rb +3 -0
- data/lib/timber/events/template_render.rb +3 -0
- data/lib/timber/integration.rb +40 -0
- data/lib/timber/integrations.rb +21 -14
- data/lib/timber/integrations/action_controller.rb +18 -0
- data/lib/timber/integrations/action_controller/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +6 -0
- data/lib/timber/integrations/action_dispatch.rb +23 -0
- data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +2 -0
- data/lib/timber/integrations/action_view.rb +18 -0
- data/lib/timber/integrations/action_view/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +10 -0
- data/lib/timber/integrations/active_record.rb +18 -0
- data/lib/timber/integrations/active_record/log_subscriber.rb +2 -0
- data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +8 -0
- data/lib/timber/integrations/rack.rb +12 -2
- data/lib/timber/integrations/rack/exception_event.rb +38 -5
- data/lib/timber/integrations/rack/http_context.rb +4 -6
- data/lib/timber/integrations/rack/http_events.rb +177 -27
- data/lib/timber/integrations/rack/middleware.rb +28 -0
- data/lib/timber/integrations/rack/session_context.rb +5 -6
- data/lib/timber/integrations/rack/user_context.rb +90 -43
- data/lib/timber/integrations/rails.rb +22 -0
- data/lib/timber/integrations/rails/rack_logger.rb +2 -0
- data/lib/timber/integrator.rb +18 -3
- data/lib/timber/log_devices/http.rb +107 -99
- data/lib/timber/log_devices/http/dropping_sized_queue.rb +26 -0
- data/lib/timber/log_devices/http/flushable_sized_queue.rb +42 -0
- data/lib/timber/log_entry.rb +14 -2
- data/lib/timber/logger.rb +51 -36
- data/lib/timber/overrides.rb +2 -0
- data/lib/timber/overrides/active_support_3_tagged_logging.rb +103 -0
- data/lib/timber/overrides/active_support_tagged_logging.rb +53 -90
- data/lib/timber/timer.rb +21 -0
- data/lib/timber/util/hash.rb +1 -1
- data/lib/timber/util/http_event.rb +16 -3
- data/lib/timber/version.rb +1 -1
- data/spec/support/timber.rb +2 -3
- data/spec/timber/cli/installers/rails_spec.rb +160 -0
- data/spec/timber/cli/installers/root_spec.rb +100 -0
- data/spec/timber/config_spec.rb +28 -0
- data/spec/timber/current_context_spec.rb +61 -12
- data/spec/timber/events/custom_spec.rb +13 -2
- data/spec/timber/events/exception_spec.rb +15 -0
- data/spec/timber/events/http_server_request_spec.rb +3 -3
- data/spec/timber/integrations/rack/http_events_spec.rb +101 -0
- data/spec/timber/log_devices/http_spec.rb +20 -4
- data/spec/timber/log_entry_spec.rb +2 -1
- data/spec/timber/logger_spec.rb +8 -8
- metadata +40 -9
- data/benchmarks/rails.rb +0 -122
- data/lib/timber/cli/application.rb +0 -28
- data/lib/timber/cli/install.rb +0 -196
- data/lib/timber/cli/io_helper.rb +0 -65
- data/lib/timber/cli/messages.rb +0 -180
- data/lib/timber/integrations/active_support/tagged_logging.rb +0 -71
data/lib/timber/log_entry.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'socket'
|
2
2
|
|
3
|
+
require "timber/contexts"
|
4
|
+
require "timber/events"
|
5
|
+
|
3
6
|
module Timber
|
4
7
|
# Represents a new log entry into the log. This is an intermediary class between
|
5
8
|
# `Logger` and the log device that you set it up with.
|
@@ -32,6 +35,9 @@ module Timber
|
|
32
35
|
@time_ms = options[:time_ms]
|
33
36
|
|
34
37
|
context_snapshot = {} if context_snapshot.nil?
|
38
|
+
|
39
|
+
# Set the system context for each log entry since processes can be forked
|
40
|
+
# and the process ID could change.
|
35
41
|
hostname = Socket.gethostname
|
36
42
|
pid = Process.pid
|
37
43
|
system_context = Contexts::System.new(hostname: hostname, pid: pid)
|
@@ -41,10 +47,16 @@ module Timber
|
|
41
47
|
@event = event
|
42
48
|
end
|
43
49
|
|
50
|
+
# Builds a hash representation of containing simply objects, suitable for serialization.
|
44
51
|
def as_json(options = {})
|
45
52
|
options ||= {}
|
46
|
-
hash = {
|
47
|
-
:
|
53
|
+
hash = {
|
54
|
+
:level => level,
|
55
|
+
:dt => formatted_dt,
|
56
|
+
:message => message,
|
57
|
+
:tags => tags,
|
58
|
+
:time_ms => time_ms
|
59
|
+
}
|
48
60
|
|
49
61
|
if !event.nil?
|
50
62
|
hash[:event] = event.as_json
|
data/lib/timber/logger.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
require "logger"
|
2
2
|
require "msgpack"
|
3
3
|
|
4
|
+
require "timber/current_context"
|
5
|
+
require "timber/event"
|
6
|
+
require "timber/log_devices/http"
|
7
|
+
require "timber/log_entry"
|
8
|
+
|
4
9
|
module Timber
|
5
10
|
# The Timber Logger behaves exactly like `::Logger`, except that it supports a transparent API
|
6
11
|
# for logging structured messages. It ensures your log messages are communicated properly
|
@@ -72,47 +77,49 @@ module Timber
|
|
72
77
|
"FATAL" => :fatal,
|
73
78
|
"UNKNOWN" => :unknown
|
74
79
|
}
|
80
|
+
EMPTY_ARRAY = []
|
75
81
|
|
76
82
|
private
|
77
|
-
def build_log_entry(severity, time, progname,
|
78
|
-
level = SEVERITY_MAP.fetch(severity)
|
83
|
+
def build_log_entry(severity, time, progname, logged_obj)
|
79
84
|
context_snapshot = CurrentContext.instance.snapshot
|
80
|
-
|
85
|
+
level = SEVERITY_MAP.fetch(severity)
|
81
86
|
tags = extract_active_support_tagged_logging_tags
|
82
|
-
time_ms = nil
|
83
|
-
if msg.is_a?(Hash)
|
84
|
-
if msg.key?(:tag) || msg.key?(:tags)
|
85
|
-
tags = tags.clone
|
86
|
-
tags << msg.delete(:tag) if msg.key?(:tag)
|
87
|
-
tags += msg.delete(:tags) if msg.key?(:tags)
|
88
|
-
tags.uniq!
|
89
|
-
end
|
90
|
-
time_ms = msg.delete(:time_ms) if msg.key?(:time_ms)
|
91
|
-
|
92
|
-
msg = msg[:message] if msg.length == 1
|
93
|
-
end
|
94
87
|
|
95
|
-
|
88
|
+
if logged_obj.is_a?(Event)
|
89
|
+
LogEntry.new(level, time, progname, logged_obj.message, context_snapshot, logged_obj,
|
90
|
+
tags: tags)
|
91
|
+
elsif logged_obj.is_a?(Hash)
|
92
|
+
# Extract the tags
|
93
|
+
tags = tags.clone
|
94
|
+
tags << logged_obj.delete(:tag) if logged_obj.key?(:tag)
|
95
|
+
tags += logged_obj.delete(:tags) if logged_obj.key?(:tags)
|
96
|
+
tags.uniq!
|
97
|
+
|
98
|
+
# Extract the time_ms
|
99
|
+
time_ms = logged_obj.delete(:time_ms)
|
96
100
|
|
97
|
-
|
98
|
-
|
101
|
+
# Build the event
|
102
|
+
event = Events.build(logged_obj)
|
103
|
+
message = event ? event.message : logged_obj[:message]
|
104
|
+
|
105
|
+
LogEntry.new(level, time, progname, message, context_snapshot, event, tags: tags,
|
106
|
+
time_ms: time_ms)
|
99
107
|
else
|
100
|
-
LogEntry.new(level, time, progname,
|
108
|
+
LogEntry.new(level, time, progname, logged_obj, context_snapshot, nil, tags: tags)
|
101
109
|
end
|
102
110
|
end
|
103
111
|
|
104
|
-
# Because of all the crazy ways Rails has attempted
|
112
|
+
# Because of all the crazy ways Rails has attempted tags, we need this crazy method.
|
105
113
|
def extract_active_support_tagged_logging_tags
|
106
114
|
Thread.current[:activesupport_tagged_logging_tags] ||
|
107
115
|
Thread.current["activesupport_tagged_logging_tags:#{object_id}"] ||
|
108
|
-
|
116
|
+
EMPTY_ARRAY
|
109
117
|
end
|
110
118
|
end
|
111
119
|
|
112
120
|
# For use in development and test environments where you do not want metadata
|
113
121
|
# included in the log lines.
|
114
|
-
class
|
115
|
-
|
122
|
+
class MessageOnlyFormatter < Formatter
|
116
123
|
# This method is invoked when a log event occurs
|
117
124
|
def call(severity, timestamp, progname, msg)
|
118
125
|
log_entry = build_log_entry(severity, timestamp, progname, msg)
|
@@ -127,19 +134,17 @@ module Timber
|
|
127
134
|
#
|
128
135
|
# My log message @metadata {"level":"info","dt":"2016-09-01T07:00:00.000000-05:00"}
|
129
136
|
#
|
130
|
-
class
|
131
|
-
METADATA_CALLOUT = "@metadata".freeze
|
137
|
+
class AugmentedFormatter < Formatter
|
138
|
+
METADATA_CALLOUT = " @metadata ".freeze
|
139
|
+
NEW_LINE = "\n".freeze
|
140
|
+
ESCAPED_NEW_LINE = "\\n".freeze
|
132
141
|
|
133
142
|
def call(severity, time, progname, msg)
|
134
143
|
log_entry = build_log_entry(severity, time, progname, msg)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
log_entry.message.gsub("\n", "\\n") << " " << METADATA_CALLOUT << " " << metadata << "\n"
|
140
|
-
else
|
141
|
-
log_entry.message + "\n"
|
142
|
-
end
|
144
|
+
metadata = log_entry.to_json(:except => [:message])
|
145
|
+
# use << for concatenation for performance reasons
|
146
|
+
log_entry.message.gsub(NEW_LINE, ESCAPED_NEW_LINE) << METADATA_CALLOUT <<
|
147
|
+
metadata << NEW_LINE
|
143
148
|
end
|
144
149
|
end
|
145
150
|
|
@@ -176,7 +181,7 @@ module Timber
|
|
176
181
|
include ::LoggerSilence if defined?(::LoggerSilence)
|
177
182
|
|
178
183
|
# Creates a new Timber::Logger instances. Accepts the same arguments as `::Logger.new`.
|
179
|
-
# The only difference is that it default the formatter to {
|
184
|
+
# The only difference is that it default the formatter to {AugmentedFormatter}. Using
|
180
185
|
# a different formatter is easy. For example, if you prefer your logs in JSON.
|
181
186
|
#
|
182
187
|
# @example Changing your formatter
|
@@ -193,7 +198,7 @@ module Timber
|
|
193
198
|
if args.size == 1 and args.first.is_a?(LogDevices::HTTP)
|
194
199
|
self.formatter = PassThroughFormatter.new
|
195
200
|
else
|
196
|
-
self.formatter =
|
201
|
+
self.formatter = AugmentedFormatter.new
|
197
202
|
end
|
198
203
|
|
199
204
|
self.level = environment_level
|
@@ -203,6 +208,9 @@ module Timber
|
|
203
208
|
@initialized = true
|
204
209
|
end
|
205
210
|
|
211
|
+
# Sets a new formatted on the logger.
|
212
|
+
#
|
213
|
+
# @note The formatter cannot be changed if you are using the HTTP logger backend.
|
206
214
|
def formatter=(value)
|
207
215
|
if @initialized && @logdev && @logdev.dev.is_a?(Timber::LogDevices::HTTP) && !value.is_a?(PassThroughFormatter)
|
208
216
|
raise ArgumentError.new("The formatter cannot be changed when using the " +
|
@@ -219,6 +227,13 @@ module Timber
|
|
219
227
|
Timber::CurrentContext.with(context, &block)
|
220
228
|
end
|
221
229
|
|
230
|
+
# Patch to ensure that the {#level} method is used instead of `@level`.
|
231
|
+
# This is required because of Rails' monkey patching on Logger via `::LoggerSilence`.
|
232
|
+
def add(severity, message = nil, progname = nil, &block)
|
233
|
+
return true if @logdev.nil? || (severity || UNKNOWN) < level
|
234
|
+
super
|
235
|
+
end
|
236
|
+
|
222
237
|
# Backwards compatibility with older ActiveSupport::Logger versions
|
223
238
|
Logger::Severity.constants.each do |severity|
|
224
239
|
class_eval(<<-EOT, __FILE__, __LINE__ + 1)
|
@@ -226,7 +241,7 @@ module Timber
|
|
226
241
|
progname = args.first
|
227
242
|
options = args.last
|
228
243
|
|
229
|
-
if args.length == 2 and options.is_a?(Hash) && options
|
244
|
+
if args.length == 2 and options.is_a?(Hash) && options.length > 0
|
230
245
|
progname = options.merge(message: progname)
|
231
246
|
end
|
232
247
|
|
data/lib/timber/overrides.rb
CHANGED
@@ -0,0 +1,103 @@
|
|
1
|
+
# This patch is specifically for Rails 3. The legacy approach to wrapping the logger in
|
2
|
+
# ActiveSupport::TaggedLogging is rather poor, hence the reason it was changed entirely
|
3
|
+
# for Rails 4 and 5. The problem is that ActiveSupport::TaggedLogging is a wrapping
|
4
|
+
# class that entirely redefines the public API for the logger. As a result, any deviations
|
5
|
+
# from this API in the logger are not exposed (such as accepting event data as a second argument).
|
6
|
+
# This is assuming, so we're fixing it here.
|
7
|
+
|
8
|
+
begin
|
9
|
+
require "active_support/tagged_logging"
|
10
|
+
|
11
|
+
# Instead of patching the class we're pulling the code from Rails master. This brings in
|
12
|
+
# a number of improvements while also addressing the issue above.
|
13
|
+
if ActiveSupport::TaggedLogging.instance_of?(Class)
|
14
|
+
ActiveSupport.send(:remove_const, :TaggedLogging)
|
15
|
+
|
16
|
+
require "active_support/core_ext/module/delegation"
|
17
|
+
require "active_support/core_ext/object/blank"
|
18
|
+
require "logger"
|
19
|
+
|
20
|
+
module ActiveSupport
|
21
|
+
# Wraps any standard Logger object to provide tagging capabilities.
|
22
|
+
#
|
23
|
+
# logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
24
|
+
# logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff"
|
25
|
+
# logger.tagged('BCX', "Jason") { logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff"
|
26
|
+
# logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff"
|
27
|
+
#
|
28
|
+
# This is used by the default Rails.logger as configured by Railties to make
|
29
|
+
# it easy to stamp log lines with subdomains, request ids, and anything else
|
30
|
+
# to aid debugging of multi-user production applications.
|
31
|
+
module TaggedLogging
|
32
|
+
module Formatter # :nodoc:
|
33
|
+
# This method is invoked when a log event occurs.
|
34
|
+
def call(severity, timestamp, progname, msg)
|
35
|
+
super(severity, timestamp, progname, "#{tags_text}#{msg}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def tagged(*tags)
|
39
|
+
new_tags = push_tags(*tags)
|
40
|
+
yield self
|
41
|
+
ensure
|
42
|
+
pop_tags(new_tags.size)
|
43
|
+
end
|
44
|
+
|
45
|
+
def push_tags(*tags)
|
46
|
+
tags.flatten.reject(&:blank?).tap do |new_tags|
|
47
|
+
current_tags.concat new_tags
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def pop_tags(size = 1)
|
52
|
+
current_tags.pop size
|
53
|
+
end
|
54
|
+
|
55
|
+
def clear_tags!
|
56
|
+
current_tags.clear
|
57
|
+
end
|
58
|
+
|
59
|
+
def current_tags
|
60
|
+
# We use our object ID here to avoid conflicting with other instances
|
61
|
+
thread_key = @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}".freeze
|
62
|
+
Thread.current[thread_key] ||= []
|
63
|
+
end
|
64
|
+
|
65
|
+
def tags_text
|
66
|
+
tags = current_tags
|
67
|
+
if tags.any?
|
68
|
+
tags.collect { |tag| "[#{tag}] " }.join
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Simple formatter which only displays the message.
|
74
|
+
class SimpleFormatter < ::Logger::Formatter
|
75
|
+
# This method is invoked when a log event occurs
|
76
|
+
def call(severity, timestamp, progname, msg)
|
77
|
+
"#{String === msg ? msg : msg.inspect}\n"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.new(logger)
|
82
|
+
# Ensure we set a default formatter so we aren't extending nil!
|
83
|
+
logger.formatter ||= SimpleFormatter.new
|
84
|
+
logger.formatter.extend Formatter
|
85
|
+
logger.extend(self)
|
86
|
+
end
|
87
|
+
|
88
|
+
delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
|
89
|
+
|
90
|
+
def tagged(*tags)
|
91
|
+
formatter.tagged(*tags) { yield self }
|
92
|
+
end
|
93
|
+
|
94
|
+
def flush
|
95
|
+
clear_tags!
|
96
|
+
super if defined?(super)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
rescue Exception
|
103
|
+
end
|
@@ -1,103 +1,66 @@
|
|
1
|
-
# This
|
2
|
-
# ActiveSupport::TaggedLogging is
|
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
|
-
# This is used by the default Rails.logger as configured by Railties to make
|
29
|
-
# it easy to stamp log lines with subdomains, request ids, and anything else
|
30
|
-
# to aid debugging of multi-user production applications.
|
31
|
-
module TaggedLogging
|
32
|
-
module Formatter # :nodoc:
|
33
|
-
# This method is invoked when a log event occurs.
|
34
|
-
def call(severity, timestamp, progname, msg)
|
35
|
-
super(severity, timestamp, progname, "#{tags_text}#{msg}")
|
36
|
-
end
|
37
|
-
|
38
|
-
def tagged(*tags)
|
39
|
-
new_tags = push_tags(*tags)
|
40
|
-
yield self
|
41
|
-
ensure
|
42
|
-
pop_tags(new_tags.size)
|
43
|
-
end
|
44
|
-
|
45
|
-
def push_tags(*tags)
|
46
|
-
tags.flatten.reject(&:blank?).tap do |new_tags|
|
47
|
-
current_tags.concat new_tags
|
1
|
+
# This is an override instead of an integration because without this Timber would not
|
2
|
+
# work properly if ActiveSupport::TaggedLogging is used.
|
3
|
+
#
|
4
|
+
# This is called after 'active_support_3_tagged_logging' where the constant is loaded and
|
5
|
+
# replaced. I want to make sure we don't attempt to load it again undoing the patches
|
6
|
+
# applied there.
|
7
|
+
if defined?(ActiveSupport::TaggedLogging)
|
8
|
+
module Timber
|
9
|
+
module Overrides
|
10
|
+
# @private
|
11
|
+
module ActiveSupportTaggedLogging
|
12
|
+
# @private
|
13
|
+
module FormatterMethods
|
14
|
+
def self.included(mod)
|
15
|
+
mod.module_eval do
|
16
|
+
alias_method :_timber_original_push_tags, :push_tags
|
17
|
+
alias_method :_timber_original_pop_tags, :pop_tags
|
18
|
+
|
19
|
+
def call(severity, timestamp, progname, msg)
|
20
|
+
if is_a?(Timber::Logger::Formatter)
|
21
|
+
# Don't convert the message into a string
|
22
|
+
super(severity, timestamp, progname, msg)
|
23
|
+
else
|
24
|
+
super(severity, timestamp, progname, "#{tags_text}#{msg}")
|
25
|
+
end
|
26
|
+
end
|
48
27
|
end
|
49
28
|
end
|
29
|
+
end
|
50
30
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
31
|
+
# @private
|
32
|
+
module LoggerMethods
|
33
|
+
def self.included(klass)
|
34
|
+
klass.class_eval do
|
35
|
+
def add(severity, message = nil, progname = nil, &block)
|
36
|
+
if message.nil?
|
37
|
+
if block_given?
|
38
|
+
message = block.call
|
39
|
+
else
|
40
|
+
message = progname
|
41
|
+
progname = nil #No instance variable for this like Logger
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if @logger.is_a?(Timber::Logger)
|
45
|
+
@logger.add(severity, message, progname)
|
46
|
+
else
|
47
|
+
@logger.add(severity, "#{tags_text}#{message}", progname)
|
48
|
+
end
|
49
|
+
end
|
69
50
|
end
|
70
51
|
end
|
71
52
|
end
|
72
53
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
54
|
+
if defined?(::ActiveSupport::TaggedLogging::Formatter)
|
55
|
+
if !::ActiveSupport::TaggedLogging::Formatter.include?(FormatterMethods)
|
56
|
+
::ActiveSupport::TaggedLogging::Formatter.send(:include, FormatterMethods)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
if !::ActiveSupport::TaggedLogging.include?(LoggerMethods)
|
60
|
+
::ActiveSupport::TaggedLogging.send(:include, LoggerMethods)
|
78
61
|
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.new(logger)
|
82
|
-
# Ensure we set a default formatter so we aren't extending nil!
|
83
|
-
logger.formatter ||= SimpleFormatter.new
|
84
|
-
logger.formatter.extend Formatter
|
85
|
-
logger.extend(self)
|
86
|
-
end
|
87
|
-
|
88
|
-
delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter
|
89
|
-
|
90
|
-
def tagged(*tags)
|
91
|
-
formatter.tagged(*tags) { yield self }
|
92
|
-
end
|
93
|
-
|
94
|
-
def flush
|
95
|
-
clear_tags!
|
96
|
-
super if defined?(super)
|
97
62
|
end
|
98
63
|
end
|
99
64
|
end
|
100
65
|
end
|
101
|
-
|
102
|
-
rescue Exception
|
103
66
|
end
|