semantic_logger 4.7.3 → 4.8.2

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