semantic_logger 4.7.3 → 4.8.2

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
  SHA256:
3
- metadata.gz: 4b10135713f7777b24e23191888a3341d20e39f4576c3f93fb92e008212c71f1
4
- data.tar.gz: 13d48205904e7bc452621c8f65da454dc7f77c21592318324bbffef2a1bf5bae
3
+ metadata.gz: d0bd2e2a218bdbf0bfa67ca85da999b352de9b214383890278c0710cd3f84e91
4
+ data.tar.gz: dd3b393e8f0a031ddb25c2ca3cdeaa7d761617586f366006e79d7fcf3de8a9a5
5
5
  SHA512:
6
- metadata.gz: 1c721150d177559864111177271517e51f1c52dae5ee8783839ef32ac09f24cfedcd2757f0406fabc10d181d5214521bdfd625b1def340236f74ed51ecf6ecaf
7
- data.tar.gz: adbea6f546bd0dfaa9ba59d45950fdb775f0ea308599a4a50d2aad4353ac7809f8930c4013fdc1d4f9d0ece963728347ba06b726c6e6078ceb68302dde1b721d
6
+ metadata.gz: dba969cf8d70cbb63a6542a692b68773f395eda22515267c572630aa5180a3bbfe490f2096e83cc366f06e86bbf06bafc87d2e5800810110107ac5080b7a1046
7
+ data.tar.gz: 35d69548ee2a91fb4d7c0575ea2d1da48648a7352d52304e8f270a6fe095c42e7ad1367594cef0b14941e14fc47906816df2360899c37fc577828b368c71c21a
data/README.md CHANGED
@@ -1,15 +1,13 @@
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/support)
2
+ [![Gem Version](https://img.shields.io/gem/v/semantic_logger.svg)](https://rubygems.org/gems/semantic_logger) [![Build Status](https://github.com/reidmorrison/semantic_logger/workflows/build/badge.svg)](https://github.com/reidmorrison/semantic_logger/actions?query=workflow%3Abuild) [![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)
3
3
 
4
4
  Semantic Logger is a feature rich logging framework, and replacement for existing Ruby & Rails loggers.
5
5
 
6
- * https://rocketjob.github.io/semantic_logger/
6
+ * https://logger.rocketjob.io/
7
7
 
8
8
  ## Documentation
9
9
 
10
- [Semantic Logger Guide](http://rocketjob.github.io/semantic_logger)
11
-
12
- [Reference Documentation](http://www.rubydoc.info/gems/semantic_logger/)
10
+ [Semantic Logger Guide](https://logger.rocketjob.io/)
13
11
 
14
12
  ## Upgrading to Semantic Logger v4.4
15
13
 
@@ -50,7 +48,7 @@ handles saving log information to multiple destinations / appenders.
50
48
 
51
49
  ## Rails
52
50
 
53
- When running Rails, use [rails_semantic_logger](http://github.com/rocketjob/rails_semantic_logger)
51
+ When running Rails, use [rails_semantic_logger](http://github.com/reidmorrison/rails_semantic_logger)
54
52
  instead of Semantic Logger directly since it will automatically replace the Rails default logger with Semantic Logger.
55
53
 
56
54
  ## Rocket Job
@@ -129,13 +127,13 @@ SemanticLogger.default_level = :trace
129
127
  SemanticLogger.add_appender(file_name: 'development.log', formatter: :color)
130
128
  ~~~
131
129
 
132
- If running rails, see: [Semantic Logger Rails](http://rocketjob.github.io/semantic_logger/rails.html)
130
+ If running rails, see: [Semantic Logger Rails](https://logger.rocketjob.io/rails.html)
133
131
 
134
132
  ## Author
135
133
 
136
134
  [Reid Morrison](https://github.com/reidmorrison)
137
135
 
138
- [Contributors](https://github.com/rocketjob/semantic_logger/graphs/contributors)
136
+ [Contributors](https://github.com/reidmorrison/semantic_logger/graphs/contributors)
139
137
 
140
138
  ## Versioning
141
139
 
@@ -66,7 +66,8 @@ module SemanticLogger
66
66
  elsif appender.is_a?(Subscriber)
67
67
  appender
68
68
  else
69
- raise(ArgumentError, "Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
69
+ raise(ArgumentError,
70
+ "Parameter :appender must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
70
71
  end
71
72
  elsif metric
72
73
  if metric.is_a?(Symbol)
@@ -74,10 +75,12 @@ module SemanticLogger
74
75
  elsif metric.is_a?(Subscriber)
75
76
  metric
76
77
  else
77
- raise(ArgumentError, "Parameter :metric must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
78
+ raise(ArgumentError,
79
+ "Parameter :metric must be either a Symbol or an object derived from SemanticLogger::Subscriber, not: #{appender.inspect}")
78
80
  end
79
81
  else
80
- raise(ArgumentError, "To create an appender it must supply one of the following: :io, :file_name, :appender, :metric, or :logger")
82
+ raise(ArgumentError,
83
+ "To create an appender it must supply one of the following: :io, :file_name, :appender, :metric, or :logger")
81
84
  end
82
85
  end
83
86
 
@@ -53,7 +53,7 @@ module SemanticLogger
53
53
  # Re-open appender after a fork
54
54
  def reopen
55
55
  # Workaround CRuby crash on fork by recreating queue on reopen
56
- # https://github.com/rocketjob/semantic_logger/issues/103
56
+ # https://github.com/reidmorrison/semantic_logger/issues/103
57
57
  @queue&.close
58
58
  create_queue
59
59
 
@@ -1,7 +1,8 @@
1
1
  begin
2
2
  require "elasticsearch"
3
3
  rescue LoadError
4
- raise LoadError, 'Gem elasticsearch is required for logging to Elasticsearch. Please add the gem "elasticsearch" to your Gemfile.'
4
+ raise LoadError,
5
+ 'Gem elasticsearch is required for logging to Elasticsearch. Please add the gem "elasticsearch" to your Gemfile.'
5
6
  end
6
7
 
7
8
  require "date"
@@ -17,7 +18,8 @@ require "date"
17
18
  module SemanticLogger
18
19
  module Appender
19
20
  class Elasticsearch < SemanticLogger::Subscriber
20
- attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size, :elasticsearch_args
21
+ attr_accessor :url, :index, :date_pattern, :type, :client, :flush_interval, :timeout_interval, :batch_size,
22
+ :elasticsearch_args
21
23
 
22
24
  # Create Elasticsearch appender over persistent HTTP(S)
23
25
  #
@@ -36,7 +36,7 @@ module SemanticLogger
36
36
  # SemanticLogger.default_level = :info
37
37
  #
38
38
  # # Log to screen
39
- # SemanticLogger.add_appender(io: STDOUT, formatter: :color)
39
+ # SemanticLogger.add_appender(io: $stdout, formatter: :color)
40
40
  #
41
41
  # # And log to a file at the same time
42
42
  # SemanticLogger.add_appender(file_name: 'application.log', formatter: :color)
@@ -52,7 +52,7 @@ module SemanticLogger
52
52
  # SemanticLogger.default_level = :trace
53
53
  #
54
54
  # # Log to screen but only display :info and above
55
- # SemanticLogger.add_appender(io: STDOUT, level: :info)
55
+ # SemanticLogger.add_appender(io: $stdout, level: :info)
56
56
  #
57
57
  # # And log to a file at the same time, including all :trace level data
58
58
  # SemanticLogger.add_appender(file_name: 'application.log')
@@ -62,9 +62,14 @@ module SemanticLogger
62
62
  def initialize(io: nil, file_name: nil, **args, &block)
63
63
  if io
64
64
  @log = io
65
+ unless @log.respond_to?(:write)
66
+ raise(ArgumentError, "SemanticLogging::Appender::File :io is not a valid IO instance: #{io.inspect}")
67
+ end
65
68
  else
66
69
  @file_name = file_name
67
- raise "SemanticLogging::Appender::File missing mandatory parameter :file_name or :io" unless file_name
70
+ unless file_name
71
+ raise(ArgumentError, "SemanticLogging::Appender::File missing mandatory parameter :file_name or :io")
72
+ end
68
73
 
69
74
  reopen
70
75
  end
@@ -105,6 +110,10 @@ module SemanticLogger
105
110
  def flush
106
111
  @log.flush if @log.respond_to?(:flush)
107
112
  end
113
+
114
+ def console_output?
115
+ [$stderr, $stdout].include?(@log)
116
+ end
108
117
  end
109
118
  end
110
119
  end
@@ -183,6 +183,10 @@ module SemanticLogger
183
183
  delivery_interval: delivery_interval
184
184
  )
185
185
  end
186
+
187
+ private
188
+
189
+ attr_reader :producer
186
190
  end
187
191
  end
188
192
  end
@@ -1,7 +1,8 @@
1
1
  begin
2
2
  require "splunk-sdk-ruby"
3
3
  rescue LoadError
4
- raise LoadError, 'Gem splunk-sdk-ruby is required for logging to Splunk. Please add the gem "splunk-sdk-ruby" to your Gemfile.'
4
+ raise LoadError,
5
+ 'Gem splunk-sdk-ruby is required for logging to Splunk. Please add the gem "splunk-sdk-ruby" to your Gemfile.'
5
6
  end
6
7
 
7
8
  # Splunk log appender.
@@ -89,9 +89,9 @@ module SemanticLogger
89
89
  # For splunk format requirements see:
90
90
  # https://docs.splunk.com/Documentation/Splunk/latest/Data/FormateventsforHTTPEventCollector
91
91
  def call(log, logger)
92
- h = SemanticLogger::Formatters::Raw.new(time_format: :seconds).call(log, logger)
92
+ h = SemanticLogger::Formatters::Raw.new(time_format: :seconds).call(log, logger)
93
93
  h.delete(:host)
94
- message = {
94
+ message = {
95
95
  source: logger.application,
96
96
  host: logger.host,
97
97
  time: h.delete(:time),
@@ -57,7 +57,7 @@ module SemanticLogger
57
57
  # Only used with the TCP protocol.
58
58
  # Specify custom parameters to pass into Net::TCPClient.new
59
59
  # For a list of options see the net_tcp_client documentation:
60
- # https://github.com/rocketjob/net_tcp_client/blob/master/lib/net/tcp_client/tcp_client.rb
60
+ # https://github.com/reidmorrison/net_tcp_client/blob/master/lib/net/tcp_client/tcp_client.rb
61
61
  #
62
62
  # level: [:trace | :debug | :info | :warn | :error | :fatal]
63
63
  # Override the log level for this appender.
@@ -151,7 +151,8 @@ module SemanticLogger
151
151
  begin
152
152
  require "syslog_protocol"
153
153
  rescue LoadError
154
- raise LoadError, "Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol"
154
+ raise LoadError,
155
+ "Missing gem: syslog_protocol. This gem is required when logging over TCP or UDP. To fix this error: gem install syslog_protocol"
155
156
  end
156
157
 
157
158
  # The net_tcp_client gem is required when logging over TCP.
@@ -159,7 +160,8 @@ module SemanticLogger
159
160
  begin
160
161
  require "net/tcp_client"
161
162
  rescue LoadError
162
- raise LoadError, "Missing gem: net_tcp_client. This gem is required when logging over TCP. To fix this error: gem install net_tcp_client"
163
+ raise LoadError,
164
+ "Missing gem: net_tcp_client. This gem is required when logging over TCP. To fix this error: gem install net_tcp_client"
163
165
  end
164
166
  end
165
167
  end
@@ -32,7 +32,7 @@ module SemanticLogger
32
32
  # require 'logger'
33
33
  # require 'semantic_logger'
34
34
  #
35
- # ruby_logger = Logger.new(STDOUT)
35
+ # ruby_logger = Logger.new($stdout)
36
36
  # SemanticLogger.add_appender(logger: ruby_logger)
37
37
  #
38
38
  # logger = SemanticLogger['test']
@@ -45,7 +45,8 @@ module SemanticLogger
45
45
  # Check if the custom appender responds to all the log levels. For example Ruby ::Logger
46
46
  does_not_implement = LEVELS[1..-1].find { |i| !@logger.respond_to?(i) }
47
47
  if does_not_implement
48
- raise(ArgumentError, "Supplied logger does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}")
48
+ raise(ArgumentError,
49
+ "Supplied logger does not implement:#{does_not_implement}. It must implement all of #{LEVELS[1..-1].inspect}")
49
50
  end
50
51
 
51
52
  super(**args, &block)
@@ -10,42 +10,48 @@ module SemanticLogger
10
10
 
11
11
  def add(**args, &block)
12
12
  appender = SemanticLogger::Appender.factory(**args, &block)
13
+
14
+ if appender.respond_to?(:console_output?) && appender.console_output? && console_output?
15
+ logger.warn "Ignoring attempt to add a second console appender: #{appender.class.name} since it would result in duplicate console output."
16
+ return
17
+ end
18
+
13
19
  self << appender
14
20
  appender
15
21
  end
16
22
 
23
+ # Whether any of the existing appenders already output to the console?
24
+ # I.e. Writes to stdout or stderr.
25
+ def console_output?
26
+ any? { |appender| appender.respond_to?(:console_output?) && appender.console_output? }
27
+ end
28
+
17
29
  def log(log)
18
30
  each do |appender|
19
- begin
20
- appender.log(log) if appender.should_log?(log)
21
- rescue Exception => e
22
- logger.error "Failed to log to appender: #{appender.name}", e
23
- end
31
+ appender.log(log) if appender.should_log?(log)
32
+ rescue Exception => e
33
+ logger.error "Failed to log to appender: #{appender.name}", e
24
34
  end
25
35
  end
26
36
 
27
37
  def flush
28
38
  each do |appender|
29
- begin
30
- logger.trace "Flushing appender: #{appender.name}"
31
- appender.flush
32
- rescue Exception => e
33
- logger.error "Failed to flush appender: #{appender.name}", e
34
- end
39
+ logger.trace "Flushing appender: #{appender.name}"
40
+ appender.flush
41
+ rescue Exception => e
42
+ logger.error "Failed to flush appender: #{appender.name}", e
35
43
  end
36
44
  logger.trace "All appenders flushed"
37
45
  end
38
46
 
39
47
  def close
40
- each do |appender|
41
- begin
42
- logger.trace "Closing appender: #{appender.name}"
43
- appender.flush
44
- appender.close
45
- delete(appender)
46
- rescue Exception => e
47
- logger.error "Failed to close appender: #{appender.name}", e
48
- end
48
+ to_a.each do |appender|
49
+ logger.trace "Closing appender: #{appender.name}"
50
+ delete(appender)
51
+ appender.flush
52
+ appender.close
53
+ rescue Exception => e
54
+ logger.error "Failed to close appender: #{appender.name}", e
49
55
  end
50
56
  logger.trace "All appenders closed and removed from appender list"
51
57
  end
@@ -53,14 +59,12 @@ module SemanticLogger
53
59
  # After a fork the appender thread is not running, start it if it is not running.
54
60
  def reopen
55
61
  each do |appender|
56
- begin
57
- next unless appender.respond_to?(:reopen)
62
+ next unless appender.respond_to?(:reopen)
58
63
 
59
- logger.trace "Reopening appender: #{appender.name}"
60
- appender.reopen
61
- rescue Exception => e
62
- logger.error "Failed to re-open appender: #{appender.name}", e
63
- end
64
+ logger.trace "Reopening appender: #{appender.name}"
65
+ appender.reopen
66
+ rescue Exception => e
67
+ logger.error "Failed to re-open appender: #{appender.name}", e
64
68
  end
65
69
  logger.trace "All appenders re-opened"
66
70
  end
@@ -63,7 +63,7 @@ module SemanticLogger
63
63
  # SemanticLogger.default_level = :info
64
64
  #
65
65
  # # Log to screen
66
- # SemanticLogger.add_appender(io: STDOUT, formatter: :color)
66
+ # SemanticLogger.add_appender(io: $stdout, formatter: :color)
67
67
  #
68
68
  # # And log to a file at the same time
69
69
  # SemanticLogger.add_appender(file_name: 'application.log', formatter: :color)
@@ -136,7 +136,7 @@ module SemanticLogger
136
136
 
137
137
  backtrace =
138
138
  if thread == Thread.current
139
- Utils.extract_backtrace
139
+ Utils.extract_backtrace(caller)
140
140
  else
141
141
  log.thread_name = thread.name
142
142
  log.tags = (thread[:semantic_logger_tags] || []).clone
@@ -263,14 +263,22 @@ module SemanticLogger
263
263
  # For example if set to :warn, this appender would only log :warn and :fatal
264
264
  # log messages when other appenders could be logging :info and lower
265
265
  #
266
- # filter [Regexp|Proc]
266
+ # filter [Regexp|Proc|Module]
267
267
  # RegExp: Only include log messages where the class name matches the supplied
268
268
  # regular expression. All other messages will be ignored
269
269
  # Proc: Only include log messages where the supplied Proc returns true
270
270
  # The Proc must return true or false
271
+ # Module: A module that implements `.call`. For example:
272
+ # module ComplexFilter
273
+ # def self.call(log)
274
+ # (/\AExclude/ =~ log.message).nil?
275
+ # end
276
+ # end
271
277
  def initialize(klass, level = nil, filter = nil)
272
- # Support filtering all messages to this logger using a Regular Expression or Proc
273
- raise ":filter must be a Regexp or Proc" unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc)
278
+ # Support filtering all messages to this logger instance.
279
+ unless filter.nil? || filter.is_a?(Regexp) || filter.is_a?(Proc) || filter.respond_to?(:call)
280
+ raise ":filter must be a Regexp, Proc, or implement :call"
281
+ end
274
282
 
275
283
  @filter = filter.is_a?(Regexp) ? filter.freeze : filter
276
284
  @name = klass.is_a?(String) ? klass : klass.name
@@ -368,7 +376,7 @@ module SemanticLogger
368
376
  exception = e
369
377
  ensure
370
378
  # Must use ensure block otherwise a `return` in the yield above will skip the log entry
371
- log = Log.new(name, level, index)
379
+ log = Log.new(name, level, index)
372
380
  exception ||= params[:exception]
373
381
  message = params[:message] if params[:message]
374
382
  duration =
@@ -1,16 +1,15 @@
1
1
  module SemanticLogger
2
2
  module Formatters
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"
13
- # @formatter:on
3
+ autoload :Base, "semantic_logger/formatters/base"
4
+ autoload :Color, "semantic_logger/formatters/color"
5
+ autoload :Default, "semantic_logger/formatters/default"
6
+ autoload :Json, "semantic_logger/formatters/json"
7
+ autoload :Raw, "semantic_logger/formatters/raw"
8
+ autoload :OneLine, "semantic_logger/formatters/one_line"
9
+ autoload :Signalfx, "semantic_logger/formatters/signalfx"
10
+ autoload :Syslog, "semantic_logger/formatters/syslog"
11
+ autoload :Fluentd, "semantic_logger/formatters/fluentd"
12
+ autoload :Logfmt, "semantic_logger/formatters/logfmt"
14
13
 
15
14
  # Return formatter that responds to call.
16
15
  #
@@ -109,14 +109,14 @@ module SemanticLogger
109
109
  def payload
110
110
  return unless log.payload?
111
111
 
112
- if !log.payload.respond_to?(:ai)
113
- super
114
- else
112
+ if log.payload.respond_to?(:ai)
115
113
  begin
116
114
  "-- #{log.payload.ai(@ai_options)}"
117
115
  rescue StandardError
118
116
  super
119
117
  end
118
+ else
119
+ super
120
120
  end
121
121
  end
122
122
 
@@ -0,0 +1,54 @@
1
+ require "json"
2
+
3
+ module SemanticLogger
4
+ module Formatters
5
+ class Logfmt < Raw
6
+ def initialize(time_format: :iso_8601, time_key: :timestamp, **args)
7
+ super(time_format: time_format, time_key: time_key, **args)
8
+ end
9
+
10
+ def call(log, logger)
11
+ @raw = super(log, logger)
12
+
13
+ raw_to_logfmt
14
+ end
15
+
16
+ private
17
+
18
+ def raw_to_logfmt
19
+ @parsed = @raw.slice(:timestamp, :level, :name, :message, :duration).merge tag: "success"
20
+ handle_payload
21
+ handle_exception
22
+
23
+ flatten_log
24
+ end
25
+
26
+ def handle_payload
27
+ return unless @raw.key? :payload
28
+
29
+ @parsed = @parsed.merge(@raw[:payload])
30
+ end
31
+
32
+ def handle_exception
33
+ return unless @raw.key? :exception
34
+
35
+ @parsed[:tag] = "exception"
36
+ @parsed = @parsed.merge(@raw[:exception])
37
+ end
38
+
39
+ def flatten_log
40
+ flattened = @parsed.map do |key, value|
41
+ "#{key}=#{parse_value(value)}"
42
+ end
43
+
44
+ flattened.join(" ")
45
+ end
46
+
47
+ def parse_value(value)
48
+ return value.to_json if value.instance_of? String
49
+
50
+ value
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,7 +1,8 @@
1
1
  begin
2
2
  require "syslog_protocol"
3
3
  rescue LoadError
4
- raise LoadError, 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
4
+ raise LoadError,
5
+ 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
5
6
  end
6
7
 
7
8
  module SemanticLogger
@@ -1,7 +1,8 @@
1
1
  begin
2
2
  require "syslog_protocol"
3
3
  rescue LoadError
4
- raise LoadError, 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
4
+ raise LoadError,
5
+ 'Gem syslog_protocol is required for remote logging using the Syslog protocol. Please add the gem "syslog_protocol" to your Gemfile.'
5
6
  end
6
7
 
7
8
  module SemanticLogger
@@ -114,14 +114,12 @@ module SemanticLogger
114
114
 
115
115
  # Elastic logging: Log when :duration exceeds :min_duration
116
116
  # Except if there is an exception when it will always be logged
117
- if duration
118
- return false if (duration < min_duration) && exception.nil?
119
- end
117
+ return false if duration && ((duration < min_duration) && exception.nil?)
120
118
 
121
119
  if backtrace
122
120
  self.backtrace = Utils.extract_backtrace(backtrace)
123
121
  elsif level_index >= SemanticLogger.backtrace_level_index
124
- self.backtrace = Utils.extract_backtrace
122
+ self.backtrace = Utils.extract_backtrace(caller)
125
123
  end
126
124
 
127
125
  true
@@ -8,7 +8,7 @@
8
8
  # Example:
9
9
  # require 'semantic_logger'
10
10
  # SemanticLogger.default_level = :debug
11
- # SemanticLogger.add_appender(io: STDOUT, formatter: :color)
11
+ # SemanticLogger.add_appender(io: $stdout, formatter: :color)
12
12
  #
13
13
  # class ExternalSupplier
14
14
  # # Create class and instance logger methods
@@ -32,7 +32,14 @@ module SemanticLogger
32
32
  module Loggable
33
33
  def self.included(base)
34
34
  base.extend ClassMethods
35
+ base.singleton_class.class_eval do
36
+ undef_method :logger if method_defined?(:logger)
37
+ undef_method :logger= if method_defined?(:logger=)
38
+ end
35
39
  base.class_eval do
40
+ undef_method :logger if method_defined?(:logger)
41
+ undef_method :logger= if method_defined?(:logger=)
42
+
36
43
  # Returns [SemanticLogger::Logger] class level logger
37
44
  def self.logger
38
45
  @semantic_logger ||= SemanticLogger[self]
@@ -21,7 +21,19 @@ module SemanticLogger
21
21
  end
22
22
 
23
23
  def self.processor
24
- @processor ||= SemanticLogger.sync? ? SyncProcessor.new : Processor.new
24
+ @processor ||= Processor.new
25
+ end
26
+
27
+ # Switch to the synchronous processor
28
+ def self.sync!
29
+ return if @processor.is_a?(SyncProcessor)
30
+
31
+ @processor = SyncProcessor.new(@processor&.appenders)
32
+ end
33
+
34
+ # Running without the background logging thread?
35
+ def self.sync?
36
+ processor.is_a?(SyncProcessor)
25
37
  end
26
38
 
27
39
  # Returns a Logger instance
@@ -70,11 +82,9 @@ module SemanticLogger
70
82
  return unless @subscribers
71
83
 
72
84
  @subscribers.each do |subscriber|
73
- begin
74
- subscriber.call(log)
75
- rescue Exception => e
76
- processor.logger.error("Exception calling :on_log subscriber", e)
77
- end
85
+ subscriber.call(log)
86
+ rescue Exception => e
87
+ processor.logger.error("Exception calling :on_log subscriber", e)
78
88
  end
79
89
  end
80
90
  end
@@ -1,7 +1,7 @@
1
1
  module SemanticLogger
2
2
  # Thread that submits and processes log requests
3
3
  class Processor < Appender::Async
4
- # Allow the internal logger to be overridden from its default of STDERR
4
+ # Allow the internal logger to be overridden from its default of $stderr
5
5
  # Can be replaced with another Ruby logger or Rails logger, but never to
6
6
  # SemanticLogger::Logger itself since it is for reporting problems
7
7
  # while trying to log to the various appenders
@@ -11,11 +11,11 @@ module SemanticLogger
11
11
 
12
12
  # Internal logger for SemanticLogger
13
13
  # For example when an appender is not working etc..
14
- # By default logs to STDERR
14
+ # By default logs to $stderr
15
15
  def self.logger
16
16
  @logger ||=
17
17
  begin
18
- l = SemanticLogger::Appender::File.new(io: STDERR, level: :warn)
18
+ l = SemanticLogger::Appender::File.new(io: $stderr, level: :warn)
19
19
  l.name = name
20
20
  l
21
21
  end
@@ -101,7 +101,7 @@ module SemanticLogger
101
101
  # Or,
102
102
  # io: [IO]
103
103
  # An IO Stream to log to.
104
- # For example STDOUT, STDERR, etc.
104
+ # For example $stdout, $stderr, etc.
105
105
  #
106
106
  # Or,
107
107
  # appender: [Symbol|SemanticLogger::Subscriber]
@@ -138,14 +138,14 @@ module SemanticLogger
138
138
  # Examples:
139
139
  #
140
140
  # # Send all logging output to Standard Out (Screen)
141
- # SemanticLogger.add_appender(io: STDOUT)
141
+ # SemanticLogger.add_appender(io: $stdout)
142
142
  #
143
143
  # # Send all logging output to a file
144
144
  # SemanticLogger.add_appender(file_name: 'logfile.log')
145
145
  #
146
146
  # # Send all logging output to a file and only :info and above to standard output
147
147
  # SemanticLogger.add_appender(file_name: 'logfile.log')
148
- # SemanticLogger.add_appender(io: STDOUT, level: :info)
148
+ # SemanticLogger.add_appender(io: $stdout, level: :info)
149
149
  #
150
150
  # Log to log4r, Logger, etc.:
151
151
  #
@@ -154,7 +154,7 @@ module SemanticLogger
154
154
  # require 'semantic_logger'
155
155
  #
156
156
  # # Built-in Ruby logger
157
- # log = Logger.new(STDOUT)
157
+ # log = Logger.new($stdout)
158
158
  # log.level = Logger::DEBUG
159
159
  #
160
160
  # SemanticLogger.default_level = :debug
@@ -173,7 +173,15 @@ module SemanticLogger
173
173
  # Remove an existing appender
174
174
  # Currently only supports appender instances
175
175
  def self.remove_appender(appender)
176
+ return unless appender
177
+
176
178
  Logger.processor.appenders.delete(appender)
179
+ appender.close
180
+ end
181
+
182
+ # Clear out all previously registered appenders
183
+ def self.clear_appenders!
184
+ Logger.processor.close
177
185
  end
178
186
 
179
187
  # Returns [SemanticLogger::Subscriber] a copy of the list of active
@@ -494,12 +502,12 @@ module SemanticLogger
494
502
  # I.e. Instead of logging messages in a separate thread for better performance,
495
503
  # log them using the current thread.
496
504
  def self.sync!
497
- @sync = true
505
+ Logger.sync!
498
506
  end
499
507
 
500
508
  # Running in synchronous mode?
501
509
  def self.sync?
502
- @sync
510
+ Logger.sync?
503
511
  end
504
512
 
505
513
  # Initial default Level for all new instances of SemanticLogger::Logger
@@ -10,7 +10,7 @@ module SemanticLogger
10
10
  def_delegator :@appenders, :close
11
11
  def_delegator :@appenders, :reopen
12
12
 
13
- # Allow the internal logger to be overridden from its default of STDERR
13
+ # Allow the internal logger to be overridden from its default of $stderr
14
14
  # Can be replaced with another Ruby logger or Rails logger, but never to
15
15
  # SemanticLogger::Logger itself since it is for reporting problems
16
16
  # while trying to log to the various appenders
@@ -20,11 +20,11 @@ module SemanticLogger
20
20
 
21
21
  # Internal logger for SemanticLogger
22
22
  # For example when an appender is not working etc..
23
- # By default logs to STDERR
23
+ # By default logs to $stderr
24
24
  def self.logger
25
25
  @logger ||=
26
26
  begin
27
- l = SemanticLogger::Appender::File.new(io: STDERR, level: :warn)
27
+ l = SemanticLogger::Appender::File.new(io: $stderr, level: :warn)
28
28
  l.name = name
29
29
  l
30
30
  end
@@ -32,8 +32,8 @@ module SemanticLogger
32
32
 
33
33
  attr_reader :appenders
34
34
 
35
- def initialize
36
- @appenders = Appenders.new(self.class.logger.dup)
35
+ def initialize(appenders = nil)
36
+ @appenders = appenders || Appenders.new(self.class.logger.dup)
37
37
  end
38
38
 
39
39
  def start
@@ -32,29 +32,48 @@ module SemanticLogger
32
32
  end
33
33
  end
34
34
 
35
- SELF_PATTERN = File.join("lib", "semantic_logger")
36
-
37
- # Extract the backtrace leaving out the last few Semantic Logger lines.
35
+ # Extract the backtrace stripping off the leading semantic logger entries.
36
+ # Leaves all other system and gem path entries in place.
38
37
  def self.extract_backtrace(stack = caller)
39
- while (first = stack.first) && first.include?(SELF_PATTERN)
38
+ while (first = stack.first) && extract_path?(first)
40
39
  stack.shift
41
40
  end
42
41
  stack
43
42
  end
44
43
 
45
- # Strips off all gems and built-in ruby code paths from the top of the stack until application code is found.
44
+ def self.extract_paths
45
+ @extract_paths ||= %w[lib/semantic_logger lib/rails_semantic_logger]
46
+ end
47
+
48
+ # Whether this path should be excluded from any cleansed backtrace
49
+ def self.extract_path?(path)
50
+ extract_paths.any? { |exclude| path.include?(exclude) }
51
+ end
52
+
53
+ # Try to strip everything off of the supplied backtrace, until the first application stack entry is at the top.
54
+ # For example all leading gem paths and built-in ruby code paths are removed from the top.
55
+ # Once the first application entry is found, the remaining stack is returned.
46
56
  def self.strip_backtrace(stack = caller)
47
- while (first = stack.first) && system_path?(first)
57
+ while (first = stack.first) && (strip_path?(first) || extract_path?(first))
48
58
  stack.shift
49
59
  end
50
60
  stack
51
61
  end
52
62
 
53
- GEM_ROOT = File.expand_path("../../..", __dir__) + "/"
63
+ # Paths to exclude in the stripped backtrace
64
+ # Includes Gems and built-in Ruby code paths
65
+ def self.strip_paths
66
+ @strip_paths ||=
67
+ begin
68
+ paths = Gem.path | [Gem.default_dir]
69
+ paths << RbConfig::CONFIG["rubylibdir"]
70
+ paths
71
+ end
72
+ end
54
73
 
55
- def self.system_path?(path)
56
- path.start_with?(GEM_ROOT) ||
57
- path.start_with?(RbConfig::CONFIG["rubylibdir"])
74
+ # Whether this path should be excluded from any cleansed backtrace
75
+ def self.strip_path?(path)
76
+ strip_paths.any? { |exclude| path.start_with?(exclude) }
58
77
  end
59
78
  end
60
79
  end
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger
2
- VERSION = "4.7.3".freeze
2
+ VERSION = "4.8.2".freeze
3
3
  end
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: 4.7.3
4
+ version: 4.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-22 00:00:00.000000000 Z
11
+ date: 2021-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -26,7 +26,6 @@ dependencies:
26
26
  version: '1.0'
27
27
  description:
28
28
  email:
29
- - reidmo@gmail.com
30
29
  executables: []
31
30
  extensions: []
32
31
  extra_rdoc_files: []
@@ -68,6 +67,7 @@ files:
68
67
  - lib/semantic_logger/formatters/default.rb
69
68
  - lib/semantic_logger/formatters/fluentd.rb
70
69
  - lib/semantic_logger/formatters/json.rb
70
+ - lib/semantic_logger/formatters/logfmt.rb
71
71
  - lib/semantic_logger/formatters/one_line.rb
72
72
  - lib/semantic_logger/formatters/raw.rb
73
73
  - lib/semantic_logger/formatters/signalfx.rb
@@ -89,7 +89,7 @@ files:
89
89
  - lib/semantic_logger/sync_processor.rb
90
90
  - lib/semantic_logger/utils.rb
91
91
  - lib/semantic_logger/version.rb
92
- homepage: https://github.com/rocketjob/semantic_logger
92
+ homepage: https://logger.rocketjob.io
93
93
  licenses:
94
94
  - Apache-2.0
95
95
  metadata: {}
@@ -101,14 +101,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - ">="
103
103
  - !ruby/object:Gem::Version
104
- version: '2.3'
104
+ version: '2.5'
105
105
  required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  requirements: []
111
- rubygems_version: 3.0.8
111
+ rubygems_version: 3.2.15
112
112
  signing_key:
113
113
  specification_version: 4
114
114
  summary: Feature rich logging framework, and replacement for existing Ruby & Rails