semantic_logger 2.17.0 → 2.18.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d01095b46462b1fc9ea2b2d918a372bda406cd8
4
- data.tar.gz: d6e2b86770aaaa606727efa5090028ffd0e6bcb5
3
+ metadata.gz: 60df9242109f0c836e1375c4c21d5b0a85165e34
4
+ data.tar.gz: 47e1799788d85898b1ff7501ba99e460c78a815f
5
5
  SHA512:
6
- metadata.gz: 0ec5d70d0147dba2cb7c63a1981de782a215036adbf469c48d2cb04a1c66a59b055fbf0627214464f0d12199679b69b2ddcd62fc93bf6017311a1cda730e5f90
7
- data.tar.gz: 84d8f9e36d3ca6d04849e765a6cab837a281bdbcb625d4afebdecbe9d0d30bf86ac0f9153726bb9a726f702d8b22f4551ad782e2c25f285b89ff3bb17b9f0a0b
6
+ metadata.gz: 304af80d0e158f72a2dd5a90f8ac1e56dd8955bcfd26b4cec84862c0347ba5fb5b93ae4d6e76cdf6f48f3f84bb6310c9dfa703f36534bc253c64020d91576cd2
7
+ data.tar.gz: 0b1064e891a59877f1e991a19e73e2a1f10aac25e4621df25c311bd7d903df68144df37a88d5bc13b6e456a86446d14e43ad5834fa5009e2eb651745de5d0e6c
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # semantic_logger
2
- [![Gem Version](https://img.shields.io/gem/v/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![Build Status](https://travis-ci.org/rocketjob/semantic_logger.svg?branch=master)](https://travis-ci.org/rocketjob/semantic_logger) [![Downloads](https://img.shields.io/gem/dt/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg) [![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-Support-brightgreen.svg)](https://gitter.im/rocketjob/rocketjob)
2
+ [![Gem Version](https://img.shields.io/gem/v/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![Build Status](https://travis-ci.org/rocketjob/semantic_logger.svg?branch=master)](https://travis-ci.org/rocketjob/semantic_logger) [![Downloads](https://img.shields.io/gem/dt/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](http://opensource.org/licenses/Apache-2.0) ![](https://img.shields.io/badge/status-Production%20Ready-blue.svg) [![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-Support-brightgreen.svg)](https://gitter.im/rocketjob/support)
3
3
 
4
4
  Low latency, high throughput, enterprise-scale logging system for Ruby
5
5
 
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ end
18
18
  desc 'Run Test Suite'
19
19
  task :test do
20
20
  Rake::TestTask.new(:functional) do |t|
21
- t.test_files = FileList['test/*_test.rb']
21
+ t.test_files = FileList['test/**/*_test.rb']
22
22
  t.verbose = true
23
23
  end
24
24
 
@@ -5,6 +5,7 @@ require 'semantic_logger/semantic_logger'
5
5
  # @formatter:off
6
6
  module SemanticLogger
7
7
  autoload :Base, 'semantic_logger/base'
8
+ autoload :Log, 'semantic_logger/log'
8
9
  autoload :Logger, 'semantic_logger/logger'
9
10
  autoload :Loggable, 'semantic_logger/loggable'
10
11
  autoload :DebugAsTraceLogger, 'semantic_logger/debug_as_trace_logger'
@@ -11,16 +11,27 @@ module SemanticLogger
11
11
 
12
12
  # Formatting & colors used by optional colorized_formatter
13
13
  module AnsiColors
14
- CLEAR = "\e[0m"
15
- BOLD = "\e[1m"
16
- BLACK = "\e[30m"
17
- RED = "\e[31m"
18
- GREEN = "\e[32m"
19
- YELLOW = "\e[33m"
20
- BLUE = "\e[34m"
21
- MAGENTA = "\e[35m"
22
- CYAN = "\e[36m"
23
- WHITE = "\e[37m"
14
+ CLEAR = "\e[0m"
15
+ BOLD = "\e[1m"
16
+ BLACK = "\e[30m"
17
+ RED = "\e[31m"
18
+ GREEN = "\e[32m"
19
+ YELLOW = "\e[33m"
20
+ BLUE = "\e[34m"
21
+ MAGENTA = "\e[35m"
22
+ CYAN = "\e[36m"
23
+ WHITE = "\e[37m"
24
+
25
+ # Maps the log level to a color for colorized formatters
26
+ # Since this map is not frozen, it can be modified as needed
27
+ LEVEL_MAP = {
28
+ trace: MAGENTA,
29
+ debug: GREEN,
30
+ info: CYAN,
31
+ warn: BOLD,
32
+ error: RED,
33
+ fatal: RED
34
+ }
24
35
  end
25
36
 
26
37
  class Base < SemanticLogger::Base
@@ -32,69 +43,73 @@ module SemanticLogger
32
43
  # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
33
44
  def default_formatter
34
45
  Proc.new do |log|
35
- tags = log.tags.collect { |tag| "[#{tag}]" }.join(' ') + ' ' if log.tags && (log.tags.size > 0)
46
+ # Header with date, time, log level and process info
47
+ entry = "#{log.formatted_time} #{log.level_to_s} [#{log.process_info}]"
36
48
 
37
- message = log.message.to_s.dup
38
- message << ' -- ' << log.payload.inspect unless log.payload.nil? || (log.payload.respond_to?(:empty?) && log.payload.empty?)
39
- message << ' -- Exception: ' << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
49
+ # Tags
50
+ entry << ' ' << log.tags.collect { |tag| "[#{tag}]" }.join(' ') if log.tags && (log.tags.size > 0)
40
51
 
41
- duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
52
+ # Duration
53
+ entry << " (#{log.duration_human})" if log.duration
42
54
 
43
- file_name =
44
- if log.backtrace || log.exception
45
- backtrace = log.backtrace || log.exception.backtrace
46
- location = backtrace[0].split('/').last
47
- file, line = location.split(':')
48
- " #{file}:#{line}"
49
- end
55
+ # Class / app name
56
+ entry << " #{log.name}"
50
57
 
51
- "#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s[0..0].upcase} [#{$$}:#{'%.50s' % log.thread_name}#{file_name}] #{tags}#{duration_str}#{log.name} -- #{message}"
58
+ # Log message
59
+ entry << " -- #{log.message}" if log.message
60
+
61
+ # Payload
62
+ unless log.payload.nil? || (log.payload.respond_to?(:empty?) && log.payload.empty?)
63
+ entry << ' -- ' << log.payload.inspect
64
+ end
65
+
66
+ # Exceptions
67
+ log.each_exception do |exception, i|
68
+ entry << (i == 0 ? ' -- Exception: ' : "\nCause: ")
69
+ entry << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
70
+ end
71
+ entry
52
72
  end
53
73
  end
54
74
 
55
75
  # Optional log formatter to colorize log output
56
76
  # To use this formatter
57
- # SemanticLogger.add_appender($stdout, nil, &SemanticLogger::Logger.colorized_formatter)
77
+ # SemanticLogger.add_appender($stdout, &SemanticLogger::Appender::Base.colorized_formatter)
58
78
  #
59
79
  # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
60
80
  def self.colorized_formatter
61
81
  Proc.new do |log|
62
- colors = SemanticLogger::Appender::AnsiColors
63
- tags = log.tags.collect { |tag| "[#{colors::CYAN}#{tag}#{colors::CLEAR}]" }.join(' ') + ' ' if log.tags && (log.tags.size > 0)
82
+ colors = SemanticLogger::Appender::AnsiColors
83
+ level_color = colors::LEVEL_MAP[log.level]
84
+
85
+ # Header with date, time, log level and process info
86
+ entry = "#{log.formatted_time} #{level_color}#{log.level_to_s}#{colors::CLEAR} [#{log.process_info}]"
64
87
 
65
- message = log.message.to_s.dup
88
+ # Tags
89
+ entry << ' ' << log.tags.collect { |tag| "[#{level_color}#{tag}#{colors::CLEAR}]" }.join(' ') if log.tags && (log.tags.size > 0)
90
+
91
+ # Duration
92
+ entry << " (#{colors::BOLD}#{log.duration_human}#{colors::CLEAR})" if log.duration
93
+
94
+ # Class / app name
95
+ entry << " #{level_color}#{log.name}#{colors::CLEAR}"
96
+
97
+ # Log message
98
+ entry << " -- #{log.message}" if log.message
99
+
100
+ # Payload
66
101
  unless log.payload.nil? || (log.payload.respond_to?(:empty?) && log.payload.empty?)
67
102
  payload = log.payload
68
103
  payload = (defined?(AwesomePrint) && payload.respond_to?(:ai)) ? payload.ai(multiline: false) : payload.inspect
69
- message << ' -- ' << payload
104
+ entry << ' -- ' << payload
105
+ end
106
+
107
+ # Exceptions
108
+ log.each_exception do |exception, i|
109
+ entry << (i == 0 ? ' -- Exception: ' : "\nCause: ")
110
+ entry << "#{colors::BOLD}#{exception.class}: #{exception.message}#{colors::CLEAR}\n#{(exception.backtrace || []).join("\n")}"
70
111
  end
71
- message << ' -- Exception: ' << "#{colors::BOLD}#{log.exception.class}: #{log.exception.message}#{colors::CLEAR}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
72
-
73
- duration_str = log.duration ? "(#{colors::BOLD}#{'%.1f' % log.duration}ms#{colors::CLEAR}) " : ''
74
-
75
- level_color =
76
- case log.level
77
- when :trace
78
- colors::MAGENTA
79
- when :debug
80
- colors::GREEN
81
- when :info
82
- colors::CYAN
83
- when :warn
84
- colors::BOLD
85
- when :error, :fatal
86
- colors::RED
87
- end
88
-
89
- file_name =
90
- if log.backtrace || log.exception
91
- backtrace = log.backtrace || log.exception.backtrace
92
- location = backtrace[0].split('/').last
93
- file, line = location.split(':')
94
- " #{level_color}#{file}:#{line}#{colors::CLEAR}"
95
- end
96
-
97
- "#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{level_color}#{colors::BOLD}#{log.level.to_s[0..0].upcase}#{colors::CLEAR} [#{$$}:#{'%.30s' % log.thread_name}#{file_name}] #{tags}#{duration_str}#{level_color}#{log.name}#{colors::CLEAR} -- #{message}"
112
+ entry
98
113
  end
99
114
  end
100
115
 
@@ -139,17 +154,18 @@ module SemanticLogger
139
154
  @level_index || 0
140
155
  end
141
156
 
142
- # For JRuby include the Thread name rather than its id
143
157
  if defined? Java
144
158
  # Return the Time as a formatted string
145
159
  # JRuby only supports time in ms
146
160
  def self.formatted_time(time)
161
+ warn '[deprecated] SemanticLogger::Base.formatted_time is deprecated please use log.formatted_time'
147
162
  "#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%03d' % (time.usec/1000)}"
148
163
  end
149
164
  else
150
165
  # Return the Time as a formatted string
151
166
  # Ruby MRI supports micro seconds
152
167
  def self.formatted_time(time)
168
+ warn '[deprecated] SemanticLogger::Base.formatted_time is deprecated please use log.formatted_time'
153
169
  "#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%06d' % (time.usec)}"
154
170
  end
155
171
  end
@@ -56,7 +56,7 @@ class SemanticLogger::Appender::Bugsnag < SemanticLogger::Appender::Base
56
56
  # Returns [Hash] of parameters to send to Bugsnag.
57
57
  def default_formatter
58
58
  proc do |log|
59
- h = {severity: log_level(log), tags: log.tags, class: log.name}
59
+ h = {severity: log_level(log), tags: log.tags, class: log.name}
60
60
  h[:message] = log.message if log.exception
61
61
  h.merge!(log.payload) if log.payload
62
62
  h
@@ -154,21 +154,25 @@ module SemanticLogger
154
154
  level_index: log.level_index,
155
155
  }
156
156
  document[:application] = application if application
157
- document[:message] = self.class.strip_colorizing(log.message) if log.message
157
+ document[:message] = log.cleansed_message if log.message
158
158
  document[:duration] = log.duration if log.duration
159
159
  document[:tags] = log.tags if log.tags && (log.tags.size > 0)
160
160
  document[:payload] = log.payload if log.payload
161
161
  if log.exception
162
- document[:exception] = {
163
- name: log.exception.class.name,
164
- message: log.exception.message,
165
- stack_trace: log.exception.backtrace
166
- }
162
+ root = document
163
+ log.each_exception do |exception, i|
164
+ name = i == 0 ? :exception : :cause
165
+ root[name] = {
166
+ name: exception.class.name,
167
+ message: exception.message,
168
+ stack_trace: exception.backtrace
169
+ }
170
+ root = root[name]
171
+ end
167
172
  end
168
- if log.backtrace || log.exception
169
- backtrace = log.backtrace || log.exception.backtrace
170
- location = backtrace[0].split('/').last
171
- file, line = location.split(':')
173
+
174
+ file, line = log.file_name_and_line
175
+ if file
172
176
  document[:file_name] = file
173
177
  document[:line_number] = line.to_i
174
178
  end
@@ -176,11 +180,6 @@ module SemanticLogger
176
180
  end
177
181
  end
178
182
 
179
- # Strip the standard Rails colorizing from the logged message
180
- def self.strip_colorizing(message)
181
- message.to_s.gsub(/(\e(\[([\d;]*[mz]?))?)?/, '').strip
182
- end
183
-
184
183
  # Default host_name to use if none is supplied to the appenders initializer
185
184
  def self.host_name
186
185
  @@host_name ||= Socket.gethostname.split('.').first
@@ -40,8 +40,8 @@ class SemanticLogger::Appender::Splunk < SemanticLogger::Appender::Base
40
40
  def parse_options(options)
41
41
  @config = {
42
42
  scheme: options[:scheme] || :https,
43
- host: options[:host] || 'localhost',
44
- port: options[:port] || 8089,
43
+ host: options[:host] || 'localhost',
44
+ port: options[:port] || 8089,
45
45
  username: options[:username],
46
46
  password: options[:password]
47
47
  }
@@ -239,7 +239,14 @@ module SemanticLogger
239
239
 
240
240
  message = log.message.to_s
241
241
  message << ' -- ' << log.payload.inspect if log.payload
242
- message << ' -- ' << "#{log.exception.class}: #{log.exception.message}\n#{(log.exception.backtrace || []).join("\n")}" if log.exception
242
+ log.each_exception do |exception, i|
243
+ if i == 0
244
+ message << ' -- '
245
+ else
246
+ message << "\nCause: "
247
+ end
248
+ message << "#{exception.class}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
249
+ end
243
250
 
244
251
  duration_str = log.duration ? "(#{'%.1f' % log.duration}ms) " : ''
245
252
 
@@ -279,46 +279,6 @@ module SemanticLogger
279
279
  @level_index || SemanticLogger.default_level_index
280
280
  end
281
281
 
282
- # Struct Log
283
- #
284
- # level
285
- # Log level of the supplied log call
286
- # :trace, :debug, :info, :warn, :error, :fatal
287
- #
288
- # thread_name
289
- # Name of the thread in which the logging call was called
290
- #
291
- # name
292
- # Class name supplied to the logging instance
293
- #
294
- # message
295
- # Text message to be logged
296
- #
297
- # payload
298
- # Optional Hash or Ruby Exception object to be logged
299
- #
300
- # time
301
- # The time at which the log entry was created
302
- #
303
- # duration
304
- # The time taken to complete a benchmark call
305
- #
306
- # tags
307
- # Any tags active on the thread when the log call was made
308
- #
309
- # level_index
310
- # Internal index of the log level
311
- #
312
- # exception
313
- # Ruby Exception object to log
314
- #
315
- # metric [Object]
316
- # Object supplied when benchmark_x was called
317
- #
318
- # backtrace [Array<String>]
319
- # The backtrace captured at source when the log level >= SemanticLogger.backtrace_level
320
- Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception, :metric, :backtrace)
321
-
322
282
  # Whether to log the supplied message based on the current filter if any
323
283
  def include_message?(struct)
324
284
  return true if @filter.nil?
@@ -335,7 +295,7 @@ module SemanticLogger
335
295
  # Detect exception being logged
336
296
  if exception.nil? && payload.nil? && message.kind_of?(Exception)
337
297
  exception = message
338
- message = exception.inspect
298
+ message = nil
339
299
  elsif exception.nil? && payload && payload.respond_to?(:backtrace) && payload.respond_to?(:message)
340
300
  # Under JRuby a java exception is not a Ruby Exception
341
301
  # Java::JavaLang::ClassCastException.new.is_a?(Exception) => false
@@ -0,0 +1,143 @@
1
+ module SemanticLogger
2
+ # Log Struct
3
+ #
4
+ # Structure for holding all log entries
5
+ #
6
+ # level
7
+ # Log level of the supplied log call
8
+ # :trace, :debug, :info, :warn, :error, :fatal
9
+ #
10
+ # thread_name
11
+ # Name of the thread in which the logging call was called
12
+ #
13
+ # name
14
+ # Class name supplied to the logging instance
15
+ #
16
+ # message
17
+ # Text message to be logged
18
+ #
19
+ # payload
20
+ # Optional Hash or Ruby Exception object to be logged
21
+ #
22
+ # time
23
+ # The time at which the log entry was created
24
+ #
25
+ # duration
26
+ # The time taken to complete a benchmark call
27
+ #
28
+ # tags
29
+ # Any tags active on the thread when the log call was made
30
+ #
31
+ # level_index
32
+ # Internal index of the log level
33
+ #
34
+ # exception
35
+ # Ruby Exception object to log
36
+ #
37
+ # metric [Object]
38
+ # Object supplied when benchmark_x was called
39
+ #
40
+ # backtrace [Array<String>]
41
+ # The backtrace captured at source when the log level >= SemanticLogger.backtrace_level
42
+ Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception, :metric, :backtrace) do
43
+
44
+ MAX_EXCEPTIONS_TO_UNWRAP = 5
45
+ # Call the block for exception and any nested exception
46
+ def each_exception(&block)
47
+ # With thanks to https://github.com/bugsnag/bugsnag-ruby/blob/6348306e44323eee347896843d16c690cd7c4362/lib/bugsnag/notification.rb#L81
48
+ depth = 0
49
+ exceptions = []
50
+ ex = exception
51
+ while ex != nil && !exceptions.include?(ex) && exceptions.length < MAX_EXCEPTIONS_TO_UNWRAP
52
+ exceptions << ex
53
+ block.call(ex, depth)
54
+
55
+ depth += 1
56
+ ex =
57
+ if ex.respond_to?(:cause) && ex.cause
58
+ ex.cause
59
+ elsif ex.respond_to?(:continued_exception) && ex.continued_exception
60
+ ex.continued_exception
61
+ elsif ex.respond_to?(:original_exception) && ex.original_exception
62
+ ex.original_exception
63
+ end
64
+ end
65
+ end
66
+
67
+ # Returns [String] duration of the log entry as a string
68
+ # Returns nil if their is no duration
69
+ # Java time precision does not include microseconds
70
+ if defined? JRuby
71
+ def duration_to_s
72
+ "#{duration.to_i}ms" if duration
73
+ end
74
+ else
75
+ def duration_to_s
76
+ return unless duration
77
+ duration < 10.0 ? "#{'%.3f' % duration}ms" : "#{'%.1f' % duration}ms"
78
+ end
79
+ end
80
+
81
+ # Returns [String] the duration in human readable form
82
+ def duration_human
83
+ return nil unless duration
84
+ seconds = duration / 1000
85
+ if seconds >= 86400.0 # 1 day
86
+ "#{(seconds / 86400).to_i}d #{Time.at(seconds).strftime('%-Hh %-Mm')}"
87
+ elsif seconds >= 3600.0 # 1 hour
88
+ Time.at(seconds).strftime('%-Hh %-Mm')
89
+ elsif seconds >= 60.0 # 1 minute
90
+ Time.at(seconds).strftime('%-Mm %-Ss')
91
+ elsif seconds >= 1.0 # 1 second
92
+ Time.at(seconds).strftime('%-Ss %Lms')
93
+ else
94
+ duration_to_s
95
+ end
96
+ end
97
+
98
+ # Returns [String] single character upper case log level
99
+ def level_to_s
100
+ level.to_s[0..0].upcase
101
+ end
102
+
103
+ # Returns [String] the available process info
104
+ # Example:
105
+ # 18934:thread 23 test_logging.rb:51
106
+ def process_info(thread_name_length = 30)
107
+ file, line = file_name_and_line
108
+ file_name = " #{file}:#{line}" if file
109
+
110
+ "#{$$}:#{"%.#{thread_name_length}s" % thread_name}#{file_name}"
111
+ end
112
+
113
+ # Returns [String, String] the file_name and line_number from the backtrace supplied
114
+ # in either the backtrace or exception
115
+ def file_name_and_line
116
+ if backtrace || (exception && exception.backtrace)
117
+ stacktrace = backtrace || exception.backtrace
118
+ stacktrace[0].split('/').last.split(':')[0..1] if stacktrace && stacktrace.size > 0
119
+ end
120
+ end
121
+
122
+ # Strip the standard Rails colorizing from the logged message
123
+ def cleansed_message
124
+ message.to_s.gsub(/(\e(\[([\d;]*[mz]?))?)?/, '').strip
125
+ end
126
+
127
+ if defined? JRuby
128
+ # Return the Time as a formatted string
129
+ # JRuby only supports time in ms
130
+ def formatted_time
131
+ "#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%03d' % (time.usec/1000)}"
132
+ end
133
+ else
134
+ # Return the Time as a formatted string
135
+ # Ruby MRI supports micro seconds
136
+ def formatted_time
137
+ "#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%06d' % (time.usec)}"
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ end
@@ -58,7 +58,7 @@ module SemanticLogger
58
58
  def self.flush
59
59
  return false unless appender_thread_active?
60
60
 
61
- logger.debug "Flushing appenders with #{queue_size} log messages on the queue"
61
+ logger.trace "Flushing appenders with #{queue_size} log messages on the queue"
62
62
  reply_queue = Queue.new
63
63
  queue << {command: :flush, reply_queue: reply_queue}
64
64
  reply_queue.pop
@@ -174,7 +174,7 @@ module SemanticLogger
174
174
  # Should any appender fail to log or flush, the exception is logged and
175
175
  # other appenders will still be called
176
176
  Thread.current.name = 'SemanticLogger::AppenderThread'
177
- logger.debug "V#{VERSION} Appender thread active"
177
+ logger.trace "V#{VERSION} Appender thread active"
178
178
  begin
179
179
  count = 0
180
180
  while message = queue.pop
@@ -200,7 +200,7 @@ module SemanticLogger
200
200
  when :flush
201
201
  SemanticLogger.appenders.each do |appender|
202
202
  begin
203
- logger.debug "Appender thread: Flushing appender: #{appender.name}"
203
+ logger.trace "Appender thread: Flushing appender: #{appender.name}"
204
204
  appender.flush
205
205
  rescue Exception => exc
206
206
  logger.error "Appender thread: Failed to flush appender: #{appender.inspect}", exc
@@ -208,7 +208,7 @@ module SemanticLogger
208
208
  end
209
209
 
210
210
  message[:reply_queue] << true if message[:reply_queue]
211
- logger.debug 'Appender thread: All appenders flushed'
211
+ logger.trace 'Appender thread: All appenders flushed'
212
212
  else
213
213
  logger.warn "Appender thread: Ignoring unknown command: #{message[:command]}"
214
214
  end
@@ -226,7 +226,7 @@ module SemanticLogger
226
226
  @@appender_thread = nil
227
227
  # This block may be called after the file handles have been released by Ruby
228
228
  begin
229
- logger.debug 'Appender thread has stopped'
229
+ logger.trace 'Appender thread has stopped'
230
230
  rescue Exception
231
231
  nil
232
232
  end
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger #:nodoc
2
- VERSION = '2.17.0'
2
+ VERSION = '2.18.0'
3
3
  end
@@ -14,12 +14,13 @@ module Appender
14
14
  @hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
15
15
  @hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
16
16
  @thread_name = Thread.current.name
17
+ @file_name_reg_exp = RUBY_VERSION.to_f <= 2.0 ? ' (mock|file_test).rb:\d+' : ' file_test.rb:\d+'
17
18
  end
18
19
 
19
20
  describe 'format logs into text form' do
20
21
  it 'handle no message or payload' do
21
22
  @appender.debug
22
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- \n/, @io.string
23
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File\n/, @io.string
23
24
  end
24
25
 
25
26
  it 'handle message' do
@@ -37,18 +38,48 @@ module Appender
37
38
  assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str} -- Exception: StandardError: StandardError\n\n/, @io.string
38
39
  end
39
40
 
40
- it 'handle exception only' do
41
+ it 'logs exception with nil backtrace' do
41
42
  @appender.debug StandardError.new('StandardError')
42
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- #<StandardError: StandardError> -- Exception: StandardError: StandardError\n\n/, @io.string
43
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- Exception: StandardError: StandardError\n\n/, @io.string
44
+ end
45
+
46
+ it 'handle nested exception' do
47
+ begin
48
+ raise StandardError, 'FirstError'
49
+ rescue Exception => e
50
+ begin
51
+ raise StandardError, 'SecondError'
52
+ rescue Exception => e2
53
+ @appender.debug e2
54
+ end
55
+ end
56
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name} file_test.rb:\d+\] SemanticLogger::Appender::File -- Exception: StandardError: SecondError\n/, @io.string
57
+ assert_match /^Cause: StandardError: FirstError\n/, @io.string if Exception.instance_methods.include?(:cause)
58
+ end
59
+
60
+ it 'logs exception with empty backtrace' do
61
+ exc = StandardError.new('StandardError')
62
+ exc.set_backtrace([])
63
+ @appender.debug exc
64
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- Exception: StandardError: StandardError\n\n/, @io.string
43
65
  end
44
66
  end
45
67
 
46
68
  describe 'for each log level' do
47
69
  # Ensure that any log level can be logged
48
70
  SemanticLogger::LEVELS.each do |level|
49
- it "log #{level} information" do
50
- @appender.send(level, 'hello world', @hash)
51
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string
71
+ it "log #{level} with file_name" do
72
+ SemanticLogger.stub(:backtrace_level_index, 0) do
73
+ @appender.send(level, 'hello world', @hash)
74
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:#{@thread_name}#{@file_name_reg_exp}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string
75
+ end
76
+ end
77
+
78
+ it "log #{level} without file_name" do
79
+ SemanticLogger.stub(:backtrace_level_index, 100) do
80
+ @appender.send(level, 'hello world', @hash)
81
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:#{@thread_name}\] SemanticLogger::Appender::File -- hello world -- #{@hash_str}\n/, @io.string
82
+ end
52
83
  end
53
84
  end
54
85
  end
@@ -64,7 +95,7 @@ module Appender
64
95
 
65
96
  duration_str = log.duration ? " (#{'%.1f' % log.duration}ms)" : ''
66
97
 
67
- "#{SemanticLogger::Appender::Base.formatted_time(log.time)} #{log.level.to_s.upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}#{duration_str}"
98
+ "#{log.formatted_time} #{log.level.to_s.upcase} [#{$$}:#{log.thread_name}] #{tags}#{log.name} -- #{message}#{duration_str}"
68
99
  end
69
100
  end
70
101
 
@@ -66,7 +66,7 @@ module Appender
66
66
  end
67
67
 
68
68
  it "handle message without payload" do
69
- log = SemanticLogger::Base::Log.new(:debug)
69
+ log = SemanticLogger::Log.new(:debug)
70
70
  @appender.debug('hello world')
71
71
 
72
72
  document = @appender.collection.find_one
@@ -1,4 +1,4 @@
1
- require_relative 'test_helper'
1
+ require_relative '../test_helper'
2
2
 
3
3
  # Unit Test for SemanticLogger::Appender::Splunk
4
4
  #
@@ -3,66 +3,66 @@ require_relative '../test_helper'
3
3
  # Unit Test for SemanticLogger::Appender::Wrapper
4
4
  #
5
5
  module Appender
6
- class WrapperTest < Minitest::Test
7
- describe SemanticLogger::Appender::Wrapper do
8
- before do
9
- @time = Time.new
10
- @mock_logger = MockLogger.new
11
- @appender = SemanticLogger::Appender::Wrapper.new(@mock_logger)
12
- @hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
13
- @hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
14
- end
15
-
16
- describe 'format logs into text form' do
17
- it 'handle nil name, message and payload' do
18
- log = SemanticLogger::Logger::Log.new
19
- log.time = Time.now
20
- log.level = :debug
21
- @appender.log(log)
22
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] -- /, @mock_logger.message
6
+ class WrapperTest < Minitest::Test
7
+ describe SemanticLogger::Appender::Wrapper do
8
+ before do
9
+ @time = Time.new
10
+ @mock_logger = MockLogger.new
11
+ @appender = SemanticLogger::Appender::Wrapper.new(@mock_logger)
12
+ @hash = {session_id: 'HSSKLEU@JDK767', tracking_number: 12345}
13
+ @hash_str = @hash.inspect.sub("{", "\\{").sub("}", "\\}")
23
14
  end
24
15
 
25
- it 'handle nil message and payload' do
26
- log = SemanticLogger::Logger::Log.new
27
- log.time = Time.now
28
- log.level = :debug
29
- log.name = 'class'
30
- @appender.log(log)
31
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] class -- /, @mock_logger.message
32
- end
16
+ describe 'format logs into text form' do
17
+ it 'handle nil name, message and payload' do
18
+ log = SemanticLogger::Log.new
19
+ log.time = Time.now
20
+ log.level = :debug
21
+ @appender.log(log)
22
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] /, @mock_logger.message
23
+ end
33
24
 
34
- it 'handle nil payload' do
35
- log = SemanticLogger::Logger::Log.new
36
- log.time = Time.now
37
- log.level = :debug
38
- log.name = 'class'
39
- log.message = 'hello world'
40
- @appender.log(log)
41
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] class -- hello world/, @mock_logger.message
42
- end
25
+ it 'handle nil message and payload' do
26
+ log = SemanticLogger::Log.new
27
+ log.time = Time.now
28
+ log.level = :debug
29
+ log.name = 'class'
30
+ @appender.log(log)
31
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] class/, @mock_logger.message
32
+ end
43
33
 
44
- it 'handle payload' do
45
- log = SemanticLogger::Logger::Log.new
46
- log.time = Time.now
47
- log.level = :debug
48
- log.name = 'class'
49
- log.message = 'hello world'
50
- log.payload = @hash
51
- @appender.log(log)
52
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] class -- hello world -- #{@hash_str}/, @mock_logger.message
34
+ it 'handle nil payload' do
35
+ log = SemanticLogger::Log.new
36
+ log.time = Time.now
37
+ log.level = :debug
38
+ log.name = 'class'
39
+ log.message = 'hello world'
40
+ @appender.log(log)
41
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] class -- hello world/, @mock_logger.message
42
+ end
43
+
44
+ it 'handle payload' do
45
+ log = SemanticLogger::Log.new
46
+ log.time = Time.now
47
+ log.level = :debug
48
+ log.name = 'class'
49
+ log.message = 'hello world'
50
+ log.payload = @hash
51
+ @appender.log(log)
52
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:\] class -- hello world -- #{@hash_str}/, @mock_logger.message
53
+ end
53
54
  end
54
- end
55
55
 
56
- describe 'for each log level' do
57
- # Ensure that any log level can be logged
58
- Logger::Severity.constants.each do |level|
59
- it "log #{level.downcase.to_sym} info" do
60
- @appender.log SemanticLogger::Logger::Log.new(level.downcase.to_sym, 'thread', 'class', 'hello world', @hash, Time.now)
61
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:thread\] class -- hello world -- #{@hash_str}/, @mock_logger.message
56
+ describe 'for each log level' do
57
+ # Ensure that any log level can be logged
58
+ Logger::Severity.constants.each do |level|
59
+ it "log #{level.downcase.to_sym} info" do
60
+ @appender.log SemanticLogger::Log.new(level.downcase.to_sym, 'thread', 'class', 'hello world', @hash, Time.now)
61
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ \w \[\d+:thread\] class -- hello world -- #{@hash_str}/, @mock_logger.message
62
+ end
62
63
  end
63
64
  end
64
- end
65
65
 
66
+ end
66
67
  end
67
68
  end
68
- end
data/test/logger_test.rb CHANGED
@@ -133,13 +133,13 @@ class LoggerTest < Minitest::Test
133
133
  it "log #{level} info" do
134
134
  assert_equal 'result', @logger.send("benchmark_#{level}".to_sym, 'hello world') { 'result' } # Measure duration of the supplied block
135
135
  SemanticLogger.flush
136
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
136
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
137
137
  end
138
138
 
139
139
  it "log #{level} info with payload" do
140
140
  assert_equal 'result', @logger.send("benchmark_#{level}".to_sym, 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
141
141
  SemanticLogger.flush
142
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
142
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
143
143
  end
144
144
 
145
145
  it "not log #{level} info when block is faster than :min_duration" do
@@ -151,7 +151,7 @@ class LoggerTest < Minitest::Test
151
151
  it "log #{level} info when block duration exceeds :min_duration" do
152
152
  assert_equal 'result', @logger.send("benchmark_#{level}".to_sym, 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
153
153
  SemanticLogger.flush
154
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
154
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
155
155
  end
156
156
 
157
157
  it "log #{level} info with an exception" do
@@ -159,7 +159,7 @@ class LoggerTest < Minitest::Test
159
159
  @logger.send("benchmark_#{level}", 'hello world', payload: @hash) { raise RuntimeError.new("Test") } # Measure duration of the supplied block
160
160
  end
161
161
  SemanticLogger.flush
162
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \(\d+\.\dms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
162
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
163
163
  end
164
164
 
165
165
  it "change log #{level} info with an exception" do
@@ -167,14 +167,14 @@ class LoggerTest < Minitest::Test
167
167
  @logger.send("benchmark_#{level}", 'hello world', payload: @hash, on_exception_level: :fatal) { raise RuntimeError.new("Test") } # Measure duration of the supplied block
168
168
  end
169
169
  SemanticLogger.flush
170
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ F \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \(\d+\.\dms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
170
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ F \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
171
171
  end
172
172
 
173
173
  it "log #{level} info with metric" do
174
174
  metric_name = '/my/custom/metric'
175
175
  assert_equal 'result', @logger.send("benchmark_#{level}".to_sym, 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
176
176
  SemanticLogger.flush
177
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
177
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
178
178
  assert metric_name, $last_metric.metric
179
179
  end
180
180
 
@@ -182,7 +182,7 @@ class LoggerTest < Minitest::Test
182
182
  SemanticLogger.stub(:backtrace_level_index, 0) do
183
183
  assert_equal 'result', @logger.send("benchmark_#{level}".to_sym, 'hello world') { 'result' }
184
184
  SemanticLogger.flush
185
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
185
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
186
186
  end
187
187
  end
188
188
  end
@@ -191,13 +191,13 @@ class LoggerTest < Minitest::Test
191
191
  it "log #{level} info" do
192
192
  assert_equal 'result', @logger.benchmark(level, 'hello world') { 'result' } # Measure duration of the supplied block
193
193
  SemanticLogger.flush
194
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
194
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
195
195
  end
196
196
 
197
197
  it "log #{level} info with payload" do
198
198
  assert_equal 'result', @logger.benchmark(level, 'hello world', payload: @hash) { 'result' } # Measure duration of the supplied block
199
199
  SemanticLogger.flush
200
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
200
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
201
201
  end
202
202
 
203
203
  it "not log #{level} info when block is faster than :min_duration" do
@@ -209,7 +209,7 @@ class LoggerTest < Minitest::Test
209
209
  it "log #{level} info when block duration exceeds :min_duration" do
210
210
  assert_equal 'result', @logger.benchmark(level, 'hello world', min_duration: 200, payload: @hash) { sleep 0.5; 'result' } # Measure duration of the supplied block
211
211
  SemanticLogger.flush
212
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
212
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
213
213
  end
214
214
 
215
215
  it "log #{level} info with an exception" do
@@ -217,14 +217,14 @@ class LoggerTest < Minitest::Test
217
217
  @logger.benchmark(level, 'hello world', payload: @hash) { raise RuntimeError.new('Test') } # Measure duration of the supplied block
218
218
  end
219
219
  SemanticLogger.flush
220
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \(\d+\.\dms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
220
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- Exception: RuntimeError: Test -- #{@hash_str}/, @mock_logger.message
221
221
  end
222
222
 
223
223
  it "log #{level} info with metric" do
224
224
  metric_name = '/my/custom/metric'
225
225
  assert_equal 'result', @logger.benchmark(level, 'hello world', metric: metric_name) { 'result' } # Measure duration of the supplied block
226
226
  SemanticLogger.flush
227
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
227
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
228
228
  assert metric_name, $last_metric.metric
229
229
  end
230
230
 
@@ -232,7 +232,7 @@ class LoggerTest < Minitest::Test
232
232
  SemanticLogger.stub(:backtrace_level_index, 0) do
233
233
  assert_equal 'result', @logger.benchmark(level, 'hello world') { 'result' }
234
234
  SemanticLogger.flush
235
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
235
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ #{level_char} \[\d+:#{@thread_name}#{@file_name_reg_exp}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
236
236
  end
237
237
  end
238
238
  end
@@ -241,7 +241,7 @@ class LoggerTest < Minitest::Test
241
241
  it 'log when the block performs a return' do
242
242
  assert_equal 'Good', function_with_return(@logger)
243
243
  SemanticLogger.flush
244
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
244
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world -- #{@hash_str}/, @mock_logger.message
245
245
  end
246
246
 
247
247
  it 'not log at a level below the silence level' do
@@ -250,7 +250,7 @@ class LoggerTest < Minitest::Test
250
250
  @logger.warn "don't log me"
251
251
  end
252
252
  SemanticLogger.flush
253
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
253
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
254
254
  end
255
255
 
256
256
  it 'log at a silence level below the default level' do
@@ -264,7 +264,7 @@ class LoggerTest < Minitest::Test
264
264
  assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ D \[\d+:#{@thread_name}\] LoggerTest -- hello world -- Calculations -- #{@hash_str}/, first_message
265
265
  SemanticLogger.flush
266
266
  # Only the last log message is kept in mock logger
267
- assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \(\d+\.\dms\) LoggerTest -- hello world/, @mock_logger.message
267
+ assert_match /\d+-\d+-\d+ \d+:\d+:\d+.\d+ I \[\d+:#{@thread_name}\] \((\d+\.\d+)|(\d+)ms\) LoggerTest -- hello world/, @mock_logger.message
268
268
  end
269
269
  end
270
270
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.0
4
+ version: 2.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-05 00:00:00.000000000 Z
11
+ date: 2015-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sync_attr
@@ -62,6 +62,7 @@ files:
62
62
  - lib/semantic_logger/core_ext/thread.rb
63
63
  - lib/semantic_logger/debug_as_trace_logger.rb
64
64
  - lib/semantic_logger/jruby/garbage_collection_logger.rb
65
+ - lib/semantic_logger/log.rb
65
66
  - lib/semantic_logger/loggable.rb
66
67
  - lib/semantic_logger/logger.rb
67
68
  - lib/semantic_logger/semantic_logger.rb