semantic_logger 4.5.0 → 4.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +7 -7
  4. data/lib/semantic_logger.rb +23 -22
  5. data/lib/semantic_logger/ansi_colors.rb +0 -10
  6. data/lib/semantic_logger/appender.rb +54 -64
  7. data/lib/semantic_logger/appender/async.rb +10 -8
  8. data/lib/semantic_logger/appender/async_batch.rb +4 -2
  9. data/lib/semantic_logger/appender/bugsnag.rb +7 -7
  10. data/lib/semantic_logger/appender/elasticsearch.rb +12 -11
  11. data/lib/semantic_logger/appender/elasticsearch_http.rb +4 -4
  12. data/lib/semantic_logger/appender/file.rb +2 -1
  13. data/lib/semantic_logger/appender/graylog.rb +15 -10
  14. data/lib/semantic_logger/appender/honeybadger.rb +3 -3
  15. data/lib/semantic_logger/appender/http.rb +20 -18
  16. data/lib/semantic_logger/appender/kafka.rb +5 -5
  17. data/lib/semantic_logger/appender/mongodb.rb +6 -6
  18. data/lib/semantic_logger/appender/new_relic.rb +2 -2
  19. data/lib/semantic_logger/appender/rabbitmq.rb +5 -5
  20. data/lib/semantic_logger/appender/sentry.rb +7 -7
  21. data/lib/semantic_logger/appender/splunk.rb +6 -5
  22. data/lib/semantic_logger/appender/splunk_http.rb +3 -3
  23. data/lib/semantic_logger/appender/syslog.rb +12 -12
  24. data/lib/semantic_logger/appender/tcp.rb +9 -9
  25. data/lib/semantic_logger/appender/udp.rb +2 -2
  26. data/lib/semantic_logger/appenders.rb +13 -34
  27. data/lib/semantic_logger/base.rb +43 -31
  28. data/lib/semantic_logger/formatters.rb +11 -11
  29. data/lib/semantic_logger/formatters/base.rb +15 -6
  30. data/lib/semantic_logger/formatters/color.rb +12 -13
  31. data/lib/semantic_logger/formatters/default.rb +18 -5
  32. data/lib/semantic_logger/formatters/fluentd.rb +7 -18
  33. data/lib/semantic_logger/formatters/json.rb +3 -5
  34. data/lib/semantic_logger/formatters/raw.rb +39 -10
  35. data/lib/semantic_logger/formatters/signalfx.rb +14 -21
  36. data/lib/semantic_logger/formatters/syslog.rb +3 -3
  37. data/lib/semantic_logger/formatters/syslog_cee.rb +3 -3
  38. data/lib/semantic_logger/jruby/garbage_collection_logger.rb +4 -2
  39. data/lib/semantic_logger/levels.rb +9 -7
  40. data/lib/semantic_logger/log.rb +49 -73
  41. data/lib/semantic_logger/logger.rb +6 -8
  42. data/lib/semantic_logger/metric/new_relic.rb +3 -3
  43. data/lib/semantic_logger/metric/signalfx.rb +3 -3
  44. data/lib/semantic_logger/metric/statsd.rb +7 -7
  45. data/lib/semantic_logger/processor.rb +7 -5
  46. data/lib/semantic_logger/reporters/minitest.rb +4 -4
  47. data/lib/semantic_logger/semantic_logger.rb +37 -12
  48. data/lib/semantic_logger/subscriber.rb +14 -7
  49. data/lib/semantic_logger/sync.rb +12 -0
  50. data/lib/semantic_logger/sync_processor.rb +43 -0
  51. data/lib/semantic_logger/utils.rb +6 -6
  52. data/lib/semantic_logger/version.rb +1 -1
  53. metadata +5 -3
@@ -1,4 +1,4 @@
1
- require 'concurrent'
1
+ require "concurrent"
2
2
  module SemanticLogger
3
3
  # Logger stores the class name to be used for all log messages so that every
4
4
  # log message written by this instance will include the class name
@@ -9,7 +9,7 @@ module SemanticLogger
9
9
  subscriber = block || object
10
10
 
11
11
  unless subscriber.is_a?(Proc) || subscriber.respond_to?(:call)
12
- raise('When supplying an on_log subscriber, it must support the #call method')
12
+ raise("When supplying an on_log subscriber, it must support the #call method")
13
13
  end
14
14
 
15
15
  subscribers = (@subscribers ||= Concurrent::Array.new)
@@ -21,7 +21,7 @@ module SemanticLogger
21
21
  end
22
22
 
23
23
  def self.processor
24
- @processor
24
+ @processor ||= SemanticLogger.sync? ? SyncProcessor.new : Processor.new
25
25
  end
26
26
 
27
27
  # Returns a Logger instance
@@ -63,9 +63,7 @@ module SemanticLogger
63
63
  Logger.processor.log(log)
64
64
  end
65
65
 
66
- private
67
-
68
- @processor = Processor.new
66
+ @processor = nil
69
67
  @subscribers = nil
70
68
 
71
69
  def self.call_subscribers(log)
@@ -74,8 +72,8 @@ module SemanticLogger
74
72
  @subscribers.each do |subscriber|
75
73
  begin
76
74
  subscriber.call(log)
77
- rescue Exception => exc
78
- self.class.processor.logger.error('Exception calling :on_log subscriber', exc)
75
+ rescue Exception => e
76
+ processor.logger.error("Exception calling :on_log subscriber", e)
79
77
  end
80
78
  end
81
79
  end
@@ -1,7 +1,7 @@
1
1
  begin
2
- require 'newrelic_rpm'
2
+ require "newrelic_rpm"
3
3
  rescue LoadError
4
- raise 'Gem newrelic_rpm is required for logging to New Relic. Please add the gem "newrelic_rpm" to your Gemfile.'
4
+ raise LoadError, 'Gem newrelic_rpm is required for logging to New Relic. Please add the gem "newrelic_rpm" to your Gemfile.'
5
5
  end
6
6
 
7
7
  # Send Metrics to NewRelic
@@ -37,7 +37,7 @@ module SemanticLogger
37
37
  # regular expression. All other messages will be ignored.
38
38
  # Proc: Only include log messages where the supplied Proc returns true
39
39
  # The Proc must return true or false.
40
- def initialize(prefix: 'Custom', **args, &block)
40
+ def initialize(prefix: "Custom", **args, &block)
41
41
  @prefix = prefix
42
42
  super(**args, &block)
43
43
  end
@@ -10,7 +10,7 @@ module SemanticLogger
10
10
  class Signalfx < SemanticLogger::Appender::Http
11
11
  attr_reader :full_url
12
12
 
13
- END_POINT = 'v2/datapoint'.freeze
13
+ END_POINT = "v2/datapoint".freeze
14
14
 
15
15
  # Create SignalFx metrics appender.
16
16
  #
@@ -75,7 +75,7 @@ module SemanticLogger
75
75
  # end
76
76
  def initialize(token:,
77
77
  dimensions: nil,
78
- url: 'https://ingest.signalfx.com',
78
+ url: "https://ingest.signalfx.com",
79
79
  formatter: nil,
80
80
  **args,
81
81
  &block)
@@ -84,7 +84,7 @@ module SemanticLogger
84
84
 
85
85
  super(url: url, formatter: formatter, **args, &block)
86
86
 
87
- @header['X-SF-TOKEN'] = token
87
+ @header["X-SF-TOKEN"] = token
88
88
  @full_url = "#{url}/#{END_POINT}"
89
89
  end
90
90
 
@@ -1,8 +1,8 @@
1
- require 'uri'
1
+ require "uri"
2
2
  begin
3
- require 'statsd-ruby'
3
+ require "statsd-ruby"
4
4
  rescue LoadError
5
- raise 'Gem statsd-ruby is required for logging metrics. Please add the gem "statsd-ruby" to your Gemfile.'
5
+ raise LoadError, 'Gem statsd-ruby is required for logging metrics. Please add the gem "statsd-ruby" to your Gemfile.'
6
6
  end
7
7
 
8
8
  module SemanticLogger
@@ -26,17 +26,17 @@ module SemanticLogger
26
26
  # metric: :statsd,
27
27
  # url: 'localhost:8125'
28
28
  # )
29
- def initialize(url: 'udp://localhost:8125')
29
+ def initialize(url: "udp://localhost:8125")
30
30
  @url = url
31
31
  end
32
32
 
33
33
  def reopen
34
34
  uri = URI.parse(@url)
35
- raise('Statsd only supports udp. Example: "udp://localhost:8125"') if uri.scheme != 'udp'
35
+ raise('Statsd only supports udp. Example: "udp://localhost:8125"') if uri.scheme != "udp"
36
36
 
37
37
  @statsd = ::Statsd.new(uri.host, uri.port)
38
- path = uri.path.chomp('/')
39
- @statsd.namespace = path.sub('/', '') if path != ''
38
+ path = uri.path.chomp("/")
39
+ @statsd.namespace = path.sub("/", "") if path != ""
40
40
  end
41
41
 
42
42
  def log(log)
@@ -13,11 +13,12 @@ module SemanticLogger
13
13
  # For example when an appender is not working etc..
14
14
  # By default logs to STDERR
15
15
  def self.logger
16
- @logger ||= begin
17
- l = SemanticLogger::Appender::File.new(io: STDERR, level: :warn)
18
- l.name = name
19
- l
20
- end
16
+ @logger ||=
17
+ begin
18
+ l = SemanticLogger::Appender::File.new(io: STDERR, level: :warn)
19
+ l.name = name
20
+ l
21
+ end
21
22
  end
22
23
 
23
24
  attr_reader :appenders
@@ -30,6 +31,7 @@ module SemanticLogger
30
31
  # Start the appender thread
31
32
  def start
32
33
  return false if active?
34
+
33
35
  thread
34
36
  true
35
37
  end
@@ -23,7 +23,7 @@ module SemanticLogger
23
23
  class Minitest < ::Minitest::AbstractReporter
24
24
  include SemanticLogger::Loggable
25
25
 
26
- logger.name = 'Minitest'
26
+ logger.name = "Minitest"
27
27
 
28
28
  attr_accessor :io
29
29
 
@@ -33,11 +33,11 @@ module SemanticLogger
33
33
 
34
34
  def after_test(test)
35
35
  if test.error?
36
- logger.benchmark_error("FAIL #{test.class_name} #{test.name}", duration: test.time * 1_000, metric: 'minitest/fail')
36
+ logger.benchmark_error("FAIL #{test.class_name} #{test.name}", duration: test.time * 1_000, metric: "minitest/fail")
37
37
  elsif test.skipped?
38
- logger.benchmark_warn("SKIP #{test.class_name} #{test.name}", duration: test.time * 1_000, metric: 'minitest/skip')
38
+ logger.benchmark_warn("SKIP #{test.class_name} #{test.name}", duration: test.time * 1_000, metric: "minitest/skip")
39
39
  else
40
- logger.benchmark_info("PASS #{test.class_name} #{test.name}", duration: test.time * 1_000, metric: 'minitest/pass')
40
+ logger.benchmark_info("PASS #{test.class_name} #{test.name}", duration: test.time * 1_000, metric: "minitest/pass")
41
41
  end
42
42
  end
43
43
  end
@@ -1,5 +1,5 @@
1
- require 'concurrent'
2
- require 'socket'
1
+ require "concurrent"
2
+ require "socket"
3
3
 
4
4
  module SemanticLogger
5
5
  # Logging levels in order of most detailed to most severe
@@ -52,7 +52,7 @@ module SemanticLogger
52
52
  # Returns [String] name of this host for logging purposes
53
53
  # Note: Not all appenders use `host`
54
54
  def self.host
55
- @host ||= Socket.gethostname.force_encoding('UTF-8')
55
+ @host ||= Socket.gethostname.force_encoding("UTF-8")
56
56
  end
57
57
 
58
58
  # Override the default host name
@@ -71,7 +71,19 @@ module SemanticLogger
71
71
  @application = application
72
72
  end
73
73
 
74
- @application = 'Semantic Logger'
74
+ # Returns [String] name of this environment for logging purposes
75
+ # Note: Not all appenders use `environment`
76
+ def self.environment
77
+ @environment
78
+ end
79
+
80
+ # Override the default environment
81
+ def self.environment=(environment)
82
+ @environment = environment
83
+ end
84
+
85
+ @application = ENV["SEMANTIC_LOGGER_APP"] || "Semantic Logger"
86
+ @environment = ENV["SEMANTIC_LOGGER_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"]
75
87
 
76
88
  # Add a new logging appender as a new destination for all log messages
77
89
  # emitted from Semantic Logger
@@ -151,8 +163,8 @@ module SemanticLogger
151
163
  # logger = SemanticLogger['Example']
152
164
  # logger.info "Hello World"
153
165
  # logger.debug("Login time", user: 'Joe', duration: 100, ip_address: '127.0.0.1')
154
- def self.add_appender(options, deprecated_level = nil, &block)
155
- appender = Logger.processor.appenders.add(options, deprecated_level, &block)
166
+ def self.add_appender(**args, &block)
167
+ appender = Logger.processor.appenders.add(**args, &block)
156
168
  # Start appender thread if it is not already running
157
169
  Logger.processor.start
158
170
  appender
@@ -256,22 +268,23 @@ module SemanticLogger
256
268
  # Note:
257
269
  # To only register one of the signal handlers, set the other to nil
258
270
  # Set gc_log_microseconds to nil to not enable JRuby Garbage collections
259
- def self.add_signal_handler(log_level_signal = 'USR2', thread_dump_signal = 'TTIN', gc_log_microseconds = 100_000)
271
+ def self.add_signal_handler(log_level_signal = "USR2", thread_dump_signal = "TTIN", gc_log_microseconds = 100_000)
260
272
  if log_level_signal
261
273
  Signal.trap(log_level_signal) do
262
274
  index = default_level == :trace ? LEVELS.find_index(:error) : LEVELS.find_index(default_level)
263
275
  new_level = LEVELS[index - 1]
264
- self['SemanticLogger'].warn "Changed global default log level to #{new_level.inspect}"
276
+ self["SemanticLogger"].warn "Changed global default log level to #{new_level.inspect}"
265
277
  self.default_level = new_level
266
278
  end
267
279
  end
268
280
 
269
281
  if thread_dump_signal
270
282
  Signal.trap(thread_dump_signal) do
271
- logger = SemanticLogger['Thread Dump']
283
+ logger = SemanticLogger["Thread Dump"]
272
284
  Thread.list.each do |thread|
273
285
  # MRI re-uses the main thread for signals, JRuby uses `SIGTTIN handler` thread.
274
286
  next if defined?(JRuby) && (thread == Thread.current)
287
+
275
288
  logger.backtrace(thread: thread)
276
289
  end
277
290
  end
@@ -290,7 +303,7 @@ module SemanticLogger
290
303
  # If the tag being supplied is definitely a string then this fast
291
304
  # tag api can be used for short lived tags
292
305
  def self.fast_tag(tag)
293
- return yield if tag.nil? || tag == ''
306
+ return yield if tag.nil? || tag == ""
294
307
 
295
308
  t = Thread.current[:semantic_logger_tags] ||= []
296
309
  begin
@@ -367,7 +380,7 @@ module SemanticLogger
367
380
  # :nodoc
368
381
  def self.named_tagged(hash)
369
382
  return yield if hash.nil? || hash.empty?
370
- raise(ArgumentError, '#named_tagged only accepts named parameters (Hash)') unless hash.is_a?(Hash)
383
+ raise(ArgumentError, "#named_tagged only accepts named parameters (Hash)") unless hash.is_a?(Hash)
371
384
 
372
385
  begin
373
386
  push_named_tags(hash)
@@ -476,11 +489,23 @@ module SemanticLogger
476
489
  Thread.current[:semantic_logger_silence] || @default_level_index
477
490
  end
478
491
 
479
- private
492
+ # Run Semantic Logger in Synchronous mode.
493
+ #
494
+ # I.e. Instead of logging messages in a separate thread for better performance,
495
+ # log them using the current thread.
496
+ def self.sync!
497
+ @sync = true
498
+ end
499
+
500
+ # Running in synchronous mode?
501
+ def self.sync?
502
+ @sync
503
+ end
480
504
 
481
505
  # Initial default Level for all new instances of SemanticLogger::Logger
482
506
  @default_level = :info
483
507
  @default_level_index = Levels.index(@default_level)
484
508
  @backtrace_level = :error
485
509
  @backtrace_level_index = Levels.index(@backtrace_level)
510
+ @sync = false
486
511
  end
@@ -5,7 +5,7 @@ module SemanticLogger
5
5
  class Subscriber < SemanticLogger::Base
6
6
  # Every appender has its own formatter
7
7
  attr_reader :formatter
8
- attr_writer :application, :host, :logger, :metrics
8
+ attr_writer :application, :environment, :host, :logger, :metrics
9
9
 
10
10
  # Returns the current log level if set, otherwise it logs everything it receives.
11
11
  def level
@@ -32,6 +32,11 @@ module SemanticLogger
32
32
  @application || SemanticLogger.application
33
33
  end
34
34
 
35
+ # Allow environment name to be set globally or on a per subscriber basis.
36
+ def environment
37
+ @environment || SemanticLogger.environment
38
+ end
39
+
35
40
  # Allow host name to be set globally or on a per subscriber basis.
36
41
  def host
37
42
  @host || SemanticLogger.host
@@ -40,11 +45,12 @@ module SemanticLogger
40
45
  # Give each appender its own logger for logging.
41
46
  # For example trace messages sent to services or errors when something fails.
42
47
  def logger
43
- @logger ||= begin
44
- logger = SemanticLogger::Processor.logger.clone
45
- logger.name = self.class.name
46
- logger
47
- end
48
+ @logger ||=
49
+ begin
50
+ logger = SemanticLogger::Processor.logger.clone
51
+ logger.name = self.class.name
52
+ logger
53
+ end
48
54
  end
49
55
 
50
56
  # Set the formatter from Symbol|Hash|Block
@@ -92,9 +98,10 @@ module SemanticLogger
92
98
  # metrics: [Boolean]
93
99
  # Whether to log metric only entries with this subscriber.
94
100
  # Default: false
95
- def initialize(level: nil, formatter: nil, filter: nil, application: nil, host: nil, metrics: false, &block)
101
+ def initialize(level: nil, formatter: nil, filter: nil, application: nil, environment: nil, host: nil, metrics: false, &block)
96
102
  self.formatter = block || formatter
97
103
  @application = application
104
+ @environment = environment
98
105
  @host = host
99
106
  @metrics = metrics
100
107
 
@@ -0,0 +1,12 @@
1
+ # Run Semantic Logger in Synchronous mode.
2
+ #
3
+ # I.e. Instead of logging messages in a separate thread for better performance,
4
+ # log them using the current thread.
5
+ #
6
+ # Usage:
7
+ # require "semantic_logger/sync"
8
+ #
9
+ # Or, when using a Gemfile:
10
+ # gem "semantic_logger", require: "semantic_logger/sync"
11
+ require "semantic_logger"
12
+ SemanticLogger.sync!
@@ -0,0 +1,43 @@
1
+ module SemanticLogger
2
+ # Thread that submits and processes log requests
3
+ class SyncProcessor
4
+ extend Forwardable
5
+
6
+ # Forward methods that can be called directly
7
+ def_delegator :@appenders, :add
8
+ def_delegator :@appenders, :log
9
+ def_delegator :@appenders, :flush
10
+ def_delegator :@appenders, :close
11
+ def_delegator :@appenders, :reopen
12
+
13
+ # Allow the internal logger to be overridden from its default of STDERR
14
+ # Can be replaced with another Ruby logger or Rails logger, but never to
15
+ # SemanticLogger::Logger itself since it is for reporting problems
16
+ # while trying to log to the various appenders
17
+ class << self
18
+ attr_writer :logger
19
+ end
20
+
21
+ # Internal logger for SemanticLogger
22
+ # For example when an appender is not working etc..
23
+ # By default logs to STDERR
24
+ def self.logger
25
+ @logger ||=
26
+ begin
27
+ l = SemanticLogger::Appender::File.new(io: STDERR, level: :warn)
28
+ l.name = name
29
+ l
30
+ end
31
+ end
32
+
33
+ attr_reader :appenders
34
+
35
+ def initialize
36
+ @appenders = Appenders.new(self.class.logger.dup)
37
+ end
38
+
39
+ def start
40
+ # NOP
41
+ end
42
+ end
43
+ end
@@ -2,7 +2,7 @@ module SemanticLogger
2
2
  # Internal-use only utility functions for Semantic Logger.
3
3
  # Not intended for public use.
4
4
  module Utils
5
- def self.constantize_symbol(symbol, namespace = 'SemanticLogger::Appender')
5
+ def self.constantize_symbol(symbol, namespace = "SemanticLogger::Appender")
6
6
  klass = "#{namespace}::#{camelize(symbol.to_s)}"
7
7
  begin
8
8
  Object.const_get(klass)
@@ -15,8 +15,8 @@ module SemanticLogger
15
15
  def self.camelize(term)
16
16
  string = term.to_s
17
17
  string = string.sub(/^[a-z\d]*/, &:capitalize)
18
- string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }
19
- string.gsub!('/'.freeze, '::'.freeze)
18
+ string.gsub!(%r{(?:_|(/))([a-z\d]*)}i) { "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}" }
19
+ string.gsub!("/".freeze, "::".freeze)
20
20
  string
21
21
  end
22
22
 
@@ -32,7 +32,7 @@ module SemanticLogger
32
32
  end
33
33
  end
34
34
 
35
- SELF_PATTERN = File.join('lib', 'semantic_logger')
35
+ SELF_PATTERN = File.join("lib", "semantic_logger")
36
36
 
37
37
  # Extract the backtrace leaving out the last few Semantic Logger lines.
38
38
  def self.extract_backtrace(stack = caller)
@@ -50,11 +50,11 @@ module SemanticLogger
50
50
  stack
51
51
  end
52
52
 
53
- GEM_ROOT = File.expand_path('../../..', __dir__) + '/'
53
+ GEM_ROOT = File.expand_path("../../..", __dir__) + "/"
54
54
 
55
55
  def self.system_path?(path)
56
56
  path.start_with?(GEM_ROOT) ||
57
- path.start_with?(RbConfig::CONFIG['rubylibdir'])
57
+ path.start_with?(RbConfig::CONFIG["rubylibdir"])
58
58
  end
59
59
  end
60
60
  end
@@ -1,3 +1,3 @@
1
1
  module SemanticLogger
2
- VERSION = '4.5.0'.freeze
2
+ VERSION = "4.7.1".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.5.0
4
+ version: 4.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-21 00:00:00.000000000 Z
11
+ date: 2020-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -85,6 +85,8 @@ files:
85
85
  - lib/semantic_logger/reporters/minitest.rb
86
86
  - lib/semantic_logger/semantic_logger.rb
87
87
  - lib/semantic_logger/subscriber.rb
88
+ - lib/semantic_logger/sync.rb
89
+ - lib/semantic_logger/sync_processor.rb
88
90
  - lib/semantic_logger/utils.rb
89
91
  - lib/semantic_logger/version.rb
90
92
  homepage: https://github.com/rocketjob/semantic_logger
@@ -106,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
108
  - !ruby/object:Gem::Version
107
109
  version: '0'
108
110
  requirements: []
109
- rubygems_version: 3.0.2
111
+ rubygems_version: 3.1.2
110
112
  signing_key:
111
113
  specification_version: 4
112
114
  summary: Feature rich logging framework, and replacement for existing Ruby & Rails