semantic_logger 4.0.0 → 4.1.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/README.md +55 -8
- data/lib/semantic_logger.rb +1 -2
- data/lib/semantic_logger/ansi_colors.rb +1 -2
- data/lib/semantic_logger/appender.rb +17 -15
- data/lib/semantic_logger/appender/bugsnag.rb +5 -4
- data/lib/semantic_logger/appender/elasticsearch.rb +102 -16
- data/lib/semantic_logger/appender/elasticsearch_http.rb +76 -0
- data/lib/semantic_logger/appender/file.rb +9 -25
- data/lib/semantic_logger/appender/graylog.rb +43 -38
- data/lib/semantic_logger/appender/honeybadger.rb +3 -5
- data/lib/semantic_logger/appender/http.rb +12 -15
- data/lib/semantic_logger/appender/kafka.rb +183 -0
- data/lib/semantic_logger/appender/mongodb.rb +3 -3
- data/lib/semantic_logger/appender/new_relic.rb +3 -7
- data/lib/semantic_logger/appender/sentry.rb +2 -5
- data/lib/semantic_logger/appender/splunk.rb +7 -10
- data/lib/semantic_logger/appender/splunk_http.rb +16 -16
- data/lib/semantic_logger/appender/syslog.rb +43 -122
- data/lib/semantic_logger/appender/tcp.rb +28 -9
- data/lib/semantic_logger/appender/udp.rb +4 -7
- data/lib/semantic_logger/appender/wrapper.rb +3 -7
- data/lib/semantic_logger/base.rb +47 -7
- data/lib/semantic_logger/formatters/base.rb +29 -10
- data/lib/semantic_logger/formatters/color.rb +75 -45
- data/lib/semantic_logger/formatters/default.rb +53 -28
- data/lib/semantic_logger/formatters/json.rb +7 -8
- data/lib/semantic_logger/formatters/raw.rb +97 -1
- data/lib/semantic_logger/formatters/syslog.rb +46 -80
- data/lib/semantic_logger/formatters/syslog_cee.rb +57 -0
- data/lib/semantic_logger/log.rb +17 -67
- data/lib/semantic_logger/logger.rb +17 -27
- data/lib/semantic_logger/processor.rb +70 -46
- data/lib/semantic_logger/semantic_logger.rb +130 -69
- data/lib/semantic_logger/subscriber.rb +18 -32
- data/lib/semantic_logger/version.rb +1 -1
- data/test/appender/elasticsearch_http_test.rb +75 -0
- data/test/appender/elasticsearch_test.rb +34 -27
- data/test/appender/file_test.rb +2 -2
- data/test/appender/honeybadger_test.rb +1 -1
- data/test/appender/kafka_test.rb +36 -0
- data/test/appender/new_relic_test.rb +1 -1
- data/test/appender/sentry_test.rb +1 -1
- data/test/appender/syslog_test.rb +2 -2
- data/test/appender/wrapper_test.rb +1 -1
- data/test/formatters/color_test.rb +154 -0
- data/test/formatters/default_test.rb +176 -0
- data/test/loggable_test.rb +1 -1
- data/test/logger_test.rb +47 -4
- data/test/measure_test.rb +2 -2
- data/test/semantic_logger_test.rb +34 -6
- data/test/test_helper.rb +8 -0
- metadata +14 -3
@@ -4,24 +4,43 @@ module SemanticLogger
|
|
4
4
|
# Start the appender thread
|
5
5
|
def self.start
|
6
6
|
return false if active?
|
7
|
-
|
8
|
-
raise 'Failed to start Appender Thread' unless
|
7
|
+
@thread = Thread.new { process_requests }
|
8
|
+
raise 'Failed to start Appender Thread' unless @thread
|
9
9
|
true
|
10
10
|
end
|
11
11
|
|
12
12
|
# Returns true if the appender_thread is active
|
13
13
|
def self.active?
|
14
|
-
|
14
|
+
@thread && @thread.alive?
|
15
15
|
end
|
16
16
|
|
17
|
-
# Returns [Integer] the number of log entries waiting to be written to the appenders
|
17
|
+
# Returns [Integer] the number of log entries waiting to be written to the appenders.
|
18
|
+
#
|
19
|
+
# When this number grows it is because the logging appender thread is not
|
20
|
+
# able to write to the appenders fast enough. Either reduce the amount of
|
21
|
+
# logging, increase the log level, reduce the number of appenders, or
|
22
|
+
# look into speeding up the appenders themselves
|
18
23
|
def self.queue_size
|
19
24
|
queue.size
|
20
25
|
end
|
21
26
|
|
22
|
-
#
|
27
|
+
# Flush all queued log entries disk, database, etc.
|
28
|
+
# All queued log messages are written and then each appender is flushed in turn.
|
29
|
+
def self.flush
|
30
|
+
submit_request(:flush)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Close all appenders and flush any outstanding messages.
|
34
|
+
def self.close
|
35
|
+
submit_request(:close)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Add log request to the queue for processing.
|
23
39
|
def self.<<(log)
|
24
|
-
|
40
|
+
return unless active?
|
41
|
+
|
42
|
+
call_log_subscribers(log)
|
43
|
+
queue << log
|
25
44
|
end
|
26
45
|
|
27
46
|
# Submit command and wait for reply
|
@@ -47,78 +66,68 @@ module SemanticLogger
|
|
47
66
|
# SemanticLogger::Logger itself since it is for reporting problems
|
48
67
|
# while trying to log to the various appenders
|
49
68
|
def self.logger=(logger)
|
50
|
-
|
69
|
+
@logger = logger
|
51
70
|
end
|
52
71
|
|
53
72
|
# Returns the check_interval which is the number of messages between checks
|
54
73
|
# to determine if the appender thread is falling behind
|
55
74
|
def self.lag_check_interval
|
56
|
-
|
75
|
+
@lag_check_interval
|
57
76
|
end
|
58
77
|
|
59
78
|
# Set the check_interval which is the number of messages between checks
|
60
79
|
# to determine if the appender thread is falling behind
|
61
80
|
def self.lag_check_interval=(lag_check_interval)
|
62
|
-
|
81
|
+
@lag_check_interval = lag_check_interval
|
63
82
|
end
|
64
83
|
|
65
84
|
# Returns the amount of time in seconds
|
66
85
|
# to determine if the appender thread is falling behind
|
67
86
|
def self.lag_threshold_s
|
68
|
-
|
87
|
+
@lag_threshold_s
|
69
88
|
end
|
70
89
|
|
71
|
-
# Supply a metrics appender to be called whenever a logging metric is encountered
|
72
|
-
#
|
73
|
-
# Parameters
|
74
|
-
# appender: [Symbol | Object | Proc]
|
75
|
-
# [Proc] the block to call.
|
76
|
-
# [Object] the block on which to call #call.
|
77
|
-
# [Symbol] :new_relic, or :statsd to forward metrics to
|
78
|
-
#
|
79
|
-
# block
|
80
|
-
# The block to be called
|
81
|
-
#
|
82
|
-
# Example:
|
83
|
-
# SemanticLogger.on_metric do |log|
|
84
|
-
# puts "#{log.metric} was received. Log: #{log.inspect}"
|
85
|
-
# end
|
86
|
-
#
|
87
|
-
# Note:
|
88
|
-
# * This callback is called in the logging thread.
|
89
|
-
# * Does not slow down the application.
|
90
|
-
# * Only context is what is passed in the log struct, the original thread context is not available.
|
91
90
|
def self.on_metric(options = {}, &block)
|
92
91
|
# Backward compatibility
|
93
|
-
options
|
94
|
-
|
92
|
+
options = options.is_a?(Hash) ? options.dup : {appender: options}
|
93
|
+
subscriber = block || options.delete(:appender)
|
95
94
|
|
96
95
|
# Convert symbolized metrics appender to an actual object
|
97
|
-
|
96
|
+
subscriber = SemanticLogger::Appender.constantize_symbol(subscriber, 'SemanticLogger::Metrics').new(options) if subscriber.is_a?(Symbol)
|
97
|
+
|
98
|
+
raise('When supplying a metrics subscriber, it must support the #call method') unless subscriber.is_a?(Proc) || subscriber.respond_to?(:call)
|
99
|
+
subscribers = (@metric_subscribers ||= Concurrent::Array.new)
|
100
|
+
subscribers << subscriber unless subscribers.include?(subscriber)
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.on_log(object = nil, &block)
|
104
|
+
subscriber = block || object
|
98
105
|
|
99
|
-
raise('When supplying
|
100
|
-
(
|
106
|
+
raise('When supplying an on_log subscriber, it must support the #call method') unless subscriber.is_a?(Proc) || subscriber.respond_to?(:call)
|
107
|
+
subscribers = (@log_subscribers ||= Concurrent::Array.new)
|
108
|
+
subscribers << subscriber unless subscribers.include?(subscriber)
|
101
109
|
end
|
102
110
|
|
103
111
|
private
|
104
112
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
113
|
+
@thread = nil
|
114
|
+
@queue = Queue.new
|
115
|
+
@lag_check_interval = 5000
|
116
|
+
@lag_threshold_s = 30
|
117
|
+
@metric_subscribers = nil
|
118
|
+
@log_subscribers = nil
|
110
119
|
|
111
120
|
# Queue to hold messages that need to be logged to the various appenders
|
112
121
|
def self.queue
|
113
|
-
|
122
|
+
@queue
|
114
123
|
end
|
115
124
|
|
116
125
|
# Internal logger for SemanticLogger
|
117
126
|
# For example when an appender is not working etc..
|
118
127
|
# By default logs to STDERR
|
119
128
|
def self.logger
|
120
|
-
|
121
|
-
l = SemanticLogger::Appender::File.new(STDERR, :warn)
|
129
|
+
@logger ||= begin
|
130
|
+
l = SemanticLogger::Appender::File.new(io: STDERR, level: :warn)
|
122
131
|
l.name = name
|
123
132
|
l
|
124
133
|
end
|
@@ -156,6 +165,7 @@ module SemanticLogger
|
|
156
165
|
when :close
|
157
166
|
close_appenders
|
158
167
|
message[:reply_queue] << true if message[:reply_queue]
|
168
|
+
break
|
159
169
|
else
|
160
170
|
logger.warn "Appender thread: Ignoring unknown command: #{message[:command]}"
|
161
171
|
end
|
@@ -170,7 +180,7 @@ module SemanticLogger
|
|
170
180
|
end
|
171
181
|
retry
|
172
182
|
ensure
|
173
|
-
|
183
|
+
@thread = nil
|
174
184
|
# This block may be called after the file handles have been released by Ruby
|
175
185
|
begin
|
176
186
|
logger.trace 'Appender thread has stopped'
|
@@ -183,9 +193,9 @@ module SemanticLogger
|
|
183
193
|
# Call Metric subscribers
|
184
194
|
def self.call_metric_subscribers(log)
|
185
195
|
# If no subscribers registered, then return immediately
|
186
|
-
return unless
|
196
|
+
return unless @metric_subscribers
|
187
197
|
|
188
|
-
|
198
|
+
@metric_subscribers.each do |subscriber|
|
189
199
|
begin
|
190
200
|
subscriber.call(log)
|
191
201
|
rescue Exception => exc
|
@@ -194,6 +204,20 @@ module SemanticLogger
|
|
194
204
|
end
|
195
205
|
end
|
196
206
|
|
207
|
+
# Call on_log subscribers
|
208
|
+
def self.call_log_subscribers(log)
|
209
|
+
# If no subscribers registered, then return immediately
|
210
|
+
return unless @log_subscribers
|
211
|
+
|
212
|
+
@log_subscribers.each do |subscriber|
|
213
|
+
begin
|
214
|
+
subscriber.call(log)
|
215
|
+
rescue Exception => exc
|
216
|
+
logger.error 'Exception calling :on_log subscriber', exc
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
197
221
|
# Call Appenders
|
198
222
|
def self.call_appenders(log)
|
199
223
|
SemanticLogger.appenders.each do |appender|
|
@@ -12,14 +12,14 @@ module SemanticLogger
|
|
12
12
|
|
13
13
|
# Sets the global default log level
|
14
14
|
def self.default_level=(level)
|
15
|
-
|
15
|
+
@default_level = level
|
16
16
|
# For performance reasons pre-calculate the level index
|
17
|
-
|
17
|
+
@default_level_index = level_to_index(level)
|
18
18
|
end
|
19
19
|
|
20
20
|
# Returns the global default log level
|
21
21
|
def self.default_level
|
22
|
-
|
22
|
+
@default_level
|
23
23
|
end
|
24
24
|
|
25
25
|
# Sets the level at which backtraces should be captured
|
@@ -33,45 +33,45 @@ module SemanticLogger
|
|
33
33
|
# Capturing backtraces is very expensive and should not be done all
|
34
34
|
# the time. It is recommended to run it at :error level in production.
|
35
35
|
def self.backtrace_level=(level)
|
36
|
-
|
36
|
+
@backtrace_level = level
|
37
37
|
# For performance reasons pre-calculate the level index
|
38
|
-
|
38
|
+
@backtrace_level_index = level.nil? ? 65535 : level_to_index(level)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Returns the current backtrace level
|
42
42
|
def self.backtrace_level
|
43
|
-
|
43
|
+
@backtrace_level
|
44
44
|
end
|
45
45
|
|
46
46
|
# Returns the current backtrace level index
|
47
47
|
# For internal use only
|
48
48
|
def self.backtrace_level_index #:nodoc
|
49
|
-
|
49
|
+
@backtrace_level_index
|
50
50
|
end
|
51
51
|
|
52
52
|
# Returns [String] name of this host for logging purposes
|
53
53
|
# Note: Not all appenders use `host`
|
54
54
|
def self.host
|
55
|
-
|
55
|
+
@host ||= Socket.gethostname.force_encoding("UTF-8")
|
56
56
|
end
|
57
57
|
|
58
58
|
# Override the default host name
|
59
59
|
def self.host=(host)
|
60
|
-
|
60
|
+
@host = host
|
61
61
|
end
|
62
62
|
|
63
63
|
# Returns [String] name of this application for logging purposes
|
64
64
|
# Note: Not all appenders use `application`
|
65
65
|
def self.application
|
66
|
-
|
66
|
+
@application
|
67
67
|
end
|
68
68
|
|
69
69
|
# Override the default application
|
70
70
|
def self.application=(application)
|
71
|
-
|
71
|
+
@application = application
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
@application = 'Semantic Logger'
|
75
75
|
|
76
76
|
# Add a new logging appender as a new destination for all log messages
|
77
77
|
# emitted from Semantic Logger
|
@@ -154,7 +154,7 @@ module SemanticLogger
|
|
154
154
|
def self.add_appender(options, deprecated_level = nil, &block)
|
155
155
|
options = options.is_a?(Hash) ? options.dup : convert_old_appender_args(options, deprecated_level)
|
156
156
|
appender = SemanticLogger::Appender.create(options, &block)
|
157
|
-
|
157
|
+
@appenders << appender
|
158
158
|
|
159
159
|
# Start appender thread if it is not already running
|
160
160
|
SemanticLogger::Processor.start
|
@@ -164,7 +164,7 @@ module SemanticLogger
|
|
164
164
|
# Remove an existing appender
|
165
165
|
# Currently only supports appender instances
|
166
166
|
def self.remove_appender(appender)
|
167
|
-
|
167
|
+
@appenders.delete(appender)
|
168
168
|
end
|
169
169
|
|
170
170
|
# Returns [SemanticLogger::Subscriber] a copy of the list of active
|
@@ -172,31 +172,33 @@ module SemanticLogger
|
|
172
172
|
# Use SemanticLogger.add_appender and SemanticLogger.remove_appender
|
173
173
|
# to manipulate the active appenders list
|
174
174
|
def self.appenders
|
175
|
-
|
175
|
+
@appenders.clone
|
176
176
|
end
|
177
177
|
|
178
|
-
#
|
179
|
-
#
|
178
|
+
# Flush all queued log entries disk, database, etc.
|
179
|
+
# All queued log messages are written and then each appender is flushed in turn.
|
180
180
|
def self.flush
|
181
|
-
SemanticLogger::
|
181
|
+
SemanticLogger::Processor.flush
|
182
182
|
end
|
183
183
|
|
184
|
-
# Close and flush
|
184
|
+
# Close all appenders and flush any outstanding messages.
|
185
185
|
def self.close
|
186
|
-
SemanticLogger::
|
186
|
+
SemanticLogger::Processor.close
|
187
187
|
end
|
188
188
|
|
189
189
|
# After forking an active process call SemanticLogger.reopen to re-open
|
190
|
-
# any open file handles etc to resources
|
190
|
+
# any open file handles etc to resources.
|
191
191
|
#
|
192
|
-
# Note:
|
192
|
+
# Note:
|
193
|
+
# Not all appenders implement reopen.
|
194
|
+
# Check the code for each appender you are using before relying on this behavior.
|
193
195
|
def self.reopen
|
194
|
-
|
195
|
-
# After a fork the appender thread is not running, start it if it is not running
|
196
|
+
@appenders.each {|appender| appender.reopen if appender.respond_to?(:reopen)}
|
197
|
+
# After a fork the appender thread is not running, start it if it is not running.
|
196
198
|
SemanticLogger::Processor.start
|
197
199
|
end
|
198
200
|
|
199
|
-
# Supply a
|
201
|
+
# Supply a metrics appender to be called whenever a logging metric is encountered
|
200
202
|
#
|
201
203
|
# Parameters
|
202
204
|
# appender: [Symbol | Object | Proc]
|
@@ -213,13 +215,41 @@ module SemanticLogger
|
|
213
215
|
# end
|
214
216
|
#
|
215
217
|
# Note:
|
216
|
-
# * This callback is called in the logging thread.
|
218
|
+
# * This callback is called in the separate logging thread.
|
217
219
|
# * Does not slow down the application.
|
218
220
|
# * Only context is what is passed in the log struct, the original thread context is not available.
|
219
221
|
def self.on_metric(options = {}, &block)
|
220
222
|
SemanticLogger::Processor.on_metric(options, &block)
|
221
223
|
end
|
222
224
|
|
225
|
+
# Supply a callback to be called whenever a log entry is created.
|
226
|
+
# Useful for capturing appender specific context information.
|
227
|
+
#
|
228
|
+
# Parameters
|
229
|
+
# object: [Object | Proc]
|
230
|
+
# [Proc] the block to call.
|
231
|
+
# [Object] any object on which to call #call.
|
232
|
+
#
|
233
|
+
# Example:
|
234
|
+
# SemanticLogger.on_log do |log|
|
235
|
+
# log.set_context(:honeybadger, Honeybadger.get_context)
|
236
|
+
# end
|
237
|
+
#
|
238
|
+
# Example:
|
239
|
+
# module CaptureContext
|
240
|
+
# def call(log)
|
241
|
+
# log.set_context(:honeybadger, Honeybadger.get_context)
|
242
|
+
# end
|
243
|
+
# end
|
244
|
+
# SemanticLogger.on_log(CaptureContext)
|
245
|
+
#
|
246
|
+
# Note:
|
247
|
+
# * This callback is called within the thread of the application making the logging call.
|
248
|
+
# * If these callbacks are slow they will slow down the application.
|
249
|
+
def self.on_log(object = nil, &block)
|
250
|
+
Processor.on_log(object, &block)
|
251
|
+
end
|
252
|
+
|
223
253
|
# Add signal handlers for Semantic Logger
|
224
254
|
#
|
225
255
|
# Two signal handlers will be registered by default:
|
@@ -285,20 +315,52 @@ module SemanticLogger
|
|
285
315
|
# If the tag being supplied is definitely a string then this fast
|
286
316
|
# tag api can be used for short lived tags
|
287
317
|
def self.fast_tag(tag)
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
318
|
+
return yield if tag.nil? || tag == ''
|
319
|
+
|
320
|
+
t = Thread.current[:semantic_logger_tags] ||= []
|
321
|
+
begin
|
322
|
+
t << tag
|
323
|
+
yield
|
324
|
+
ensure
|
325
|
+
t.pop
|
326
|
+
end
|
292
327
|
end
|
293
328
|
|
294
|
-
# Add the
|
295
|
-
#
|
296
|
-
# Returns result of block
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
329
|
+
# Add the tags or named tags to the list of tags to log for this thread whilst the supplied block is active.
|
330
|
+
#
|
331
|
+
# Returns result of block.
|
332
|
+
#
|
333
|
+
# Tagged example:
|
334
|
+
# SemanticLogger.tagged(12345, 'jack') do
|
335
|
+
# logger.debug('Hello World')
|
336
|
+
# end
|
337
|
+
#
|
338
|
+
# Named Tags (Hash) example:
|
339
|
+
# SemanticLogger.tagged(tracking_number: 12345) do
|
340
|
+
# logger.debug('Hello World')
|
341
|
+
# end
|
342
|
+
#
|
343
|
+
# Notes:
|
344
|
+
# - Tags should be a list without any empty values, or contain any array.
|
345
|
+
# - `logger.tagged` is a slower api that will flatten the example below:
|
346
|
+
# `logger.tagged([['first', nil], nil, ['more'], 'other'])`
|
347
|
+
# to the equivalent of:
|
348
|
+
# `logger.tagged('first', 'more', 'other')`
|
349
|
+
def self.tagged(*tags, &block)
|
350
|
+
return yield if tags.empty?
|
351
|
+
|
352
|
+
# Allow named tags to be passed into the logger
|
353
|
+
if tags.size == 1
|
354
|
+
tag = tags[0]
|
355
|
+
return tag.is_a?(Hash) ? named_tagged(tag, &block) : fast_tag(tag, &block)
|
356
|
+
end
|
357
|
+
|
358
|
+
begin
|
359
|
+
push_tags(*tags)
|
360
|
+
yield
|
361
|
+
ensure
|
362
|
+
pop_tags(tags.size)
|
363
|
+
end
|
302
364
|
end
|
303
365
|
|
304
366
|
# Returns a copy of the [Array] of [String] tags currently active for this thread
|
@@ -310,13 +372,15 @@ module SemanticLogger
|
|
310
372
|
end
|
311
373
|
|
312
374
|
# Add tags to the current scope
|
313
|
-
#
|
375
|
+
#
|
376
|
+
# Note:
|
377
|
+
# - This method does not flatten the array or remove any empty elements, or duplicates
|
378
|
+
# since the performance penalty is excessive.
|
379
|
+
# - To get the flattening behavior use the slower api:
|
380
|
+
# `logger.push_tags`
|
314
381
|
def self.push_tags(*tags)
|
315
|
-
|
316
|
-
|
317
|
-
t = Thread.current[:semantic_logger_tags]
|
318
|
-
Thread.current[:semantic_logger_tags] = t.nil? ? new_tags : t.concat(new_tags)
|
319
|
-
new_tags
|
382
|
+
(Thread.current[:semantic_logger_tags] ||= []).concat(tags)
|
383
|
+
tags
|
320
384
|
end
|
321
385
|
|
322
386
|
# Remove specified number of tags from the current tag list
|
@@ -325,33 +389,30 @@ module SemanticLogger
|
|
325
389
|
t.pop(quantity) unless t.nil?
|
326
390
|
end
|
327
391
|
|
328
|
-
#
|
329
|
-
# the supplied block is active.
|
330
|
-
#
|
331
|
-
# Add a payload to all log calls on This Thread within the supplied block
|
332
|
-
#
|
333
|
-
# SemanticLogger.named_tagged(tracking_number: 12345) do
|
334
|
-
# logger.debug('Hello World')
|
335
|
-
# end
|
336
|
-
#
|
337
|
-
# Returns result of block
|
392
|
+
# :nodoc
|
338
393
|
def self.named_tagged(hash)
|
394
|
+
return yield if hash.nil? || hash.empty?
|
339
395
|
raise(ArgumentError, '#named_tagged only accepts named parameters (Hash)') unless hash.is_a?(Hash)
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
396
|
+
|
397
|
+
t = Thread.current[:semantic_logger_named_tags] ||= []
|
398
|
+
begin
|
399
|
+
t << hash
|
400
|
+
yield
|
401
|
+
ensure
|
402
|
+
t.pop
|
403
|
+
end
|
344
404
|
end
|
345
405
|
|
346
|
-
# Returns a copy of the
|
347
|
-
# Returns nil if no named tags are set
|
406
|
+
# Returns [Hash] a copy of the named tags currently active for this thread.
|
348
407
|
def self.named_tags
|
349
408
|
if (list = Thread.current[:semantic_logger_named_tags]) && !list.empty?
|
350
409
|
if list.size > 1
|
351
|
-
list.
|
410
|
+
list.reduce({}) {|sum, h| sum.merge(h)}
|
352
411
|
else
|
353
412
|
list.first.clone
|
354
413
|
end
|
414
|
+
else
|
415
|
+
{}
|
355
416
|
end
|
356
417
|
end
|
357
418
|
|
@@ -401,10 +462,10 @@ module SemanticLogger
|
|
401
462
|
|
402
463
|
private
|
403
464
|
|
404
|
-
|
465
|
+
@appenders = Concurrent::Array.new
|
405
466
|
|
406
467
|
def self.default_level_index
|
407
|
-
Thread.current[:semantic_logger_silence] ||
|
468
|
+
Thread.current[:semantic_logger_silence] || @default_level_index
|
408
469
|
end
|
409
470
|
|
410
471
|
# Returns the symbolic level for the supplied level index
|
@@ -425,14 +486,14 @@ module SemanticLogger
|
|
425
486
|
LEVELS.index(level)
|
426
487
|
elsif level.is_a?(Integer) && defined?(::Logger::Severity)
|
427
488
|
# Mapping of Rails and Ruby Logger levels to SemanticLogger levels
|
428
|
-
|
489
|
+
@map_levels ||= begin
|
429
490
|
levels = []
|
430
491
|
::Logger::Severity.constants.each do |constant|
|
431
492
|
levels[::Logger::Severity.const_get(constant)] = LEVELS.find_index(constant.downcase.to_sym) || LEVELS.find_index(:error)
|
432
493
|
end
|
433
494
|
levels
|
434
495
|
end
|
435
|
-
|
496
|
+
@map_levels[level]
|
436
497
|
end
|
437
498
|
raise "Invalid level:#{level.inspect} being requested. Must be one of #{LEVELS.inspect}" unless index
|
438
499
|
index
|
@@ -457,8 +518,8 @@ module SemanticLogger
|
|
457
518
|
end
|
458
519
|
|
459
520
|
# Initial default Level for all new instances of SemanticLogger::Logger
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
521
|
+
@default_level = :info
|
522
|
+
@default_level_index = level_to_index(@default_level)
|
523
|
+
@backtrace_level = :error
|
524
|
+
@backtrace_level_index = level_to_index(@backtrace_level)
|
464
525
|
end
|