semantic_logger 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|