semantic_logger 4.6.1 → 4.7.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +7 -7
  3. data/lib/semantic_logger.rb +23 -22
  4. data/lib/semantic_logger/appender.rb +32 -33
  5. data/lib/semantic_logger/appender/async.rb +9 -8
  6. data/lib/semantic_logger/appender/async_batch.rb +4 -2
  7. data/lib/semantic_logger/appender/bugsnag.rb +7 -7
  8. data/lib/semantic_logger/appender/elasticsearch.rb +10 -10
  9. data/lib/semantic_logger/appender/elasticsearch_http.rb +4 -4
  10. data/lib/semantic_logger/appender/file.rb +2 -1
  11. data/lib/semantic_logger/appender/graylog.rb +12 -10
  12. data/lib/semantic_logger/appender/honeybadger.rb +3 -3
  13. data/lib/semantic_logger/appender/http.rb +20 -18
  14. data/lib/semantic_logger/appender/kafka.rb +5 -5
  15. data/lib/semantic_logger/appender/mongodb.rb +6 -6
  16. data/lib/semantic_logger/appender/new_relic.rb +2 -2
  17. data/lib/semantic_logger/appender/rabbitmq.rb +5 -5
  18. data/lib/semantic_logger/appender/sentry.rb +7 -7
  19. data/lib/semantic_logger/appender/splunk.rb +5 -5
  20. data/lib/semantic_logger/appender/splunk_http.rb +2 -2
  21. data/lib/semantic_logger/appender/syslog.rb +12 -12
  22. data/lib/semantic_logger/appender/tcp.rb +5 -5
  23. data/lib/semantic_logger/appender/udp.rb +2 -2
  24. data/lib/semantic_logger/appenders.rb +11 -11
  25. data/lib/semantic_logger/base.rb +16 -14
  26. data/lib/semantic_logger/formatters.rb +11 -11
  27. data/lib/semantic_logger/formatters/base.rb +8 -3
  28. data/lib/semantic_logger/formatters/color.rb +1 -1
  29. data/lib/semantic_logger/formatters/default.rb +18 -5
  30. data/lib/semantic_logger/formatters/fluentd.rb +3 -3
  31. data/lib/semantic_logger/formatters/json.rb +1 -1
  32. data/lib/semantic_logger/formatters/raw.rb +30 -6
  33. data/lib/semantic_logger/formatters/signalfx.rb +10 -9
  34. data/lib/semantic_logger/formatters/syslog.rb +3 -3
  35. data/lib/semantic_logger/formatters/syslog_cee.rb +3 -3
  36. data/lib/semantic_logger/jruby/garbage_collection_logger.rb +4 -2
  37. data/lib/semantic_logger/levels.rb +9 -7
  38. data/lib/semantic_logger/log.rb +17 -11
  39. data/lib/semantic_logger/logger.rb +6 -6
  40. data/lib/semantic_logger/metric/new_relic.rb +3 -3
  41. data/lib/semantic_logger/metric/signalfx.rb +3 -3
  42. data/lib/semantic_logger/metric/statsd.rb +7 -7
  43. data/lib/semantic_logger/processor.rb +7 -5
  44. data/lib/semantic_logger/reporters/minitest.rb +4 -4
  45. data/lib/semantic_logger/semantic_logger.rb +25 -10
  46. data/lib/semantic_logger/subscriber.rb +6 -5
  47. data/lib/semantic_logger/sync.rb +12 -0
  48. data/lib/semantic_logger/sync_processor.rb +44 -0
  49. data/lib/semantic_logger/utils.rb +6 -6
  50. data/lib/semantic_logger/version.rb +1 -1
  51. metadata +4 -2
@@ -126,7 +126,7 @@ module SemanticLogger
126
126
  # Log a thread backtrace
127
127
  def backtrace(thread: Thread.current,
128
128
  level: :warn,
129
- message: 'Backtrace:',
129
+ message: "Backtrace:",
130
130
  payload: nil,
131
131
  metric: nil,
132
132
  metric_amount: nil)
@@ -190,7 +190,8 @@ module SemanticLogger
190
190
  # Allow named tags to be passed into the logger
191
191
  if tags.size == 1
192
192
  tag = tags[0]
193
- return yield if tag.nil? || tag == ''
193
+ return yield if tag.nil? || tag == ""
194
+
194
195
  return tag.is_a?(Hash) ? SemanticLogger.named_tagged(tag, &block) : SemanticLogger.fast_tag(tag.to_s, &block)
195
196
  end
196
197
 
@@ -240,7 +241,7 @@ module SemanticLogger
240
241
 
241
242
  # Write log data to underlying data storage
242
243
  def log(_log_)
243
- raise NotImplementedError, 'Logging Appender must implement #log(log)'
244
+ raise NotImplementedError, "Logging Appender must implement #log(log)"
244
245
  end
245
246
 
246
247
  # Whether this log entry meets the criteria to be logged by this appender.
@@ -269,7 +270,7 @@ module SemanticLogger
269
270
  # The Proc must return true or false
270
271
  def initialize(klass, level = nil, filter = nil)
271
272
  # Support filtering all messages to this logger using a Regular Expression or Proc
272
- raise ':filter must be a Regexp or Proc' unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc)
273
+ raise ":filter must be a Regexp or Proc" unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc)
273
274
 
274
275
  @filter = filter.is_a?(Regexp) ? filter.freeze : filter
275
276
  @name = klass.is_a?(String) ? klass : klass.name
@@ -308,12 +309,12 @@ module SemanticLogger
308
309
  if payload.nil? && exception.nil? && message.is_a?(Hash)
309
310
  # Check if someone just logged a hash payload instead of meaning to call semantic logger
310
311
  if message.key?(:message) || message.key?(:payload) || message.key?(:exception) || message.key?(:metric)
311
- log.assign(message)
312
+ log.assign(**message)
312
313
  else
313
314
  log.assign_positional(nil, message, nil, &block)
314
315
  end
315
316
  elsif exception.nil? && message && payload && payload.is_a?(Hash) &&
316
- (payload.key?(:payload) || payload.key?(:exception) || payload.key?(:metric))
317
+ (payload.key?(:payload) || payload.key?(:exception) || payload.key?(:metric))
317
318
  log.assign(message: message, **payload)
318
319
  else
319
320
  log.assign_positional(message, payload, exception, &block)
@@ -344,18 +345,18 @@ module SemanticLogger
344
345
  yield(params)
345
346
  end
346
347
  end
347
- rescue Exception => exc
348
- exception = exc
348
+ rescue Exception => e
349
+ exception = e
349
350
  ensure
350
351
  # Must use ensure block otherwise a `return` in the yield above will skip the log entry
351
- log = Log.new(name, level, index)
352
+ log = Log.new(name, level, index)
352
353
  exception ||= params[:exception]
353
- message = params[:message] if params[:message]
354
- duration =
354
+ message = params[:message] if params[:message]
355
+ duration =
355
356
  if block_given?
356
357
  1_000.0 * (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start)
357
358
  else
358
- params[:duration] || raise('Mandatory block missing when :duration option is not supplied')
359
+ params[:duration] || raise("Mandatory block missing when :duration option is not supplied")
359
360
  end
360
361
 
361
362
  # Extract options after block completes so that block can modify any of the options
@@ -377,6 +378,7 @@ module SemanticLogger
377
378
  # Log level may change during assign due to :on_exception_level
378
379
  self.log(log) if should_log && should_log?(log)
379
380
  raise exception if exception
381
+
380
382
  result
381
383
  end
382
384
  end
@@ -395,8 +397,8 @@ module SemanticLogger
395
397
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
396
398
  begin
397
399
  yield
398
- rescue Exception => exc
399
- exception = exc
400
+ rescue Exception => e
401
+ exception = e
400
402
  ensure
401
403
  log = Log.new(name, level, index)
402
404
  # May return false due to elastic logging
@@ -1,15 +1,15 @@
1
1
  module SemanticLogger
2
2
  module Formatters
3
3
  # @formatter:off
4
- autoload :Base, 'semantic_logger/formatters/base'
5
- autoload :Color, 'semantic_logger/formatters/color'
6
- autoload :Default, 'semantic_logger/formatters/default'
7
- autoload :Json, 'semantic_logger/formatters/json'
8
- autoload :Raw, 'semantic_logger/formatters/raw'
9
- autoload :OneLine, 'semantic_logger/formatters/one_line'
10
- autoload :Signalfx, 'semantic_logger/formatters/signalfx'
11
- autoload :Syslog, 'semantic_logger/formatters/syslog'
12
- autoload :Fluentd, 'semantic_logger/formatters/fluentd'
4
+ autoload :Base, "semantic_logger/formatters/base"
5
+ autoload :Color, "semantic_logger/formatters/color"
6
+ autoload :Default, "semantic_logger/formatters/default"
7
+ autoload :Json, "semantic_logger/formatters/json"
8
+ autoload :Raw, "semantic_logger/formatters/raw"
9
+ autoload :OneLine, "semantic_logger/formatters/one_line"
10
+ autoload :Signalfx, "semantic_logger/formatters/signalfx"
11
+ autoload :Syslog, "semantic_logger/formatters/syslog"
12
+ autoload :Fluentd, "semantic_logger/formatters/fluentd"
13
13
  # @formatter:on
14
14
 
15
15
  # Return formatter that responds to call.
@@ -22,10 +22,10 @@ module SemanticLogger
22
22
  # - Any object that responds to :call
23
23
  def self.factory(formatter)
24
24
  if formatter.is_a?(Symbol)
25
- SemanticLogger::Utils.constantize_symbol(formatter, 'SemanticLogger::Formatters').new
25
+ SemanticLogger::Utils.constantize_symbol(formatter, "SemanticLogger::Formatters").new
26
26
  elsif formatter.is_a?(Hash) && formatter.size.positive?
27
27
  fmt, options = formatter.first
28
- SemanticLogger::Utils.constantize_symbol(fmt.to_sym, 'SemanticLogger::Formatters').new(options)
28
+ SemanticLogger::Utils.constantize_symbol(fmt.to_sym, "SemanticLogger::Formatters").new(**options)
29
29
  elsif formatter.respond_to?(:call)
30
30
  formatter
31
31
  else
@@ -1,8 +1,8 @@
1
- require 'time'
1
+ require "time"
2
2
  module SemanticLogger
3
3
  module Formatters
4
4
  class Base
5
- attr_accessor :time_format, :log_host, :log_application, :log_environment, :precision
5
+ attr_accessor :log, :logger, :time_format, :log_host, :log_application, :log_environment, :precision
6
6
 
7
7
  # Time precision varies by Ruby interpreter
8
8
  # JRuby 9.1.8.0 supports microseconds
@@ -61,6 +61,11 @@ module SemanticLogger
61
61
  format_time(log.time) if time_format
62
62
  end
63
63
 
64
+ # Process ID
65
+ def pid
66
+ $$
67
+ end
68
+
64
69
  private
65
70
 
66
71
  # Return the Time as a formatted string
@@ -77,7 +82,7 @@ module SemanticLogger
77
82
  when :seconds
78
83
  time.to_f
79
84
  when nil
80
- ''
85
+ ""
81
86
  else
82
87
  time.strftime(time_format)
83
88
  end
@@ -1,6 +1,6 @@
1
1
  # Load AwesomePrint if available
2
2
  begin
3
- require 'awesome_print'
3
+ require "awesome_print"
4
4
  rescue LoadError
5
5
  nil
6
6
  end
@@ -2,8 +2,6 @@ module SemanticLogger
2
2
  module Formatters
3
3
  # Default non-colored text log output
4
4
  class Default < Base
5
- attr_accessor :log, :logger
6
-
7
5
  # Formatting methods, must return nil, or a string
8
6
  # Nil values are ignored
9
7
 
@@ -12,9 +10,24 @@ module SemanticLogger
12
10
  log.level_to_s
13
11
  end
14
12
 
15
- # Process info
13
+ # Name of the thread that logged the message.
14
+ def thread_name
15
+ format("%.30s", log.thread_name)
16
+ end
17
+
18
+ # Ruby file name and line number that logged the message.
19
+ def file_name_and_line
20
+ file, line = log.file_name_and_line(true)
21
+ "#{file}:#{line}" if file
22
+ end
23
+
24
+ # Returns [String] the available process info
25
+ # Example:
26
+ # [18934:thread_name test_logging.rb:51]
16
27
  def process_info
17
- "[#{log.process_info}]"
28
+ process_id = "#{pid}:" if pid
29
+ fname = file_name_and_line
30
+ fname ? "[#{process_id}#{thread_name} #{fname}]" : "[#{process_id}#{thread_name}]"
18
31
  end
19
32
 
20
33
  # Tags
@@ -67,7 +80,7 @@ module SemanticLogger
67
80
  self.log = log
68
81
  self.logger = logger
69
82
 
70
- [time, level, process_info, tags, named_tags, duration, name, message, payload, exception].compact.join(' ')
83
+ [time, level, process_info, tags, named_tags, duration, name, message, payload, exception].compact.join(" ")
71
84
  end
72
85
  end
73
86
  end
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require "json"
2
2
 
3
3
  module SemanticLogger
4
4
  module Formatters
@@ -13,8 +13,8 @@ module SemanticLogger
13
13
  end
14
14
 
15
15
  def level
16
- hash['severity'] = log.level
17
- hash['severity_index'] = log.level_index
16
+ hash["severity"] = log.level
17
+ hash["severity_index"] = log.level_index
18
18
  end
19
19
 
20
20
  def process_info
@@ -1,4 +1,4 @@
1
- require 'json'
1
+ require "json"
2
2
  module SemanticLogger
3
3
  module Formatters
4
4
  class Json < Raw
@@ -1,9 +1,9 @@
1
- require 'json'
1
+ require "json"
2
2
  module SemanticLogger
3
3
  module Formatters
4
4
  class Raw < Base
5
5
  # Fields are added by populating this hash.
6
- attr_accessor :hash, :log, :logger, :time_key
6
+ attr_accessor :hash, :time_key
7
7
 
8
8
  # By default Raw formatter does not reformat the time
9
9
  def initialize(time_format: :none, time_key: :time, **args)
@@ -37,11 +37,18 @@ module SemanticLogger
37
37
  hash[:level_index] = log.level_index
38
38
  end
39
39
 
40
- # Process info
41
- def process_info
42
- hash[:pid] = $$
40
+ # Process ID
41
+ def pid
42
+ hash[:pid] = super
43
+ end
44
+
45
+ # Name of the thread that logged the message.
46
+ def thread_name
43
47
  hash[:thread] = log.thread_name
48
+ end
44
49
 
50
+ # Ruby file name and line number that logged the message.
51
+ def file_name_and_line
45
52
  file, line = log.file_name_and_line
46
53
  return unless file
47
54
 
@@ -85,6 +92,7 @@ module SemanticLogger
85
92
  # Exception
86
93
  def exception
87
94
  return unless log.exception
95
+
88
96
  root = hash
89
97
  log.each_exception do |exception, i|
90
98
  name = i.zero? ? :exception : :cause
@@ -109,7 +117,23 @@ module SemanticLogger
109
117
  self.log = log
110
118
  self.logger = logger
111
119
 
112
- host; application; environment; time; level; process_info; duration; tags; named_tags; name; message; payload; exception; metric
120
+ host
121
+ application
122
+ environment
123
+ time
124
+ level
125
+ pid
126
+ thread_name
127
+ file_name_and_line
128
+ duration
129
+ tags
130
+ named_tags
131
+ name
132
+ message
133
+ payload
134
+ exception
135
+ metric
136
+
113
137
  hash
114
138
  end
115
139
  end
@@ -1,13 +1,13 @@
1
- require 'json'
1
+ require "json"
2
2
  module SemanticLogger
3
3
  module Formatters
4
4
  class Signalfx < Base
5
- attr_accessor :token, :dimensions, :hash, :log, :logger, :gauge_name, :counter_name
5
+ attr_accessor :token, :dimensions, :hash, :gauge_name, :counter_name
6
6
 
7
7
  def initialize(token:,
8
8
  dimensions: nil,
9
- gauge_name: 'Application.average',
10
- counter_name: 'Application.counter',
9
+ gauge_name: "Application.average",
10
+ counter_name: "Application.counter",
11
11
  time_format: :ms,
12
12
  **args)
13
13
 
@@ -23,19 +23,19 @@ module SemanticLogger
23
23
  # Strip leading '/'
24
24
  # Convert remaining '/' to '.'
25
25
  def metric
26
- name = log.metric.to_s.sub(/\A\/+/, '')
26
+ name = log.metric.to_s.sub(%r{\A/+}, "")
27
27
  if log.dimensions
28
- name.tr!('/', '.')
28
+ name.tr!("/", ".")
29
29
  hash[:metric] = name
30
30
  else
31
31
  # Extract class and action from metric name
32
- names = name.split('/')
32
+ names = name.split("/")
33
33
  h = (hash[:dimensions] ||= {})
34
34
  if names.size > 1
35
35
  h[:action] = names.pop
36
- h[:class] = names.join('::')
36
+ h[:class] = names.join("::")
37
37
  else
38
- h[:class] = 'Unknown'
38
+ h[:class] = "Unknown"
39
39
  h[:action] = names.first || log.metric
40
40
  end
41
41
 
@@ -67,6 +67,7 @@ module SemanticLogger
67
67
  name = name.to_sym
68
68
  value = value.to_s
69
69
  next if value.empty?
70
+
70
71
  h[name] = value if dimensions&.include?(name)
71
72
  end
72
73
  end
@@ -1,7 +1,7 @@
1
1
  begin
2
- require 'syslog_protocol'
2
+ require "syslog_protocol"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.')
4
+ raise LoadError, 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
5
5
  end
6
6
 
7
7
  module SemanticLogger
@@ -73,7 +73,7 @@ module SemanticLogger
73
73
  packet = SyslogProtocol::Packet.new
74
74
  packet.hostname = logger.host
75
75
  packet.facility = facility
76
- packet.tag = logger.application.delete(' ')
76
+ packet.tag = logger.application.delete(" ")
77
77
  packet.content = message
78
78
  packet.time = log.time
79
79
  packet.severity = level_map[log.level]
@@ -1,7 +1,7 @@
1
1
  begin
2
- require 'syslog_protocol'
2
+ require "syslog_protocol"
3
3
  rescue LoadError
4
- raise LoadError.new('Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.')
4
+ raise LoadError, 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
5
5
  end
6
6
 
7
7
  module SemanticLogger
@@ -45,7 +45,7 @@ module SemanticLogger
45
45
  packet = SyslogProtocol::Packet.new
46
46
  packet.hostname = logger.host
47
47
  packet.facility = facility
48
- packet.tag = logger.application.delete(' ')
48
+ packet.tag = logger.application.delete(" ")
49
49
  packet.content = message
50
50
  packet.time = log.time
51
51
  packet.severity = level_map[log.level]
@@ -12,7 +12,9 @@ module SemanticLogger
12
12
  # Must leave the method name as-is so that it can be found by Java
13
13
  def handleNotification(notification, _)
14
14
  # Only care about GARBAGE_COLLECTION_NOTIFICATION notifications
15
- return unless notification.get_type == Java::ComSunManagement::GarbageCollectionNotificationInfo::GARBAGE_COLLECTION_NOTIFICATION
15
+ unless notification.get_type == Java::ComSunManagement::GarbageCollectionNotificationInfo::GARBAGE_COLLECTION_NOTIFICATION
16
+ return
17
+ end
16
18
 
17
19
  info = Java::ComSunManagement::GarbageCollectionNotificationInfo.from(notification.user_data)
18
20
  gc_info = info.gc_info
@@ -20,7 +22,7 @@ module SemanticLogger
20
22
 
21
23
  return unless duration >= @min_microseconds
22
24
 
23
- SemanticLogger['GarbageCollector'].measure_warn(
25
+ SemanticLogger["GarbageCollector"].measure_warn(
24
26
  "Garbage Collection completed: #{info.gc_name} ##{gc_info.id}",
25
27
  duration: duration.to_f / 1000
26
28
  )
@@ -16,17 +16,19 @@ module SemanticLogger
16
16
  LEVELS.index(level)
17
17
  elsif level.is_a?(Integer) && defined?(::Logger::Severity)
18
18
  # Mapping of Rails and Ruby Logger levels to SemanticLogger levels
19
- @map_levels ||= begin
20
- levels = []
21
- ::Logger::Severity.constants.each do |constant|
22
- levels[::Logger::Severity.const_get(constant)] =
23
- LEVELS.find_index(constant.downcase.to_sym) || LEVELS.find_index(:error)
19
+ @map_levels ||=
20
+ begin
21
+ levels = []
22
+ ::Logger::Severity.constants.each do |constant|
23
+ levels[::Logger::Severity.const_get(constant)] =
24
+ LEVELS.find_index(constant.downcase.to_sym) || LEVELS.find_index(:error)
25
+ end
26
+ levels
24
27
  end
25
- levels
26
- end
27
28
  @map_levels[level]
28
29
  end
29
30
  raise "Invalid level:#{level.inspect} being requested. Must be one of #{LEVELS.inspect}" unless index
31
+
30
32
  index
31
33
  end
32
34
 
@@ -87,7 +87,7 @@ module SemanticLogger
87
87
  end
88
88
 
89
89
  self.message = message
90
- if payload && payload.is_a?(Hash)
90
+ if payload&.is_a?(Hash)
91
91
  self.payload = payload
92
92
  elsif payload
93
93
  self.message = message.nil? ? payload.to_s : "#{message} -- #{payload}"
@@ -155,7 +155,7 @@ module SemanticLogger
155
155
  message = message.nil? ? result : "#{message} -- #{result}"
156
156
  assign(message: message, payload: payload, exception: exception)
157
157
  elsif message.nil? && result.is_a?(Hash) && %i[message payload exception].any? { |k| result.key? k }
158
- assign(result)
158
+ assign(**result)
159
159
  elsif payload&.respond_to?(:merge)
160
160
  assign(message: message, payload: payload.merge(result), exception: exception)
161
161
  else
@@ -178,7 +178,7 @@ module SemanticLogger
178
178
  yield(ex, depth)
179
179
 
180
180
  depth += 1
181
- ex =
181
+ ex =
182
182
  if ex.respond_to?(:cause) && ex.cause
183
183
  ex.cause
184
184
  elsif ex.respond_to?(:continued_exception) && ex.continued_exception
@@ -191,7 +191,7 @@ module SemanticLogger
191
191
 
192
192
  # Returns [String] the exception backtrace including all of the child / caused by exceptions
193
193
  def backtrace_to_s
194
- trace = ''
194
+ trace = ""
195
195
  each_exception do |exception, i|
196
196
  if i.zero?
197
197
  trace = (exception.backtrace || []).join("\n")
@@ -212,6 +212,7 @@ module SemanticLogger
212
212
  else
213
213
  def duration_to_s
214
214
  return unless duration
215
+
215
216
  duration < 10.0 ? "#{format('%.3f', duration)}ms" : "#{format('%.1f', duration)}ms"
216
217
  end
217
218
  end
@@ -219,13 +220,14 @@ module SemanticLogger
219
220
  # Returns [String] the duration in human readable form
220
221
  def duration_human
221
222
  return nil unless duration
223
+
222
224
  seconds = duration / 1000
223
225
  if seconds >= 86_400.0 # 1 day
224
226
  "#{(seconds / 86_400).to_i}d #{Time.at(seconds).strftime('%-Hh %-Mm')}"
225
227
  elsif seconds >= 3600.0 # 1 hour
226
- Time.at(seconds).strftime('%-Hh %-Mm')
228
+ Time.at(seconds).strftime("%-Hh %-Mm")
227
229
  elsif seconds >= 60.0 # 1 minute
228
- Time.at(seconds).strftime('%-Mm %-Ss')
230
+ Time.at(seconds).strftime("%-Mm %-Ss")
229
231
  elsif seconds >= 1.0 # 1 second
230
232
  "#{format('%.3f', seconds)}s"
231
233
  else
@@ -238,9 +240,7 @@ module SemanticLogger
238
240
  level.to_s[0..0].upcase
239
241
  end
240
242
 
241
- # Returns [String] the available process info
242
- # Example:
243
- # 18934:thread 23 test_logging.rb:51
243
+ # DEPRECATED
244
244
  def process_info(thread_name_length = 30)
245
245
  file, line = file_name_and_line(true)
246
246
  file_name = " #{file}:#{line}" if file
@@ -248,7 +248,7 @@ module SemanticLogger
248
248
  "#{$$}:#{format("%.#{thread_name_length}s", thread_name)}#{file_name}"
249
249
  end
250
250
 
251
- CALLER_REGEXP = /^(.*):(\d+).*/
251
+ CALLER_REGEXP = /^(.*):(\d+).*/.freeze
252
252
 
253
253
  # Extract the filename and line number from the last entry in the supplied backtrace
254
254
  def extract_file_and_line(stack, short_name = false)
@@ -265,7 +265,7 @@ module SemanticLogger
265
265
 
266
266
  # Strip the standard Rails colorizing from the logged message
267
267
  def cleansed_message
268
- message.to_s.gsub(/(\e(\[([\d;]*[mz]?))?)?/, '').strip
268
+ message.to_s.gsub(/(\e(\[([\d;]*[mz]?))?)?/, "").strip
269
269
  end
270
270
 
271
271
  # Return the payload in text form
@@ -279,6 +279,12 @@ module SemanticLogger
279
279
  !(payload.nil? || (payload.respond_to?(:empty?) && payload.empty?))
280
280
  end
281
281
 
282
+ def to_h(host = SemanticLogger.host, application = SemanticLogger.application, environment = SemanticLogger.environment)
283
+ logger = Struct.new(:host, :application, :environment)
284
+ .new(host, application, environment)
285
+ SemanticLogger::Formatters::Raw.new.call(self, logger)
286
+ end
287
+
282
288
  # Lazy initializes the context hash and assigns a key value pair.
283
289
  def set_context(key, value)
284
290
  (self.context ||= {})[key] = value